diff options
| author | Yongpeng Yang <yangyongpeng@xiaomi.com> | 2026-04-03 22:40:17 +0800 |
|---|---|---|
| committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2026-04-13 22:51:29 +0000 |
| commit | ed78aeebef05212ef7dca93bd931e4eff67c113f (patch) | |
| tree | c4f09834207325f8ff6a638b625b50502d75b838 /include/linux/tc_act/git@git.tavy.me:linux-stable.git | |
| parent | 2a3db1e02ce08c14af04da70bb99e8a0a31eb9e8 (diff) | |
f2fs: fix node_cnt race between extent node destroy and writeback
f2fs_destroy_extent_node() does not set FI_NO_EXTENT before clearing
extent nodes. When called from f2fs_drop_inode() with I_SYNC set,
concurrent kworker writeback can insert new extent nodes into the same
extent tree, racing with the destroy and triggering f2fs_bug_on() in
__destroy_extent_node(). The scenario is as follows:
drop inode writeback
- iput
- f2fs_drop_inode // I_SYNC set
- f2fs_destroy_extent_node
- __destroy_extent_node
- while (node_cnt) {
write_lock(&et->lock)
__free_extent_tree
write_unlock(&et->lock)
- __writeback_single_inode
- f2fs_outplace_write_data
- f2fs_update_read_extent_cache
- __update_extent_tree_range
// FI_NO_EXTENT not set,
// insert new extent node
} // node_cnt == 0, exit while
- f2fs_bug_on(node_cnt) // node_cnt > 0
Additionally, __update_extent_tree_range() only checks FI_NO_EXTENT for
EX_READ type, leaving EX_BLOCK_AGE updates completely unprotected.
This patch set FI_NO_EXTENT under et->lock in __destroy_extent_node(),
consistent with other callers (__update_extent_tree_range and
__drop_extent_tree) and check FI_NO_EXTENT for both EX_READ and
EX_BLOCK_AGE tree.
Fixes: 3fc5d5a182f6 ("f2fs: fix to shrink read extent node in batches")
Cc: stable@vger.kernel.org
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'include/linux/tc_act/git@git.tavy.me:linux-stable.git')
0 files changed, 0 insertions, 0 deletions
