btrfs: return accurate error code on open failure in open_fs_devices()

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>
This commit is contained in:
Anand Jain 2024-03-19 08:28:18 +05:30 committed by David Sterba
parent a8b70c7f86
commit 2f1aeab9fc

View File

@ -1184,23 +1184,30 @@ 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;
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_dev = latest_dev;