summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorAnand Jain <anand.jain@oracle.com>2022-01-12 13:06:01 +0800
committerDavid Sterba <dsterba@suse.com>2022-03-14 13:13:47 +0100
commit4889bc05a96e039b055bbd11438c40bf956f057b (patch)
tree161cbf1dca6d039fb8528da67d395e93adbd43ca /fs/btrfs/volumes.c
parent16cab91a0c8fea50a03ef9c49ca829e6c0c4cf66 (diff)
downloadlinux-4889bc05a96e039b055bbd11438c40bf956f057b.tar.bz2
btrfs: add device major-minor info in the struct btrfs_device
Internally it is common to use the major-minor number to identify a device and, at a few locations in btrfs, we use the major-minor number to match the device. So when we identify a new btrfs device through device add or device replace or device-scan/ready save the device's major-minor (dev_t) in the struct btrfs_device so that we don't have to call lookup_bdev() again. Signed-off-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c40
1 files changed, 15 insertions, 25 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b47dd1387766..ebe655eb8b4d 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -808,11 +808,17 @@ static noinline struct btrfs_device *device_list_add(const char *path,
struct rcu_string *name;
u64 found_transid = btrfs_super_generation(disk_super);
u64 devid = btrfs_stack_device_id(&disk_super->dev_item);
+ dev_t path_devt;
+ int error;
bool has_metadata_uuid = (btrfs_super_incompat_flags(disk_super) &
BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
bool fsid_change_in_progress = (btrfs_super_flags(disk_super) &
BTRFS_SUPER_FLAG_CHANGING_FSID_V2);
+ error = lookup_bdev(path, &path_devt);
+ if (error)
+ return ERR_PTR(error);
+
if (fsid_change_in_progress) {
if (!has_metadata_uuid)
fs_devices = find_fsid_inprogress(disk_super);
@@ -895,6 +901,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
return ERR_PTR(-ENOMEM);
}
rcu_assign_pointer(device->name, name);
+ device->devt = path_devt;
list_add_rcu(&device->dev_list, &fs_devices->devices);
fs_devices->num_devices++;
@@ -957,16 +964,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
* make sure it's the same device if the device is mounted
*/
if (device->bdev) {
- int error;
- dev_t path_dev;
-
- error = lookup_bdev(path, &path_dev);
- if (error) {
- mutex_unlock(&fs_devices->device_list_mutex);
- return ERR_PTR(error);
- }
-
- if (device->bdev->bd_dev != path_dev) {
+ if (device->devt != path_devt) {
mutex_unlock(&fs_devices->device_list_mutex);
/*
* device->fs_info may not be reliable here, so
@@ -999,6 +997,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
fs_devices->missing_devices--;
clear_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state);
}
+ device->devt = path_devt;
}
/*
@@ -1412,16 +1411,8 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags,
}
device = device_list_add(path, disk_super, &new_device_added);
- if (!IS_ERR(device) && new_device_added) {
- dev_t devt;
-
- /*
- * It is ok to ignore if we fail to free the stale device (if
- * any). As there is nothing much that can be done about it.
- */
- if (lookup_bdev(path, &devt) == 0)
- btrfs_free_stale_devices(devt, device);
- }
+ if (!IS_ERR(device) && new_device_added)
+ btrfs_free_stale_devices(device->devt, device);
btrfs_release_disk_super(disk_super);
@@ -2652,7 +2643,6 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
int ret = 0;
bool seeding_dev = false;
bool locked = false;
- dev_t devt;
if (sb_rdonly(sb) && !fs_devices->seeding)
return -EROFS;
@@ -2702,6 +2692,9 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
device->fs_info = fs_info;
device->bdev = bdev;
+ ret = lookup_bdev(device_path, &device->devt);
+ if (ret)
+ goto error_free_device;
ret = btrfs_get_dev_zone_info(device, false);
if (ret)
@@ -2845,13 +2838,10 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
* Now that we have written a new super block to this device, check all
* other fs_devices list if device_path alienates any other scanned
* device.
- * Skip forget_deivces if lookup_bdev() fails as there is nothing much
- * that can be done about it.
* We can ignore the return value as it typically returns -EINVAL and
* only succeeds if the device was an alien.
*/
- if (lookup_bdev(device_path, &devt) == 0)
- btrfs_forget_devices(devt);
+ btrfs_forget_devices(device->devt);
/* Update ctime/mtime for blkid or udev */
update_dev_time(device_path);