Re: [f2fs-dev] [RFC PATCH v2 0/5] f2fs: introduce inline extent mapping for inode data blocks
Yongpeng Yang <[email protected]> Mon, 13 Jul 2026 21:39:20 +0800
| Newsgroups | net.sourceforge.lists.linux-f2fs-devel |
|---|---|
| Message-ID | <SEZPR02MB5662D6AE1DC030A20333BA2D99FA2@SEZPR02MB5662.apcprd02.prod.outlook.com> |
On 7/2/26 22:30, Jaegeuk Kim via Linux-f2fs-devel wrote: > On 06/25, Chao Yu via Linux-f2fs-devel wrote: >> Sorry for the delay. >> >> On 5/29/26 16:56, Yongpeng Yang wrote: >>> From: Yongpeng Yang <[email protected]> >>> >>> Changes since v1: >>> - Introduce tracepoints for f2fs_iext_update_data_blkaddr and >>> f2fs_iext_lookup_blkaddr to aid debugging (new patch 5/5). >>> - Bypass inline extent lookup for F2FS_GET_BLOCK_PRECACHE to ensure all >>> mappings are loaded into the read extent cache. >>> - Unify the check for fofs exceeding direct_blocks range to use >>> "fofs >= direct_blocks" consistently. >>> - Remove support for caching NULL_ADDR in inline extent area. If a fofs >>> within [0, direct_blocks) is not found in inline extent, it implies >>> NULL_ADDR. This simplifies merge and split logic. >>> - Fix f2fs_iext_enable_inline_extent to use PTR_ERR instead of -ENOMEM. >>> - Change f2fs_iext_convert_to_inline_extent return type to bool. >>> - Add benchmark data covering 4K/8K/32K/64K random read. >>> - Rename __is_extent_mergeable to __is_iextent_mergeable to avoid >>> naming collision with extent cache code. >>> - Remove inode parameter from f2fs_iext_sanity_check (always NULL). >>> - Reduce #ifdef CONFIG_F2FS_INLINE_EXTENT nesting in node.c. >>> - Code style fixes to comply with kernel coding style. >>> >>> This patchset introduces an inline extent mapping mechanism for f2fs. >>> Instead of storing individual block addresses in the inode's data block >>> address area (i_addr[]), this feature packs contiguous block ranges into >>> compact extent entries, significantly reducing the number of entries >>> needed and enabling faster block address lookups via binary search. >>> >>> The inline extent format is identified by magic numbers in the inode >>> data area and is transparent to the rest of f2fs -- when the extent >>> area is full or cannot represent the mapping efficiently, it >>> automatically converts back to the direct block address format. >>> >>> Patch 1: Preparatory refactoring -- replace raw pointer arithmetic >>> with f2fs_data_blkaddr() to abstract block address access. >>> Patch 2: Core implementation -- data structures, extent operations >>> (lookup, insert, merge, split, truncate), format conversion, >>> and integration with f2fs data/node paths. >>> Patch 3: ioctl interface -- allow per-file enable/disable of inline >>> extent format via F2FS_EXTENT_FL flag. >>> Patch 4: sysfs interface -- runtime enable/disable toggle and file >>> extension list for automatic inline extent activation. >>> Patch 5: Tracepoints for inline extent lookup and update operations. >>> >>> Test setup and results: >>> ======================= >>> >>> Platform: Xiaomi smartphone, UFS 4.0 storage >>> >>> # Enable inline extent >>> echo 1 > /sys/fs/f2fs/<dev>/inline_extent_enable >>> echo 'mp4' > /sys/fs/f2fs/<dev>/inline_extent_extension_list >>> >>> # Prepare data: write with 4K offset stride to create fragmented >>> # extents, then overwrite sequentially so inline extent can cache >>> # all mappings in compact form. >>> fio --name=test --filename=data.mp4 --rw=write:4k --bs=64M \ >>> --size=8G --ioengine=libaio --direct=1 >>> sync >>> fio --name=test --filename=data.mp4 --rw=write --bs=64M \ >>> --size=8G --ioengine=libaio --direct=1 >>> sync >>> echo 3 > /proc/sys/vm/drop_caches >>> >>> # Benchmark: random buffered read, 1GB total IO >>> fio --name=buffer-read --ioengine=libaio --rw=randread --bs=$BS \ >>> --size=8G --io_size=1G --numjobs=1 --filename=data.mp4 >>> >>> Results (random read bandwidth, MiB/s): >>> +---------------------------------------------------+ >>> | BS | baseline | inline ext | improvement | >>> |--------+----------+------------+------------------| >>> | 4K | 35 | 36 | +2.5% | >>> | 8K | 60 | 62 | +3% | >>> | 32K | 179 | 191 | +6.8% | >>> | 64K | 284 | 321 | +13% | >>> +---------------------------------------------------+ >>> >>> The improvement comes from eliminating direct/indirect node page reads >>> during block address lookup -- all mappings are stored directly in >>> the inode page and found via O(log n) binary search. >>> >>> Yongpeng Yang (5): >>> f2fs: replace raw dnode pointer arithmetic with f2fs_data_blkaddr() >>> f2fs: introduce inline extent mapping for inode data blocks >>> f2fs: support setting inline extent flag via ioctl >>> f2fs: add sysfs interface for inline extent management >>> f2fs: introduce tracepoints for inline extent lookup and update >>> >>> fs/f2fs/Kconfig | 18 + >>> fs/f2fs/Makefile | 1 + >>> fs/f2fs/data.c | 157 ++++++- >>> fs/f2fs/debug.c | 4 + >>> fs/f2fs/dir.c | 9 + >>> fs/f2fs/f2fs.h | 23 +- >>> fs/f2fs/file.c | 93 +++- >>> fs/f2fs/iextent.c | 873 ++++++++++++++++++++++++++++++++++++ >>> fs/f2fs/iextent.h | 187 ++++++++ >>> fs/f2fs/inline.c | 7 + >>> fs/f2fs/namei.c | 48 ++ >>> fs/f2fs/node.c | 66 ++- >>> fs/f2fs/node.h | 4 + >>> fs/f2fs/recovery.c | 17 + >>> fs/f2fs/super.c | 13 + >>> fs/f2fs/sysfs.c | 52 +++ >>> include/trace/events/f2fs.h | 79 ++++ >>> 17 files changed, 1635 insertions(+), 16 deletions(-) >> >> It's quite a large number of change (including f2fs-tools change) to support >> this new feature, it causes the performance price ratio a little bit low. >> >> About inode disk layout, as we discuss offline, maybe we can add 4 or 8 ... >> extents in i_extra_attr area of f2fs_inode structure, it can reduce the >> change line and code complex, however, not sure how will it affect the >> benefits. >> >> To Jaegeuk, please share your thoughts on this feature. > > Agreed. Can we try to add more extents simply? Thanks for the feedback and sorry for the delay! Here is a simpler design I'd like to propose for adding more extents: 1) Shrink i_compr_blocks from __le64 to __le32, reuse the freed upper 32 bits as a new field: i_inline_ext_capacity. The in-kernel fi->i_compr_blocks is already atomic_t (32-bit), so the 64-bit on-disk width was never fully utilized. /* before */ __le64 i_compr_blocks; /* after */ __le32 i_compr_blocks; __le32 i_inline_ext_capacity; /* # of extent entries */ 2) Place the inline extent area immediately after i_extra_end[0]. The area format is: struct f2fs_iext_header followed by a struct f2fs_extent array, reusing the same inline extent format from v2, but without the magic number (since i_inline_ext_capacity already indicates the presence and size of the area). 3) Prohibit compressed files from using inline extents. On little-endian, the split maps to: offset +0: i_compr_blocks (original le64 low 32 bits) offset +4: i_inline_ext_capacity (original le64 high 32 bits) For compressed files i_inline_ext_capacity is always 0, so old fsck reading the full 64-bit i_compr_blocks gets the same value as the new 32-bit field. For non-compressed files i_compr_blocks is 0 regardless, so there is no conflict either. 4) Include the inline extent area size in i_extra_isize. i_extra_isize = base_extra_size + sizeof(struct f2fs_iext_header) + i_inline_ext_capacity * sizeof(struct f2fs_extent) Old kernels use i_extra_isize to skip the extra attribute region, so the inline extent area is simply invisible to them, it will not be misinterpreted as i_addr[] block addresses. 5) i_inline_ext_capacity is configurable at mkfs/tunefs time. When it is 0, no extra space is consumed beyond i_extra_end, so there is no impact on inodes that do not use inline extents. Please review this layout modification. Thanks Yongpeng, > >> >> Thanks, >> >>> create mode 100644 fs/f2fs/iextent.c >>> create mode 100644 fs/f2fs/iextent.h >>> >> >> >> >> _______________________________________________ >> 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 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel