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:
Daan De Meyer
2023-01-12 16:36:09 +01:00
parent da2a4f6a2e
commit 5228c58ebe
4 changed files with 35 additions and 0 deletions
+4
View File
@@ -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);
+18
View File
@@ -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));
}
+2
View File
@@ -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);
+11
View File
@@ -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)