mirror of
https://github.com/torvalds/linux.git
synced 2026-07-31 03:27:03 +02:00
f2fs: fix incorrect FI_NO_EXTENT handling in __destroy_extent_node()
When __destroy_extent_node() sets the inode flag FI_NO_EXTENT, it does not reset the length of the largest extent to 0 and update the inode folio. Since modifications to the extent tree are disallowed afterward, the cached largest extent may become stale. This can trigger the following error in xfstests generic/388: F2FS-fs (dm-0): sanity_check_extent_cache: inode (ino=1761) extent info [220057, 57, 6] is incorrect, run fsck to fix In the f2fs_drop_inode path, __destroy_extent_node() does not need to guarantee that et->node_cnt is 0, because concurrency with writeback is expected in this path, and writeback may update the extent cache. This patch reverts commited78aeebef("f2fs: fix node_cnt race between extent node destroy and writeback"), and remove the unnecessary zero check of et->node_cnt. Fixes:ed78aeebef("f2fs: fix node_cnt race between extent node destroy and writeback") Cc: stable@vger.kernel.org Reported-by: Chao Yu <chao@kernel.org> Suggested-by: Chao Yu <chao@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>
This commit is contained in:
parent
ccc6436abb
commit
1f70ddb28a
|
|
@ -119,10 +119,9 @@ static bool __may_extent_tree(struct inode *inode, enum extent_type type)
|
|||
if (!__init_may_extent_tree(inode, type))
|
||||
return false;
|
||||
|
||||
if (is_inode_flag_set(inode, FI_NO_EXTENT))
|
||||
return false;
|
||||
|
||||
if (type == EX_READ) {
|
||||
if (is_inode_flag_set(inode, FI_NO_EXTENT))
|
||||
return false;
|
||||
if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
|
||||
!f2fs_sb_has_readonly(F2FS_I_SB(inode)))
|
||||
return false;
|
||||
|
|
@ -645,14 +644,10 @@ static unsigned int __destroy_extent_node(struct inode *inode,
|
|||
|
||||
while (atomic_read(&et->node_cnt)) {
|
||||
write_lock(&et->lock);
|
||||
if (!is_inode_flag_set(inode, FI_NO_EXTENT))
|
||||
set_inode_flag(inode, FI_NO_EXTENT);
|
||||
node_cnt += __free_extent_tree(sbi, et, nr_shrink);
|
||||
write_unlock(&et->lock);
|
||||
}
|
||||
|
||||
f2fs_bug_on(sbi, atomic_read(&et->node_cnt));
|
||||
|
||||
return node_cnt;
|
||||
}
|
||||
|
||||
|
|
@ -691,12 +686,12 @@ static void __update_extent_tree_range(struct inode *inode,
|
|||
|
||||
write_lock(&et->lock);
|
||||
|
||||
if (is_inode_flag_set(inode, FI_NO_EXTENT)) {
|
||||
write_unlock(&et->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == EX_READ) {
|
||||
if (is_inode_flag_set(inode, FI_NO_EXTENT)) {
|
||||
write_unlock(&et->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
prev = et->largest;
|
||||
dei.len = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user