Re: [f2fs-dev] [PATCH RESEND 1/5] f2fs: fix extent merge failure when largest extent is not in rb-tree
Yongpeng Yang <[email protected]>
| Newsgroups | net.sourceforge.lists.linux-f2fs-devel |
|---|---|
| Message-ID | <SEZPR02MB5662938F64BC1B413D39A53699E22@SEZPR02MB5662.apcprd02.prod.outlook.com> |
On 6/15/26 7:26 PM, Chao Yu via Linux-f2fs-devel wrote: > On 6/12/26 19:58, Yongpeng Yang wrote: >> From: Yongpeng Yang <[email protected]> >> >> The following scenario can cause fiemap to report incorrect extents: >> >> $ mkfs.f2fs /dev/vdb -f >> $ mount -o mode=lfs /dev/vdb /mnt/f2fs/ >> $ dd if=/dev/urandom of=data bs=4K count=874 conv=notrunc >> $ f2fs_io fiemap 0 1000000 data 1 >> $ shrink all extent >> $ dd if=/dev/urandom of=data bs=4K count=150 seek=874 conv=notrunc >> $ f2fs_io fiemap 0 1000000 data 1 >> Fiemap: offset = 0 len = 1000000 >> logical addr. physical addr. length flags >> 0 0000000000000000 00000002868d4000 000000000036a000 00001000 >> 1 000000000036a000 0000000286c3e000 0000000000096000 00001001 >> >> The root cause is that when the largest extent is not in the extent >> tree, mergeable extents are not merged, causing f2fs_map_blocks to >> misjudge and output an incorrect extent list. >> >> Fix this by allowing the extent being inserted to merge with the largest >> extent. When updating the extent tree range, if the new extent can be >> front-merged or back-merged with the largest extent and the largest >> extent is not in the rb-tree, merge them before the normal lookup. >> >> Fixes: 429511cdf8b3 ("f2fs: add core functions for rb-tree extent cache") >> Signed-off-by: Yongpeng Yang <[email protected]> >> --- >> fs/f2fs/extent_cache.c | 21 +++++++++++++++++++++ >> 1 file changed, 21 insertions(+) >> >> diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c >> index 61f6b9714366..aa368a01b035 100644 >> --- a/fs/f2fs/extent_cache.c >> +++ b/fs/f2fs/extent_cache.c >> @@ -702,6 +702,27 @@ static void __update_extent_tree_range(struct inode *inode, >> __drop_largest_extent(et, fofs, len); >> } >> > > This can only be used for EX_READ? Yes, we only handle the case where the newly inserted mapping of EX_READ can be merged with the largest extent. > >> + if (et->largest.len != 0 && >> + (__is_front_mergeable(tei, &et->largest, type) || >> + __is_back_mergeable(tei, &et->largest, type))) { >> + /* 0. try to merge with largest extent. */ >> + en = __lookup_extent_node_ret(&et->root, >> + et->cached_en, et->largest.fofs, >> + &prev_en, &next_en, >> + &insert_p, &insert_parent, >> + &leftmost); >> + if (!en) { >> + if (__is_back_mergeable(tei, &et->largest, type)) { > > Can we reuse result of previous __is_back_mergeable()? OK, I'll change it in v2 patch. Thanks Yongpeng, > > Thanks, > >> + tei->fofs = et->largest.fofs; >> + tei->blk = et->largest.blk; >> + fofs = tei->fofs; >> + } >> + tei->len += et->largest.len; >> + len = tei->len; >> + end = fofs + len; >> + } >> + } >> + >> /* 1. lookup first extent node in range [fofs, fofs + len - 1] */ >> en = __lookup_extent_node_ret(&et->root, >> et->cached_en, fofs, > > > > _______________________________________________ > Linux-f2fs-devel mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel