On 10.07.20 г. 9:37 ч., Anand Jain wrote:
> ->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 messy.
> 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
>
> Signed-off-by: Anand Jain <anand.jain@xxxxxxxxxx>
Reviewed-by: Nikolay Borisov <nborisov@xxxxxxxx>
Tested-by: Nikolay Borisov <nborisov@xxxxxxxx>
> ---
> This has passed the xfstests/btrfs sucessfully with no new
> regressions. Thanks.
>
> fs/btrfs/super.c | 21 +++++++--------------
> 1 file changed, 7 insertions(+), 14 deletions(-)
>
> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
> index c7ee119cffa1..1e2a36f5c792 100644
> --- a/fs/btrfs/super.c
> +++ b/fs/btrfs/super.c
> @@ -2377,9 +2377,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
> @@ -2389,18 +2387,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)
>