All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC] btrfs: pick device with lowest devt for show_devname
@ 2023-11-02 11:10 Anand Jain
  2023-11-02 20:26 ` David Sterba
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Anand Jain @ 2023-11-02 11:10 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Anand Jain

In a non-single-device Btrfs filesystem, if Btrfs is already mounted and
if you run the command 'mount -a,' it will fail and the command
'umount <device>' also fails. As below:

----------------
$ cat /etc/fstab | grep btrfs
UUID=12345678-1234-1234-1234-123456789abc /btrfs btrfs defaults,nofail 0 0

$ mkfs.btrfs -qf --uuid 12345678-1234-1234-1234-123456789abc /dev/sda2 /dev/sda1
$ mount --verbose -a
/                        : ignored
/btrfs                   : successfully mounted

$ ls -l /dev/disk/by-uuid | grep 12345678-1234-1234-1234-123456789abc
lrwxrwxrwx 1 root root 10 Nov  2 17:43 12345678-1234-1234-1234-123456789abc -> ../../sda1

$ cat /proc/self/mounts | grep btrfs
/dev/sda2 /btrfs btrfs rw,relatime,space_cache=v2,subvolid=5,subvol=/ 0 0

$ findmnt --df /btrfs
SOURCE    FSTYPE SIZE  USED AVAIL USE% TARGET
/dev/sda2 btrfs    2G  5.8M  1.8G   0% /btrfs

$ mount --verbose -a
/                        : ignored
mount: /btrfs: /dev/sda1 already mounted or mount point busy.
$echo $?
32

$ umount /dev/sda1
umount: /dev/sda1: not mounted.
$ echo $?
32
----------------

I assume (RFC) this is because '/dev/disk/by-uuid,' '/proc/self/mounts,'
and 'findmnt' do not all reference the same device, resulting in the
'mount -a' and 'umount' failures. However, an empirically found solution
is to align them using a rule, such as the disk with the lowest 'devt,'
for a multi-device Btrfs filesystem.

I'm not yet sure (RFC) how to create a udev rule to point to the disk with
the lowest 'devt,' as this kernel patch does, and I believe it is
possible.

And this would ensure that '/proc/self/mounts,' 'findmnt,' and
'/dev/disk/by-uuid' all reference the same device.

After applying this patch, the above test passes. Unfortunately,
/dev/disk/by-uuid also points to the lowest 'devt' by chance, even though
no rule has been set as of now. As shown below.

----------------
$ mkfs.btrfs -qf --uuid 12345678-1234-1234-1234-123456789abc /dev/sda2 /dev/sda1

$ mount --verbose -a
/                        : ignored
/btrfs                   : successfully mounted

$ ls -l /dev/disk/by-uuid | grep 12345678-1234-1234-1234-123456789abc
lrwxrwxrwx 1 root root 10 Nov  2 17:53 12345678-1234-1234-1234-123456789abc -> ../../sda1

$ cat /proc/self/mounts | grep btrfs
/dev/sda1 /btrfs btrfs rw,relatime,space_cache=v2,subvolid=5,subvol=/ 0 0

$ findmnt --df /btrfs
SOURCE    FSTYPE SIZE  USED AVAIL USE% TARGET
/dev/sda1 btrfs    2G  5.8M  1.8G   0% /btrfs

$ mount --verbose -a
/                        : ignored
/btrfs                   : already mounted
$echo $?
0

$ umount /dev/sda1
$echo $?
0
----------------

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/super.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 66bdb6fd83bd..d768917cc5cc 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -2301,7 +2301,18 @@ 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 *fs_devices = btrfs_sb(root->d_sb)->fs_devices;
+	struct btrfs_device *device;
+	struct btrfs_device *first_device = NULL;
+
+	list_for_each_entry(device, &fs_devices->devices, dev_list) {
+		if (first_device == NULL) {
+			first_device = device;
+			continue;
+		}
+		if (first_device->devt > device->devt)
+			first_device = device;
+	}
 
 	/*
 	 * There should be always a valid pointer in latest_dev, it may be stale
@@ -2309,7 +2320,7 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root)
 	 * the end of RCU grace period.
 	 */
 	rcu_read_lock();
-	seq_escape(m, btrfs_dev_name(fs_info->fs_devices->latest_dev), " \t\n\\");
+	seq_escape(m, rcu_str_deref(first_device->name), " \t\n\\");
 	rcu_read_unlock();
 
 	return 0;
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2023-12-06 19:53 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-02 11:10 [PATCH RFC] btrfs: pick device with lowest devt for show_devname Anand Jain
2023-11-02 20:26 ` David Sterba
2023-11-02 22:55   ` Anand Jain
2023-11-20 14:42     ` David Sterba
2023-11-24 16:19 ` David Sterba
2023-11-25  1:09   ` Anand Jain
2023-11-27 11:48     ` Anand Jain
2023-11-28  8:00       ` Goffredo Baroncelli
2023-11-28 23:28         ` Anand Jain
2023-11-29 13:38           ` Andrei Borzenkov
2023-11-29 20:54           ` Goffredo Baroncelli
2023-12-05 17:44             ` David Sterba
2023-12-06 19:52               ` Goffredo Baroncelli
2023-12-05 17:43         ` David Sterba
2023-11-29 21:20 ` Goffredo Baroncelli

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.