]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Mar 2024 12:17:40 +0000 (13:17 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Mar 2024 12:17:40 +0000 (13:17 +0100)
added patches:
btrfs-do-not-skip-re-registration-for-the-mounted-device.patch

queue-6.7/btrfs-do-not-skip-re-registration-for-the-mounted-device.patch [new file with mode: 0644]
queue-6.7/series

diff --git a/queue-6.7/btrfs-do-not-skip-re-registration-for-the-mounted-device.patch b/queue-6.7/btrfs-do-not-skip-re-registration-for-the-mounted-device.patch
new file mode 100644 (file)
index 0000000..2cc252a
--- /dev/null
@@ -0,0 +1,160 @@
+From d565fffa68560ac540bf3d62cc79719da50d5e7a Mon Sep 17 00:00:00 2001
+From: Anand Jain <anand.jain@oracle.com>
+Date: Tue, 13 Feb 2024 09:13:56 +0800
+Subject: btrfs: do not skip re-registration for the mounted device
+
+From: Anand Jain <anand.jain@oracle.com>
+
+commit d565fffa68560ac540bf3d62cc79719da50d5e7a upstream.
+
+There are reports that since version 6.7 update-grub fails to find the
+device of the root on systems without initrd and on a single device.
+
+This looks like the device name changed in the output of
+/proc/self/mountinfo:
+
+6.5-rc5 working
+
+  18 1 0:16 / / rw,noatime - btrfs /dev/sda8 ...
+
+6.7 not working:
+
+  17 1 0:15 / / rw,noatime - btrfs /dev/root ...
+
+and "update-grub" shows this error:
+
+  /usr/sbin/grub-probe: error: cannot find a device for / (is /dev mounted?)
+
+This looks like it's related to the device name, but grub-probe
+recognizes the "/dev/root" path and tries to find the underlying device.
+However there's a special case for some filesystems, for btrfs in
+particular.
+
+The generic root device detection heuristic is not done and it all
+relies on reading the device infos by a btrfs specific ioctl. This ioctl
+returns the device name as it was saved at the time of device scan (in
+this case it's /dev/root).
+
+The change in 6.7 for temp_fsid to allow several single device
+filesystem to exist with the same fsid (and transparently generate a new
+UUID at mount time) was to skip caching/registering such devices.
+
+This also skipped mounted device. One step of scanning is to check if
+the device name hasn't changed, and if yes then update the cached value.
+
+This broke the grub-probe as it always read the device /dev/root and
+couldn't find it in the system. A temporary workaround is to create a
+symlink but this does not survive reboot.
+
+The right fix is to allow updating the device path of a mounted
+filesystem even if this is a single device one.
+
+In the fix, check if the device's major:minor number matches with the
+cached device. If they do, then we can allow the scan to happen so that
+device_list_add() can take care of updating the device path. The file
+descriptor remains unchanged.
+
+This does not affect the temp_fsid feature, the UUID of the mounted
+filesystem remains the same and the matching is based on device major:minor
+which is unique per mounted filesystem.
+
+This covers the path when the device (that exists for all mounted
+devices) name changes, updating /dev/root to /dev/sdx. Any other single
+device with filesystem and is not mounted is still skipped.
+
+Note that if a system is booted and initial mount is done on the
+/dev/root device, this will be the cached name of the device. Only after
+the command "btrfs device scan" it will change as it triggers the
+rename.
+
+The fix was verified by users whose systems were affected.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218353
+Link: https://lore.kernel.org/lkml/CAKLYgeJ1tUuqLcsquwuFqjDXPSJpEiokrWK2gisPKDZLs8Y2TQ@mail.gmail.com/
+Fixes: bc27d6f0aa0e ("btrfs: scan but don't register device on single device filesystem")
+CC: stable@vger.kernel.org # 6.7+
+Tested-by: Alex Romosan <aromosan@gmail.com>
+Tested-by: CHECK_1234543212345@protonmail.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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/volumes.c |   57 +++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 47 insertions(+), 10 deletions(-)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -1290,6 +1290,47 @@ int btrfs_forget_devices(dev_t devt)
+       return ret;
+ }
++static bool btrfs_skip_registration(struct btrfs_super_block *disk_super,
++                                  const char *path, dev_t devt,
++                                  bool mount_arg_dev)
++{
++      struct btrfs_fs_devices *fs_devices;
++
++      /*
++       * Do not skip device registration for mounted devices with matching
++       * maj:min but different paths. Booting without initrd relies on
++       * /dev/root initially, later replaced with the actual root device.
++       * A successful scan ensures grub2-probe selects the correct device.
++       */
++      list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
++              struct btrfs_device *device;
++
++              mutex_lock(&fs_devices->device_list_mutex);
++
++              if (!fs_devices->opened) {
++                      mutex_unlock(&fs_devices->device_list_mutex);
++                      continue;
++              }
++
++              list_for_each_entry(device, &fs_devices->devices, dev_list) {
++                      if (device->bdev && (device->bdev->bd_dev == devt) &&
++                          strcmp(device->name->str, path) != 0) {
++                              mutex_unlock(&fs_devices->device_list_mutex);
++
++                              /* Do not skip registration. */
++                              return false;
++                      }
++              }
++              mutex_unlock(&fs_devices->device_list_mutex);
++      }
++
++      if (!mount_arg_dev && btrfs_super_num_devices(disk_super) == 1 &&
++          !(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_SEEDING))
++              return true;
++
++      return false;
++}
++
+ /*
+  * Look for a btrfs signature on a device. This may be called out of the mount path
+  * and we are not allowed to call set_blocksize during the scan. The superblock
+@@ -1346,18 +1387,14 @@ struct btrfs_device *btrfs_scan_one_devi
+               goto error_bdev_put;
+       }
+-      if (!mount_arg_dev && btrfs_super_num_devices(disk_super) == 1 &&
+-          !(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_SEEDING)) {
+-              dev_t devt;
++      if (btrfs_skip_registration(disk_super, path, bdev_handle->bdev->bd_dev,
++                                  mount_arg_dev)) {
++              pr_debug("BTRFS: skip registering single non-seed device %s (%d:%d)\n",
++                        path, MAJOR(bdev_handle->bdev->bd_dev),
++                        MINOR(bdev_handle->bdev->bd_dev));
+-              ret = lookup_bdev(path, &devt);
+-              if (ret)
+-                      btrfs_warn(NULL, "lookup bdev failed for path %s: %d",
+-                                 path, ret);
+-              else
+-                      btrfs_free_stale_devices(devt, NULL);
++              btrfs_free_stale_devices(bdev_handle->bdev->bd_dev, NULL);
+-              pr_debug("BTRFS: skip registering single non-seed device %s\n", path);
+               device = NULL;
+               goto free_disk_super;
+       }
index b4daac310b8f7fa48352143657480847947d363e..a90fd6275559355597986e974c6a7fcd5aa6b8d0 100644 (file)
@@ -318,3 +318,4 @@ efi-fix-panic-in-kdump-kernel.patch
 pwm-img-fix-pwm-clock-lookup.patch
 selftests-mm-gup_test-conform-test-to-tap-format-out.patch
 selftests-mm-fix-build-with-_fortify_source.patch
+btrfs-do-not-skip-re-registration-for-the-mounted-device.patch