Skip to content

Commit 20190e4

Browse files
Yongpeng Yanggregkh
authored andcommitted
f2fs: fix incorrect FI_NO_EXTENT handling in __destroy_extent_node()
commit 1f70ddb upstream. 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 commit ed78aee ("f2fs: fix node_cnt race between extent node destroy and writeback"), and remove the unnecessary zero check of et->node_cnt. Fixes: ed78aee ("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent ff83de5 commit 20190e4

1 file changed

Lines changed: 7 additions & 12 deletions

File tree

fs/f2fs/extent_cache.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,9 @@ static bool __may_extent_tree(struct inode *inode, enum extent_type type)
119119
if (!__init_may_extent_tree(inode, type))
120120
return false;
121121

122-
if (is_inode_flag_set(inode, FI_NO_EXTENT))
123-
return false;
124-
125122
if (type == EX_READ) {
123+
if (is_inode_flag_set(inode, FI_NO_EXTENT))
124+
return false;
126125
if (is_inode_flag_set(inode, FI_COMPRESSED_FILE) &&
127126
!f2fs_sb_has_readonly(F2FS_I_SB(inode)))
128127
return false;
@@ -645,14 +644,10 @@ static unsigned int __destroy_extent_node(struct inode *inode,
645644

646645
while (atomic_read(&et->node_cnt)) {
647646
write_lock(&et->lock);
648-
if (!is_inode_flag_set(inode, FI_NO_EXTENT))
649-
set_inode_flag(inode, FI_NO_EXTENT);
650647
node_cnt += __free_extent_tree(sbi, et, nr_shrink);
651648
write_unlock(&et->lock);
652649
}
653650

654-
f2fs_bug_on(sbi, atomic_read(&et->node_cnt));
655-
656651
return node_cnt;
657652
}
658653

@@ -691,12 +686,12 @@ static void __update_extent_tree_range(struct inode *inode,
691686

692687
write_lock(&et->lock);
693688

694-
if (is_inode_flag_set(inode, FI_NO_EXTENT)) {
695-
write_unlock(&et->lock);
696-
return;
697-
}
698-
699689
if (type == EX_READ) {
690+
if (is_inode_flag_set(inode, FI_NO_EXTENT)) {
691+
write_unlock(&et->lock);
692+
return;
693+
}
694+
700695
prev = et->largest;
701696
dei.len = 0;
702697

0 commit comments

Comments
 (0)