Message ID | c13ae130cf4d170da60d9bde63de78e3583611df.1647425970.git.johannes.thumshirn@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] btrfs: zoned: use alloc_list instead of RCU locked device_list | expand |
On Wed, Mar 16, 2022 at 09:21:12AM -0700, Johannes Thumshirn wrote: > Anand pointed out, that instead of using the RCU locked version of > fs_devices->device_list we can use fs_devices->alloc_list, protected by > the chunk_mutex to traverse the list of active devices in > btrfs_can_activate_zone(). > > We are in the chunk allocation thread. The newer chunk allocation > happens from the devices in the fs_device->alloc_list protected by the > chunk_mutex. > > btrfs_create_chunk() > lockdep_assert_held(&info->chunk_mutex); > gather_device_info > list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) > > Also, a device that reappears after the mount won't join the alloc_list > yet and, it will be in the dev_list, which we don't want to consider in > the context of the chunk alloc. > > Suggested-by: Anand Jain <anand.jain@oracle.com> > Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> > --- > Changes since v1: > * Fix crash Anand reported Patch updated, thanks.
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index 49446bb5a5d1..1b1b310c3c51 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -1975,15 +1975,16 @@ int btrfs_zone_finish(struct btrfs_block_group *block_group) bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags) { + struct btrfs_fs_info *fs_info = fs_devices->fs_info; struct btrfs_device *device; bool ret = false; - if (!btrfs_is_zoned(fs_devices->fs_info)) + if (!btrfs_is_zoned(fs_info)) return true; /* Check if there is a device with active zones left */ - rcu_read_lock(); - list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) { + mutex_lock(&fs_info->chunk_mutex); + list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { struct btrfs_zoned_device_info *zinfo = device->zone_info; if (!device->bdev) @@ -1995,7 +1996,7 @@ bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags) break; } } - rcu_read_unlock(); + mutex_unlock(&fs_info->chunk_mutex); return ret; }
Anand pointed out, that instead of using the RCU locked version of fs_devices->device_list we can use fs_devices->alloc_list, protected by the chunk_mutex to traverse the list of active devices in btrfs_can_activate_zone(). We are in the chunk allocation thread. The newer chunk allocation happens from the devices in the fs_device->alloc_list protected by the chunk_mutex. btrfs_create_chunk() lockdep_assert_held(&info->chunk_mutex); gather_device_info list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) Also, a device that reappears after the mount won't join the alloc_list yet and, it will be in the dev_list, which we don't want to consider in the context of the chunk alloc. Suggested-by: Anand Jain <anand.jain@oracle.com> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> --- Changes since v1: * Fix crash Anand reported --- fs/btrfs/zoned.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)