Message ID | d995c6d145d65b93fc1be56d5c5dfab869f50911.1611627788.git.naohiro.aota@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: zoned block device support | expand |
On 1/26/2021 10:24 AM, Naohiro Aota wrote: > This is preparation patch to implement zone emulation on a regular device. > > To emulate zoned mode on a regular (non-zoned) device, we need to decide an > emulating zone size. Instead of making it compile-time static value, we'll > make it configurable at mkfs time. Since we have one zone == one device > extent restriction, we can determine the emulated zone size from the size > of a device extent. We can extend btrfs_get_dev_zone_info() to show a > regular device filled with conventional zones once the zone size is > decided. > > The current call site of btrfs_get_dev_zone_info() during the mount process > is earlier than reading the trees, so we can't slice a regular device to > conventional zones. This patch defers the loading of zone info to > open_ctree() to load the emulated zone size from a device extent. > > Reviewed-by: Josef Bacik <josef@toxicpanda.com> > Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Patches are already in for-next. My apologies for the delay in review here and in the following patches how many ever I could. Reviewed-by: Anand Jain <anand.jain@oracle.com> Thanks. > --- > fs/btrfs/disk-io.c | 13 +++++++++++++ > fs/btrfs/volumes.c | 4 ---- > fs/btrfs/zoned.c | 24 ++++++++++++++++++++++++ > fs/btrfs/zoned.h | 7 +++++++ > 4 files changed, 44 insertions(+), 4 deletions(-) > > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c > index 5473bed6a7e8..39cbe10a81b6 100644 > --- a/fs/btrfs/disk-io.c > +++ b/fs/btrfs/disk-io.c > @@ -3257,6 +3257,19 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device > if (ret) > goto fail_tree_roots; > > + /* > + * Get zone type information of zoned block devices. This will also > + * handle emulation of the zoned mode for btrfs if a regular device has > + * the zoned incompat feature flag set. > + */ > + ret = btrfs_get_dev_zone_info_all_devices(fs_info); > + if (ret) { > + btrfs_err(fs_info, > + "failed to read device zone info: %d", > + ret); > + goto fail_block_groups; > + } > + > /* > * If we have a uuid root and we're not being told to rescan we need to > * check the generation here so we can set the > diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c > index badb972919eb..bb3f341f6a22 100644 > --- a/fs/btrfs/volumes.c > +++ b/fs/btrfs/volumes.c > @@ -669,10 +669,6 @@ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices, > clear_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state); > device->mode = flags; > > - ret = btrfs_get_dev_zone_info(device); > - if (ret != 0) > - goto error_free_page; > - > fs_devices->open_devices++; > if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) && > device->devid != BTRFS_DEV_REPLACE_DEVID) { > diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c > index c38846659019..bcabdb2c97f1 100644 > --- a/fs/btrfs/zoned.c > +++ b/fs/btrfs/zoned.c > @@ -143,6 +143,30 @@ static int btrfs_get_dev_zones(struct btrfs_device *device, u64 pos, > return 0; > } > > +int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info) > +{ > + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; > + struct btrfs_device *device; > + int ret = 0; > + > + if (!btrfs_fs_incompat(fs_info, ZONED)) > + return 0; > + > + mutex_lock(&fs_devices->device_list_mutex); > + list_for_each_entry(device, &fs_devices->devices, dev_list) { > + /* We can skip reading of zone info for missing devices */ > + if (!device->bdev) > + continue; > + > + ret = btrfs_get_dev_zone_info(device); > + if (ret) > + break; > + } > + mutex_unlock(&fs_devices->device_list_mutex); > + > + return ret; > +} > + > int btrfs_get_dev_zone_info(struct btrfs_device *device) > { > struct btrfs_zoned_device_info *zone_info = NULL; > diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h > index 8abe2f83272b..5e0e7de84a82 100644 > --- a/fs/btrfs/zoned.h > +++ b/fs/btrfs/zoned.h > @@ -25,6 +25,7 @@ struct btrfs_zoned_device_info { > #ifdef CONFIG_BLK_DEV_ZONED > int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, > struct blk_zone *zone); > +int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info); > int btrfs_get_dev_zone_info(struct btrfs_device *device); > void btrfs_destroy_dev_zone_info(struct btrfs_device *device); > int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info); > @@ -42,6 +43,12 @@ static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, > return 0; > } > > +static inline int btrfs_get_dev_zone_info_all_devices( > + struct btrfs_fs_info *fs_info) > +{ > + return 0; > +} > + > static inline int btrfs_get_dev_zone_info(struct btrfs_device *device) > { > return 0; >
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 5473bed6a7e8..39cbe10a81b6 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3257,6 +3257,19 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device if (ret) goto fail_tree_roots; + /* + * Get zone type information of zoned block devices. This will also + * handle emulation of the zoned mode for btrfs if a regular device has + * the zoned incompat feature flag set. + */ + ret = btrfs_get_dev_zone_info_all_devices(fs_info); + if (ret) { + btrfs_err(fs_info, + "failed to read device zone info: %d", + ret); + goto fail_block_groups; + } + /* * If we have a uuid root and we're not being told to rescan we need to * check the generation here so we can set the diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index badb972919eb..bb3f341f6a22 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -669,10 +669,6 @@ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices, clear_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state); device->mode = flags; - ret = btrfs_get_dev_zone_info(device); - if (ret != 0) - goto error_free_page; - fs_devices->open_devices++; if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) && device->devid != BTRFS_DEV_REPLACE_DEVID) { diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index c38846659019..bcabdb2c97f1 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -143,6 +143,30 @@ static int btrfs_get_dev_zones(struct btrfs_device *device, u64 pos, return 0; } +int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info) +{ + struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; + struct btrfs_device *device; + int ret = 0; + + if (!btrfs_fs_incompat(fs_info, ZONED)) + return 0; + + mutex_lock(&fs_devices->device_list_mutex); + list_for_each_entry(device, &fs_devices->devices, dev_list) { + /* We can skip reading of zone info for missing devices */ + if (!device->bdev) + continue; + + ret = btrfs_get_dev_zone_info(device); + if (ret) + break; + } + mutex_unlock(&fs_devices->device_list_mutex); + + return ret; +} + int btrfs_get_dev_zone_info(struct btrfs_device *device) { struct btrfs_zoned_device_info *zone_info = NULL; diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h index 8abe2f83272b..5e0e7de84a82 100644 --- a/fs/btrfs/zoned.h +++ b/fs/btrfs/zoned.h @@ -25,6 +25,7 @@ struct btrfs_zoned_device_info { #ifdef CONFIG_BLK_DEV_ZONED int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, struct blk_zone *zone); +int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info); int btrfs_get_dev_zone_info(struct btrfs_device *device); void btrfs_destroy_dev_zone_info(struct btrfs_device *device); int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info); @@ -42,6 +43,12 @@ static inline int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos, return 0; } +static inline int btrfs_get_dev_zone_info_all_devices( + struct btrfs_fs_info *fs_info) +{ + return 0; +} + static inline int btrfs_get_dev_zone_info(struct btrfs_device *device) { return 0;