| From 4faf55b03823e96c44dc4e364520000ed3b12fdb Mon Sep 17 00:00:00 2001 |
| From: Anand Jain <anand.jain@oracle.com> |
| Date: Fri, 10 Jul 2020 14:37:38 +0800 |
| Subject: [PATCH] btrfs: don't traverse into the seed devices in show_devname |
| |
| commit 4faf55b03823e96c44dc4e364520000ed3b12fdb upstream. |
| |
| ->show_devname currently shows the lowest devid in the list. As the seed |
| devices have the lowest devid in the sprouted filesystem, the userland |
| tool such as findmnt end up seeing seed device instead of the device from |
| the read-writable sprouted filesystem. As shown below. |
| |
| mount /dev/sda /btrfs |
| mount: /btrfs: WARNING: device write-protected, mounted read-only. |
| |
| findmnt --output SOURCE,TARGET,UUID /btrfs |
| SOURCE TARGET UUID |
| /dev/sda /btrfs 899f7027-3e46-4626-93e7-7d4c9ad19111 |
| |
| btrfs dev add -f /dev/sdb /btrfs |
| |
| umount /btrfs |
| mount /dev/sdb /btrfs |
| |
| findmnt --output SOURCE,TARGET,UUID /btrfs |
| SOURCE TARGET UUID |
| /dev/sda /btrfs 899f7027-3e46-4626-93e7-7d4c9ad19111 |
| |
| All sprouts from a single seed will show the same seed device and the |
| same fsid. That's confusing. |
| This is causing problems in our prototype as there isn't any reference |
| to the sprout file-system(s) which is being used for actual read and |
| write. |
| |
| This was added in the patch which implemented the show_devname in btrfs |
| commit 9c5085c14798 ("Btrfs: implement ->show_devname"). |
| I tried to look for any particular reason that we need to show the seed |
| device, there isn't any. |
| |
| So instead, do not traverse through the seed devices, just show the |
| lowest devid in the sprouted fsid. |
| |
| After the patch: |
| |
| mount /dev/sda /btrfs |
| mount: /btrfs: WARNING: device write-protected, mounted read-only. |
| |
| findmnt --output SOURCE,TARGET,UUID /btrfs |
| SOURCE TARGET UUID |
| /dev/sda /btrfs 899f7027-3e46-4626-93e7-7d4c9ad19111 |
| |
| btrfs dev add -f /dev/sdb /btrfs |
| mount -o rw,remount /dev/sdb /btrfs |
| |
| findmnt --output SOURCE,TARGET,UUID /btrfs |
| SOURCE TARGET UUID |
| /dev/sdb /btrfs 595ca0e6-b82e-46b5-b9e2-c72a6928be48 |
| |
| mount /dev/sda /btrfs1 |
| mount: /btrfs1: WARNING: device write-protected, mounted read-only. |
| |
| btrfs dev add -f /dev/sdc /btrfs1 |
| |
| findmnt --output SOURCE,TARGET,UUID /btrfs1 |
| SOURCE TARGET UUID |
| /dev/sdc /btrfs1 ca1dbb7a-8446-4f95-853c-a20f3f82bdbb |
| |
| cat /proc/self/mounts | grep btrfs |
| /dev/sdb /btrfs btrfs rw,relatime,noacl,space_cache,subvolid=5,subvol=/ 0 0 |
| /dev/sdc /btrfs1 btrfs ro,relatime,noacl,space_cache,subvolid=5,subvol=/ 0 0 |
| |
| Reported-by: Martin K. Petersen <martin.petersen@oracle.com> |
| CC: stable@vger.kernel.org # 4.19+ |
| Tested-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Anand Jain <anand.jain@oracle.com> |
| Reviewed-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| |
| diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c |
| index 7c052a542412..58f890f73650 100644 |
| --- a/fs/btrfs/super.c |
| +++ b/fs/btrfs/super.c |
| @@ -2351,9 +2351,7 @@ static int btrfs_unfreeze(struct super_block *sb) |
| static int btrfs_show_devname(struct seq_file *m, struct dentry *root) |
| { |
| struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); |
| - struct btrfs_fs_devices *cur_devices; |
| struct btrfs_device *dev, *first_dev = NULL; |
| - struct list_head *head; |
| |
| /* |
| * Lightweight locking of the devices. We should not need |
| @@ -2363,18 +2361,13 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root) |
| * least until the rcu_read_unlock. |
| */ |
| rcu_read_lock(); |
| - cur_devices = fs_info->fs_devices; |
| - while (cur_devices) { |
| - head = &cur_devices->devices; |
| - list_for_each_entry_rcu(dev, head, dev_list) { |
| - if (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state)) |
| - continue; |
| - if (!dev->name) |
| - continue; |
| - if (!first_dev || dev->devid < first_dev->devid) |
| - first_dev = dev; |
| - } |
| - cur_devices = cur_devices->seed; |
| + list_for_each_entry_rcu(dev, &fs_info->fs_devices->devices, dev_list) { |
| + if (test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state)) |
| + continue; |
| + if (!dev->name) |
| + continue; |
| + if (!first_dev || dev->devid < first_dev->devid) |
| + first_dev = dev; |
| } |
| |
| if (first_dev) |
| -- |
| 2.27.0 |
| |