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>
This commit is contained in:
@@ -303,6 +303,9 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
rcu_assign_pointer(device->name, name);
|
rcu_assign_pointer(device->name, name);
|
||||||
|
ret = lookup_bdev(device_path, &device->devt);
|
||||||
|
if (ret)
|
||||||
|
goto error;
|
||||||
|
|
||||||
set_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
|
set_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
|
||||||
device->generation = 0;
|
device->generation = 0;
|
||||||
|
|||||||
@@ -808,11 +808,17 @@ static noinline struct btrfs_device *device_list_add(const char *path,
|
|||||||
struct rcu_string *name;
|
struct rcu_string *name;
|
||||||
u64 found_transid = btrfs_super_generation(disk_super);
|
u64 found_transid = btrfs_super_generation(disk_super);
|
||||||
u64 devid = btrfs_stack_device_id(&disk_super->dev_item);
|
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) &
|
bool has_metadata_uuid = (btrfs_super_incompat_flags(disk_super) &
|
||||||
BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
|
BTRFS_FEATURE_INCOMPAT_METADATA_UUID);
|
||||||
bool fsid_change_in_progress = (btrfs_super_flags(disk_super) &
|
bool fsid_change_in_progress = (btrfs_super_flags(disk_super) &
|
||||||
BTRFS_SUPER_FLAG_CHANGING_FSID_V2);
|
BTRFS_SUPER_FLAG_CHANGING_FSID_V2);
|
||||||
|
|
||||||
|
error = lookup_bdev(path, &path_devt);
|
||||||
|
if (error)
|
||||||
|
return ERR_PTR(error);
|
||||||
|
|
||||||
if (fsid_change_in_progress) {
|
if (fsid_change_in_progress) {
|
||||||
if (!has_metadata_uuid)
|
if (!has_metadata_uuid)
|
||||||
fs_devices = find_fsid_inprogress(disk_super);
|
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);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
rcu_assign_pointer(device->name, name);
|
rcu_assign_pointer(device->name, name);
|
||||||
|
device->devt = path_devt;
|
||||||
|
|
||||||
list_add_rcu(&device->dev_list, &fs_devices->devices);
|
list_add_rcu(&device->dev_list, &fs_devices->devices);
|
||||||
fs_devices->num_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
|
* make sure it's the same device if the device is mounted
|
||||||
*/
|
*/
|
||||||
if (device->bdev) {
|
if (device->bdev) {
|
||||||
int error;
|
if (device->devt != path_devt) {
|
||||||
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) {
|
|
||||||
mutex_unlock(&fs_devices->device_list_mutex);
|
mutex_unlock(&fs_devices->device_list_mutex);
|
||||||
/*
|
/*
|
||||||
* device->fs_info may not be reliable here, so
|
* 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--;
|
fs_devices->missing_devices--;
|
||||||
clear_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state);
|
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);
|
device = device_list_add(path, disk_super, &new_device_added);
|
||||||
if (!IS_ERR(device) && new_device_added) {
|
if (!IS_ERR(device) && new_device_added)
|
||||||
dev_t devt;
|
btrfs_free_stale_devices(device->devt, device);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
btrfs_release_disk_super(disk_super);
|
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;
|
int ret = 0;
|
||||||
bool seeding_dev = false;
|
bool seeding_dev = false;
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
dev_t devt;
|
|
||||||
|
|
||||||
if (sb_rdonly(sb) && !fs_devices->seeding)
|
if (sb_rdonly(sb) && !fs_devices->seeding)
|
||||||
return -EROFS;
|
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->fs_info = fs_info;
|
||||||
device->bdev = bdev;
|
device->bdev = bdev;
|
||||||
|
ret = lookup_bdev(device_path, &device->devt);
|
||||||
|
if (ret)
|
||||||
|
goto error_free_device;
|
||||||
|
|
||||||
ret = btrfs_get_dev_zone_info(device, false);
|
ret = btrfs_get_dev_zone_info(device, false);
|
||||||
if (ret)
|
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
|
* 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
|
* other fs_devices list if device_path alienates any other scanned
|
||||||
* device.
|
* 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
|
* We can ignore the return value as it typically returns -EINVAL and
|
||||||
* only succeeds if the device was an alien.
|
* only succeeds if the device was an alien.
|
||||||
*/
|
*/
|
||||||
if (lookup_bdev(device_path, &devt) == 0)
|
btrfs_forget_devices(device->devt);
|
||||||
btrfs_forget_devices(devt);
|
|
||||||
|
|
||||||
/* Update ctime/mtime for blkid or udev */
|
/* Update ctime/mtime for blkid or udev */
|
||||||
update_dev_time(device_path);
|
update_dev_time(device_path);
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ struct btrfs_device {
|
|||||||
/* the mode sent to blkdev_get */
|
/* the mode sent to blkdev_get */
|
||||||
fmode_t mode;
|
fmode_t mode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Device's major-minor number. Must be set even if the device is not
|
||||||
|
* opened (bdev == NULL), unless the device is missing.
|
||||||
|
*/
|
||||||
|
dev_t devt;
|
||||||
unsigned long dev_state;
|
unsigned long dev_state;
|
||||||
blk_status_t last_flush_error;
|
blk_status_t last_flush_error;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user