commit:     074767158010dc0de82a79a6ffaf553c57e29185
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 30 11:16:55 2024 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Dec 30 11:16:55 2024 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=07476715

btrfs: prefer to use "/dev/mapper/name" soft link instead of "/dev/dm-*"

Bug: https://bugs.gentoo.org/947126

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README                                    |   4 +
 1900_btrfs-dev-mapper-name-soft-link-fix.patch | 113 +++++++++++++++++++++++++
 2 files changed, 117 insertions(+)

diff --git a/0000_README b/0000_README
index 578b4cdb..a8f15c92 100644
--- a/0000_README
+++ b/0000_README
@@ -327,6 +327,10 @@ Patch:  1730_parisc-Disable-prctl.patch
 From:    
https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
 Desc:    prctl: Temporarily disable prctl(PR_SET_MDWE) on parisc
 
+Patch:  1900_btrfs-dev-mapper-name-soft-link-fix.patch
+From:    
https://lore.kernel.org/linux-btrfs/30aefd8b4e8c1f0c5051630b106a1ff3570d28ed.1735537399.git....@suse.com/T/#u
+Desc:    btrfs: prefer to use "/dev/mapper/name" soft link instead of 
"/dev/dm-*"
+
 Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   
https://lore.kernel.org/linux-bluetooth/[email protected]/raw
 Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. 
See bug #686758

diff --git a/1900_btrfs-dev-mapper-name-soft-link-fix.patch 
b/1900_btrfs-dev-mapper-name-soft-link-fix.patch
new file mode 100644
index 00000000..87404224
--- /dev/null
+++ b/1900_btrfs-dev-mapper-name-soft-link-fix.patch
@@ -0,0 +1,113 @@
+From git@z Thu Jan  1 00:00:00 1970
+Subject: [PATCH] btrfs: prefer to use "/dev/mapper/name" soft link instead
+ of "/dev/dm-*"
+From: Qu Wenruo <[email protected]>
+Date: Mon, 30 Dec 2024 19:15:53 +1030
+Message-Id: 
<30aefd8b4e8c1f0c5051630b106a1ff3570d28ed.1735537399.git....@suse.com>
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+[BUG]
+There is a gentoo bug report that upstream commit a5d74fa24752
+("btrfs: avoid unnecessary device path update for the same device") breaks
+6.6 LTS kernel behavior where previously lsblk can properly show multiple
+mount points of the same btrfs:
+
+ With kernel 6.6.62:
+ NAME         MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
+ sdb            8:16   0   9,1T  0 disk
+ └─sdb1         8:17   0   9,1T  0 part
+   └─hdd2     254:6    0   9,1T  0 crypt /mnt/hdd2
+                                         /var/cache/distfiles
+                                         /var/cache/binpkgs
+
+But not with that upstream commit backported:
+
+ With kernel 6.6.67:
+ sdb            8:16   0   9,1T  0 disk
+ └─sdb1         8:17   0   9,1T  0 part
+   └─hdd2     254:6    0   9,1T  0 crypt /mnt/hdd2
+
+[CAUSE]
+With that upstream patch backported to 6.6 LTS, the main change is in
+the mount info result:
+
+Before:
+ /dev/mapper/hdd2 /mnt/hdd2 btrfs 
rw,relatime,space_cache=v2,subvolid=382,subvol=/hdd2 0 0
+ /dev/mapper/hdd2 /mnt/dump btrfs 
rw,relatime,space_cache=v2,subvolid=393,subvol=/dump 0 0
+
+After:
+ /dev/dm-1 /mnt/hdd2 btrfs 
rw,relatime,space_cache=v2,subvolid=382,subvol=/hdd2 0 0
+ /dev/dm-1 /mnt/dump btrfs 
rw,relatime,space_cache=v2,subvolid=393,subvol=/dump 0 0
+
+I believe that change of mount device is causing problems for lsblk.
+
+And before that patch, even if udev registered "/dev/dm-1" to btrfs,
+later mount triggered a rescan and change the name back to
+"/dev/mapper/hdd2" thus older kernels will work as expected.
+
+But after that patch, if udev registered "/dev/dm-1", then mount
+triggered a rescan, but since btrfs detects both "/dev/dm-1" and
+"/dev/mapper/hdd2" are pointing to the same block device, btrfs refuses
+to do the rename, causing the less human readable "/dev/dm-1" to be
+there forever, and trigger the bug for lsblk.
+
+Fortunately for newer kernels, I guess due to the migration to fsconfig
+mount API, even if the end user explicitly mount the fs using
+"/dev/dm-1", the mount will resolve the path to "/dev/mapper/hdd2" link
+anyway.
+
+So for newer kernels it won't be a big deal but one extra safety net.
+
+[FIX]
+Add an extra exception for is_same_device(), that if both paths are
+pointing to the same device, but the newer path begins with "/dev/mapper"
+and the older path is not, then still treat them as different devices,
+so that we can rename to use the more human readable device path.
+
+Reported-by: David Duchesne <[email protected]>
+Link: https://bugs.gentoo.org/947126
+Fixes: a5d74fa24752 ("btrfs: avoid unnecessary device path update for the same 
device")
+Signed-off-by: Qu Wenruo <[email protected]>
+---
+Unfortunately I'm not yet 100% clear on why lsblk and libblkid failed to
+handle multiple mount points with "/dev/dm-*" path names (it can only
+show the first one).
+
+But since it's a behavior change caused by the backport, at least we
+should allow the rename to align the older behavior.
+---
+ fs/btrfs/volumes.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index c8b079ad1dfa..1d208968daf3 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -832,8 +832,20 @@ static bool is_same_device(struct btrfs_device *device, 
const char *new_path)
+       ret = kern_path(new_path, LOOKUP_FOLLOW, &new);
+       if (ret)
+               goto out;
+-      if (path_equal(&old, &new))
+-              is_same = true;
++      if (path_equal(&old, &new)) {
++              /*
++               * Special case for device mapper with its soft links.
++               *
++               * We can have the old path as "/dev/dm-3", but udev triggered
++               * rescan on the soft link "/dev/mapper/test".
++               * In that case we want to rename to that mapper link, to avoid
++               * a bug in libblkid where it can not handle multiple mount
++               * points if the device is "/dev/dm-3".
++               */
++              if (!strncmp(old_path, "/dev/mapper/", strlen("/dev/mapper")) &&
++                  strncmp(new_path, "/dev/mapper/", strlen("/dev/mapper")))
++                      is_same = true;
++      }
+ out:
+       kfree(old_path);
+       path_put(&old);
+-- 
+2.47.1
+

Reply via email to