diff options
| author | Zhang Yi <yi.zhang@huawei.com> | 2026-10-09 18:30:18 +0800 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2026-10-15 10:53:13 -0400 |
| commit | 68738d77ce86cd4028e23ac2fbc45c56683bea7a (patch) | |
| tree | f0421c0fe843681ccc9b02f95eeddf5160161949 /scripts/Makefile.thinlto | |
| parent | e055578dc19256e44a774eb04a24c8d22465a698 (diff) | |
| download | linux-68738d77ce86cd4028e23ac2fbc45c56683bea7a.tar.gz linux-68738d77ce86cd4028e23ac2fbc45c56683bea7a.zip | |
ext4: implement partial block zero range path using iomap
Introduce a new iomap_ops instance, ext4_iomap_zero_ops, along with
ext4_block_iomap_zero_range() to implement block zeroing via the iomap
infrastructure for ext4.
ext4_block_iomap_zero_range() calls iomap_zero_range() with
ext4_iomap_zero_begin() as the callback. The callback locates the
range and populates the iomap mapping. If the range is mapped,
iomap_zero_iter() in the iomap core zeros the partial block
directly. If the range is an unwritten extent within EOF, the
callback collects a dirty folio batch via iomap_fill_dirty_folios()
so that iomap_zero_iter() can zero those folios directly, bypassing
a separate slow flush operation that would otherwise be needed to
convert the unwritten extent.
Note that ext4_iomap_zero_begin() can race with concurrent writeback:
after it queries an unwritten extent, writeback may convert it to
written and complete on the folio before iomap_fill_dirty_folios() scans
the range. The empty batch then makes iomap_zero_iter() skip zeroing,
leaving stale on-disk data.
zero_range writeback
---------------------- ----------------------
ext4_block_zero_range()
iomap_zero_range()
iomap_iter()
ext4_iomap_zero_begin()
ext4_iomap_map_blocks()
-> extent is UNWRITTEN
ext4_convert_unwritten_extents_endio()
-> extent is converted to WRITTEN
-> folio is clean
iomap_fill_dirty_folios()
filemap_get_folios_dirty()
-> folio is clean, not added to batch
ext4_set_iomap() -> IOMAP_UNWRITTEN
iomap_zero_iter()
__iomap_get_folio() -> NULL (empty batch)
iomap_iter_advance_full() <-- zeroing skipped
[later read returns stale on-disk data] <-- CORRUPTION
Therefore, we retry the extent lookup when iomap_fill_dirty_folios()
adds nothing and the i_es_seq cookie captured at the first lookup has
advanced, indicating the race actually occurred.
Other important constraints:
Zeroing out under an active journal handle can cause deadlock, as the
lock/handle ordering is inconsistent with the iomap writeback path.
Therefore, ext4_block_iomap_zero_range() must not be called under an
active handle. In addition, for post-EOF zeroing, the caller cannot
rely on data=ordered mode to persist the zeroed data before
i_disksize is updated.
Subsequent patches will address this by deferring i_disksize update
to i_size until after the zeroed data has been written back.
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Link: https://patch.msgid.link/20261009103033.2920530-18-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions
