From: Anand Jain <anand.jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Cc: Anand Jain <anand.jain@oracle.com>,
"Guilherme G . Piccoli" <gpiccoli@igalia.com>
Subject: [PATCH 2/2] btrfs: support cloned-device mount capability
Date: Thu, 28 Sep 2023 09:09:47 +0800 [thread overview]
Message-ID: <e85f357bfbcef98bba37e2f39e884a371fc25b56.1695826320.git.anand.jain@oracle.com> (raw)
In-Reply-To: <cover.1695826320.git.anand.jain@oracle.com>
Guilherme's previous work [1] aimed at the mounting of cloned devices
using a superblock flag SINGLE_DEV during mkfs.
[1] https://lore.kernel.org/linux-btrfs/20230831001544.3379273-1-gpiccoli@igalia.com/
Building upon this work, here is in memory only approach. As it mounts
we determine if the same fsid is already mounted if then we generate a
random temp fsid which shall be used the mount, in memory only not
written to the disk. We distinguish devices by devt.
Example:
$ fallocate -l 300m ./disk1.img :0
$ mkfs.btrfs -f ./disk1.img :0
$ cp ./disk1.img ./disk2.img :0
$ cp ./disk1.img ./disk3.img :0
$ mount -o loop ./disk1.img /btrfs :0
$ mount -o ./disk2.img /btrfs1 :0
$ mount -o ./disk3.img /btrfs2 :0
$ btrfs fi show -m :0
Label: none uuid: 4a212b48-1bec-46a5-938a-783c8c1f0b02
Total devices 1 FS bytes used 144.00KiB
devid 1 size 300.00MiB used 88.00MiB path /dev/loop0
Label: none uuid: adabf2fe-5515-4ad0-95b4-7b1609218c16
Total devices 1 FS bytes used 144.00KiB
devid 1 size 300.00MiB used 88.00MiB path /dev/loop1
Label: none uuid: 1d77d0df-7d92-439e-adbd-20b9b86fdedb
Total devices 1 FS bytes used 144.00KiB
devid 1 size 300.00MiB used 88.00MiB path /dev/loop2
Co-developed-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
fs/btrfs/disk-io.c | 3 ++-
fs/btrfs/volumes.c | 62 +++++++++++++++++++++++++++++++++++++++++++---
fs/btrfs/volumes.h | 2 ++
3 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a970da7263b3..04f57d8368c8 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2399,7 +2399,8 @@ int btrfs_validate_super(struct btrfs_fs_info *fs_info,
ret = -EINVAL;
}
- if (memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0) {
+ if (!fs_info->fs_devices->temp_fsid &&
+ memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0) {
btrfs_err(fs_info,
"superblock fsid doesn't match fsid of fs_devices: %pU != %pU",
sb->fsid, fs_info->fs_devices->fsid);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 39b5bc2521fb..ea4a110d7753 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -554,17 +554,64 @@ static int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device
}
static struct btrfs_fs_devices *find_fsid_by_disk(
- struct btrfs_super_block *disk_super)
+ struct btrfs_super_block *disk_super,
+ dev_t devt, bool *same_fsid_diff_dev)
{
struct btrfs_fs_devices *fsid_fs_devices;
+ struct btrfs_fs_devices *devt_fs_devices;
bool has_metadata_uuid = (btrfs_super_incompat_flags(disk_super) &
BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
+ bool found_by_devt = false;
/* Find the fs_device by the usual method if found use it */
fsid_fs_devices = find_fsid(disk_super->fsid, has_metadata_uuid ?
disk_super->metadata_uuid : NULL);
- return fsid_fs_devices;
+ /* The temp_fsid feature is supported only with single device btrfs */
+ if (btrfs_super_num_devices(disk_super) != 1)
+ return fsid_fs_devices;
+
+ /* Try to find a fs_devices by matching devt */
+ list_for_each_entry(devt_fs_devices, &fs_uuids, fs_list) {
+ struct btrfs_device *device;
+
+ list_for_each_entry(device, &devt_fs_devices->devices,
+ dev_list) {
+ if (device->devt == devt) {
+ found_by_devt = true;
+ break;
+ }
+ }
+ if (found_by_devt)
+ break;
+ }
+
+ if (found_by_devt) {
+ /* existing device */
+ if (fsid_fs_devices == NULL) {
+ if (devt_fs_devices->opened == 0) {
+ /* stale device */
+ return NULL;
+ } else {
+ /* temp_fsid is mounting a subvol */
+ return devt_fs_devices;
+ }
+ } else {
+ /* regular or temp_fsid device mounting a subvol */
+ return devt_fs_devices;
+ }
+ } else {
+ /* new device */
+ if (fsid_fs_devices == NULL) {
+ return NULL;
+ } else {
+ /* sb::fsid is already used create a new temp_fsid */
+ *same_fsid_diff_dev = true;
+ return NULL;
+ }
+ }
+
+ /* Not reached */
}
/*
@@ -670,6 +717,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
u64 devid = btrfs_stack_device_id(&disk_super->dev_item);
dev_t path_devt;
int error;
+ bool same_fsid_diff_dev = false;
bool has_metadata_uuid = (btrfs_super_incompat_flags(disk_super) &
BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
@@ -687,7 +735,8 @@ static noinline struct btrfs_device *device_list_add(const char *path,
return ERR_PTR(error);
}
- fs_devices = find_fsid_by_disk(disk_super);
+ fs_devices = find_fsid_by_disk(disk_super, path_devt,
+ &same_fsid_diff_dev);
if (!fs_devices) {
fs_devices = alloc_fs_devices(disk_super->fsid);
@@ -698,6 +747,13 @@ static noinline struct btrfs_device *device_list_add(const char *path,
if (IS_ERR(fs_devices))
return ERR_CAST(fs_devices);
+ if (same_fsid_diff_dev) {
+ generate_random_uuid(fs_devices->fsid);
+ fs_devices->temp_fsid = true;
+ pr_info("BTRFS: device %s using temp fsid %pU\n",
+ path, fs_devices->fsid);
+ }
+
mutex_lock(&fs_devices->device_list_mutex);
list_add(&fs_devices->fs_list, &fs_uuids);
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index e485e6a3e52c..5921fdd3dd90 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -364,6 +364,8 @@ struct btrfs_fs_devices {
bool discardable;
/* The filesystem is a seed filesystem. */
bool seeding;
+ /* The mount need to use a randomly generated fsid. */
+ bool temp_fsid;
struct btrfs_fs_info *fs_info;
/* sysfs kobjects */
--
2.38.1
next prev parent reply other threads:[~2023-09-28 1:10 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-28 1:09 [PATCH 0/2] btrfs: support cloned-device mount capability Anand Jain
2023-09-28 1:09 ` [PATCH 1/2] btrfs: add helper function find_fsid_by_disk Anand Jain
2023-10-02 11:45 ` David Sterba
2023-10-03 0:57 ` Anand Jain
2023-09-28 1:09 ` Anand Jain [this message]
2023-10-02 12:57 ` [PATCH 2/2] btrfs: support cloned-device mount capability David Sterba
2023-10-02 22:41 ` Anand Jain
2023-10-02 12:52 ` [PATCH 0/2] " Anand Jain
2023-10-02 13:00 ` David Sterba
2023-10-03 1:13 ` Anand Jain
2023-10-06 7:42 ` Guilherme G. Piccoli
2023-10-07 8:01 ` Anand Jain
2023-10-18 14:15 ` Guilherme G. Piccoli
2023-10-19 2:13 ` Anand Jain
2023-10-19 8:15 ` Guilherme G. Piccoli
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e85f357bfbcef98bba37e2f39e884a371fc25b56.1695826320.git.anand.jain@oracle.com \
--to=anand.jain@oracle.com \
--cc=gpiccoli@igalia.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).