btrfs_show_devname don't traverse into the seed fsid
diff mbox series

Message ID 20200710063738.28368-1-anand.jain@oracle.com
State New
Headers show
Series
  • btrfs_show_devname don't traverse into the seed fsid
Related show

Commit Message

Anand Jain July 10, 2020, 6:37 a.m. UTC
->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@oracle.com>
---
This has passed the xfstests/btrfs sucessfully with no new
regressions. Thanks.

 fs/btrfs/super.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

Comments

Josef Bacik July 10, 2020, 2:32 p.m. UTC | #1
On 7/10/20 2:37 AM, 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@oracle.com>

This needs to come with an xfstest so we do not regress this in the future.  Thanks,

Josef
Anand Jain July 10, 2020, 3:16 p.m. UTC | #2
> 
> This needs to come with an xfstest so we do not regress this in the 
> future.  Thanks,

  Oh yes. Makes sense. An xfstests test case is on its way.

Thanks, Anand

> 
> Josef
Martin K. Petersen July 10, 2020, 3:54 p.m. UTC | #3
Anand,

> So instead, do not traverse through the seed devices, just show the
> lowest devid in the sprouted fsid.

Reported-by: Martin K. Petersen <martin.petersen@oracle.com>
Tested-by: Martin K. Petersen <martin.petersen@oracle.com>
Nikolay Borisov July 13, 2020, 2:04 p.m. UTC | #4
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@oracle.com>

Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Tested-by: Nikolay Borisov <nborisov@suse.com>

> ---
> 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)
>
David Sterba July 15, 2020, 10:21 a.m. UTC | #5
On Fri, Jul 10, 2020 at 02:37:38PM +0800, 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@oracle.com>

Added to misc-next, thanks.

Patch
diff mbox series

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)