Skip to content

Commit d5b81ce

Browse files
naotakdave
authored andcommitted
btrfs: zoned: fix API misuse of zone finish waiting
The commit 2ce543f ("btrfs: zoned: wait until zone is finished when allocation didn't progress") implemented a zone finish waiting mechanism to the write path of zoned mode. However, using wait_var_event()/wake_up_all() on fs_info->zone_finish_wait is wrong and wait_var_event() just hangs because no one ever wakes it up once it goes into sleep. Instead, we can simply use wait_on_bit_io() and clear_and_wake_up_bit() on fs_info->flags with a proper barrier installed. Fixes: 2ce543f ("btrfs: zoned: wait until zone is finished when allocation didn't progress") CC: [email protected] # 5.16+ Signed-off-by: Naohiro Aota <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent f2c3bec commit d5b81ce

File tree

4 files changed

+4
-9
lines changed

4 files changed

+4
-9
lines changed

fs/btrfs/ctree.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,6 @@ struct btrfs_fs_info {
10881088

10891089
spinlock_t zone_active_bgs_lock;
10901090
struct list_head zone_active_bgs;
1091-
/* Waiters when BTRFS_FS_NEED_ZONE_FINISH is set */
1092-
wait_queue_head_t zone_finish_wait;
10931091

10941092
/* Updates are not protected by any lock */
10951093
struct btrfs_commit_stats commit_stats;

fs/btrfs/disk-io.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3070,7 +3070,6 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
30703070
init_waitqueue_head(&fs_info->transaction_blocked_wait);
30713071
init_waitqueue_head(&fs_info->async_submit_wait);
30723072
init_waitqueue_head(&fs_info->delayed_iputs_wait);
3073-
init_waitqueue_head(&fs_info->zone_finish_wait);
30743073

30753074
/* Usable values until the real ones are cached from the superblock */
30763075
fs_info->nodesize = 4096;

fs/btrfs/inode.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,10 +1644,9 @@ static noinline int run_delalloc_zoned(struct btrfs_inode *inode,
16441644
done_offset = end;
16451645

16461646
if (done_offset == start) {
1647-
struct btrfs_fs_info *info = inode->root->fs_info;
1648-
1649-
wait_var_event(&info->zone_finish_wait,
1650-
!test_bit(BTRFS_FS_NEED_ZONE_FINISH, &info->flags));
1647+
wait_on_bit_io(&inode->root->fs_info->flags,
1648+
BTRFS_FS_NEED_ZONE_FINISH,
1649+
TASK_UNINTERRUPTIBLE);
16511650
continue;
16521651
}
16531652

fs/btrfs/zoned.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,8 +2007,7 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
20072007
/* For active_bg_list */
20082008
btrfs_put_block_group(block_group);
20092009

2010-
clear_bit(BTRFS_FS_NEED_ZONE_FINISH, &fs_info->flags);
2011-
wake_up_all(&fs_info->zone_finish_wait);
2010+
clear_and_wake_up_bit(BTRFS_FS_NEED_ZONE_FINISH, &fs_info->flags);
20122011

20132012
return 0;
20142013
}

0 commit comments

Comments
 (0)