mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-13 11:07:46 +10:00
btrfs: zoned: skip ZONE FINISH of conventional zones
[ Upstream commit f0ba0e7172
]
Don't call ZONE FINISH for conventional zones as this will result in I/O
errors. Instead check if the zone that needs finishing is a conventional
zone and if yes skip it.
Also factor out the actual handling of finishing a single zone into a
helper function, as do_zone_finish() is growing ever bigger and the
indentations levels are getting higher.
Reviewed-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
70a6e89b33
commit
6839108b66
@ -2186,6 +2186,40 @@ static void wait_eb_writebacks(struct btrfs_block_group *block_group)
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static int call_zone_finish(struct btrfs_block_group *block_group,
|
||||
struct btrfs_io_stripe *stripe)
|
||||
{
|
||||
struct btrfs_device *device = stripe->dev;
|
||||
const u64 physical = stripe->physical;
|
||||
struct btrfs_zoned_device_info *zinfo = device->zone_info;
|
||||
int ret;
|
||||
|
||||
if (!device->bdev)
|
||||
return 0;
|
||||
|
||||
if (zinfo->max_active_zones == 0)
|
||||
return 0;
|
||||
|
||||
if (btrfs_dev_is_sequential(device, physical)) {
|
||||
unsigned int nofs_flags;
|
||||
|
||||
nofs_flags = memalloc_nofs_save();
|
||||
ret = blkdev_zone_mgmt(device->bdev, REQ_OP_ZONE_FINISH,
|
||||
physical >> SECTOR_SHIFT,
|
||||
zinfo->zone_size >> SECTOR_SHIFT);
|
||||
memalloc_nofs_restore(nofs_flags);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(block_group->flags & BTRFS_BLOCK_GROUP_DATA))
|
||||
zinfo->reserved_active_zones++;
|
||||
btrfs_dev_clear_active_zone(device, physical);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_written)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = block_group->fs_info;
|
||||
@ -2270,31 +2304,12 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
|
||||
down_read(&dev_replace->rwsem);
|
||||
map = block_group->physical_map;
|
||||
for (i = 0; i < map->num_stripes; i++) {
|
||||
struct btrfs_device *device = map->stripes[i].dev;
|
||||
const u64 physical = map->stripes[i].physical;
|
||||
struct btrfs_zoned_device_info *zinfo = device->zone_info;
|
||||
unsigned int nofs_flags;
|
||||
|
||||
if (!device->bdev)
|
||||
continue;
|
||||
|
||||
if (zinfo->max_active_zones == 0)
|
||||
continue;
|
||||
|
||||
nofs_flags = memalloc_nofs_save();
|
||||
ret = blkdev_zone_mgmt(device->bdev, REQ_OP_ZONE_FINISH,
|
||||
physical >> SECTOR_SHIFT,
|
||||
zinfo->zone_size >> SECTOR_SHIFT);
|
||||
memalloc_nofs_restore(nofs_flags);
|
||||
|
||||
ret = call_zone_finish(block_group, &map->stripes[i]);
|
||||
if (ret) {
|
||||
up_read(&dev_replace->rwsem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(block_group->flags & BTRFS_BLOCK_GROUP_DATA))
|
||||
zinfo->reserved_active_zones++;
|
||||
btrfs_dev_clear_active_zone(device, physical);
|
||||
}
|
||||
up_read(&dev_replace->rwsem);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user