dissect-image: Notify btrfs when we're done using a loop device
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.
This commit is contained in:
@@ -707,6 +707,10 @@ int block_device_remove_all_partitions(sd_device *dev, int fd) {
|
||||
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);
|
||||
|
||||
@@ -1986,3 +1986,21 @@ int btrfs_subvol_get_parent(int fd, uint64_t subvol_id, uint64_t *ret) {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -136,3 +136,5 @@ static inline bool btrfs_might_be_subvol(const struct stat *st) {
|
||||
|
||||
return S_ISDIR(st->st_mode) && st->st_ino == 256;
|
||||
}
|
||||
|
||||
int btrfs_forget_device(const char *path);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#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"
|
||||
@@ -1739,6 +1740,16 @@ static DecryptedImage* decrypted_image_free(DecryptedImage *d) {
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user