Let's explicitly let btrfs know when we're done using a loop device.
Otherwise, btrfs will keep the device UUID cached which will result
in mount() failures if we ever generate a device or filesystem with
the same UUID again.
if (r < 0)
return r;
+ r = btrfs_forget_device(devname);
+ if (r < 0 && r != -ENOENT)
+ log_debug_errno(r, "Failed to forget btrfs device %s, ignoring: %m", devname);
+
r = block_device_remove_partition(fd, devname, nr);
if (r == -ENODEV) {
log_debug("Kernel removed partition %s before us, ignoring", devname);
return -ENXIO;
}
+
+int btrfs_forget_device(const char *path) {
+ _cleanup_close_ int control_fd = -EBADF;
+ struct btrfs_ioctl_vol_args args = {};
+
+ assert(path);
+
+ if (strlen(path) > BTRFS_PATH_NAME_MAX)
+ return -E2BIG;
+
+ strcpy(args.name, path);
+
+ control_fd = open("/dev/btrfs-control", O_RDWR|O_CLOEXEC);
+ if (control_fd < 0)
+ return -errno;
+
+ return RET_NERRNO(ioctl(control_fd, BTRFS_IOC_FORGET_DEV, &args));
+}
return S_ISDIR(st->st_mode) && st->st_ino == 256;
}
+
+int btrfs_forget_device(const char *path);
#include "ask-password-api.h"
#include "blkid-util.h"
#include "blockdev-util.h"
+#include "btrfs-util.h"
#include "chase-symlinks.h"
#include "conf-files.h"
#include "constants.h"
DecryptedPartition *p = d->decrypted + i;
if (p->device && p->name && !p->relinquished) {
+ _cleanup_free_ char *node = NULL;
+
+ node = path_join("/dev/mapper", p->name);
+ if (node) {
+ r = btrfs_forget_device(node);
+ if (r < 0 && r != -ENOENT)
+ log_debug_errno(r, "Failed to forget btrfs device %s, ignoring: %m", node);
+ } else
+ log_oom_debug();
+
/* Let's deactivate lazily, as the dm volume may be already/still used by other processes. */
r = sym_crypt_deactivate_by_name(p->device, p->name, CRYPT_DEACTIVATE_DEFERRED);
if (r < 0)