]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blobdiff - queue-5.10/btrfs-return-accurate-error-code-on-open-failure-in-.patch
Fixes for 5.10
[thirdparty/kernel/stable-queue.git] / queue-5.10 / btrfs-return-accurate-error-code-on-open-failure-in-.patch
diff --git a/queue-5.10/btrfs-return-accurate-error-code-on-open-failure-in-.patch b/queue-5.10/btrfs-return-accurate-error-code-on-open-failure-in-.patch
new file mode 100644 (file)
index 0000000..999027b
--- /dev/null
@@ -0,0 +1,76 @@
+From 87c3de6800f1078c2a2388438b035436fae53e28 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Mar 2024 08:28:18 +0530
+Subject: btrfs: return accurate error code on open failure in
+ open_fs_devices()
+
+From: Anand Jain <anand.jain@oracle.com>
+
+[ Upstream commit 2f1aeab9fca1a5f583be1add175d1ee95c213cfa ]
+
+When attempting to exclusive open a device which has no exclusive open
+permission, such as a physical device associated with the flakey dm
+device, the open operation will fail, resulting in a mount failure.
+
+In this particular scenario, we erroneously return -EINVAL instead of the
+correct error code provided by the bdev_open_by_path() function, which is
+-EBUSY.
+
+Fix this, by returning error code from the bdev_open_by_path() function.
+With this correction, the mount error message will align with that of
+ext4 and xfs.
+
+Reviewed-by: Boris Burkov <boris@bur.io>
+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: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/volumes.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 09c23626feba4..51298d749824c 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -1266,25 +1266,32 @@ static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
+       struct btrfs_device *device;
+       struct btrfs_device *latest_dev = NULL;
+       struct btrfs_device *tmp_device;
++      int ret = 0;
+       flags |= FMODE_EXCL;
+       list_for_each_entry_safe(device, tmp_device, &fs_devices->devices,
+                                dev_list) {
+-              int ret;
++              int ret2;
+-              ret = btrfs_open_one_device(fs_devices, device, flags, holder);
+-              if (ret == 0 &&
++              ret2 = btrfs_open_one_device(fs_devices, device, flags, holder);
++              if (ret2 == 0 &&
+                   (!latest_dev || device->generation > latest_dev->generation)) {
+                       latest_dev = device;
+-              } else if (ret == -ENODATA) {
++              } else if (ret2 == -ENODATA) {
+                       fs_devices->num_devices--;
+                       list_del(&device->dev_list);
+                       btrfs_free_device(device);
+               }
++              if (ret == 0 && ret2 != 0)
++                      ret = ret2;
+       }
+-      if (fs_devices->open_devices == 0)
++
++      if (fs_devices->open_devices == 0) {
++              if (ret)
++                      return ret;
+               return -EINVAL;
++      }
+       fs_devices->opened = 1;
+       fs_devices->latest_bdev = latest_dev->bdev;
+-- 
+2.43.0
+