Every time btrfs mounts a image that it's already mounted (cloned images), it will assign a new random UUID to it to avoid conflicts. However, for some internal kernel usage, it's important to access the original UUID of a given image. For instance, overlayfs' "index" feature keeps track of the UUID of the mounted filesystem on it's upper layer, to avoid being remounted with a different filesystem. However, overlayfs uses the same random UUID exposed to userspace, so the "index" check will fail when trying to remount the very same filesystem. Implement export operation get_disk_uuid() to export the real image UUID. Signed-off-by: André Almeida --- fs/btrfs/export.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 230d9326b685..09f9ef8c1b1e 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c @@ -8,6 +8,7 @@ #include "export.h" #include "accessors.h" #include "super.h" +#include "volumes.h" #define BTRFS_FID_SIZE_NON_CONNECTABLE (offsetof(struct btrfs_fid, \ parent_objectid) / 4) @@ -298,10 +299,29 @@ static int btrfs_get_name(struct dentry *parent, char *name, return 0; } +static int btrfs_get_disk_uuid(struct super_block *sb, u8 *buf, u32 *len, + u64 *offset) +{ + struct btrfs_fs_devices *fs_dev = btrfs_sb(sb)->fs_devices; + + if (fs_dev->temp_fsid) + return -ENODATA; + + if (*len < sizeof(uuid_t)) + return -EINVAL; + + memcpy(buf, &fs_dev->metadata_uuid, sizeof(uuid_t)); + *offset = offsetof(struct btrfs_fs_devices, metadata_uuid); + *len = sizeof(uuid_t); + + return 0; +} + const struct export_operations btrfs_export_ops = { .encode_fh = btrfs_encode_fh, .fh_to_dentry = btrfs_fh_to_dentry, .fh_to_parent = btrfs_fh_to_parent, .get_parent = btrfs_get_parent, .get_name = btrfs_get_name, + .get_disk_uuid = btrfs_get_disk_uuid, }; -- 2.52.0