summaryrefslogtreecommitdiff
path: root/scripts/Makefile.thinlto
diff options
context:
space:
mode:
authorDaejun Park <daejun7.park@samsung.com>2026-08-27 17:48:29 +0900
committerTheodore Ts'o <tytso@mit.edu>2026-10-08 11:06:22 -0400
commitaed43f47e1edeee1454eea86006a8c09480e5ed3 (patch)
tree7dd2fd10ce556d83d51fad34b37f58fe3726311f /scripts/Makefile.thinlto
parent418adcde99032194416248168df810535a1a93f9 (diff)
downloadlinux-aed43f47e1edeee1454eea86006a8c09480e5ed3.tar.gz
linux-aed43f47e1edeee1454eea86006a8c09480e5ed3.zip
ext4: don't report delalloc data as a hole on indirect-mapped inodes
When a plain lookup finds no block, ext4_ind_map_blocks() sizes the hole it reports by counting the empty subtrees under 'partial' in the on-disk indirect tree. That count knows nothing about delayed allocation, so a range holding delalloc data that has not been written back yet is reported as a plain hole. The extent-mapped path does not have this problem: it trims the hole it found at the first delayed extent before returning it. ext4_map_blocks() consults the extent status tree before it calls into the mapping layer, so a query that starts exactly on the delayed block still finds it. A query that starts earlier does not, because the hole reported for the earlier block already spans the delayed one. On a 4k-block filesystem, lseek(SEEK_DATA) from offset 0 on a file whose only data block is at logical block N and is still dirty returns: N = 0..11 direct blocks N << 12 N = 12 first single-indirect block N << 12 N = 13..1035 inside that indirect block -1 ENXIO N = 1036 first double-indirect block N << 12 Blocks 12 and 1036 survive because the query lands on the delayed block itself. Blocks 13..1035 are swallowed by the 1024-block hole reported for block 12. fiemap loses the same data for the same reason. An ext3 filesystem mounted as ext4 hits this during ordinary use: ext3 inodes stay indirect mapped, while mount -t ext4 turns on delayed allocation even though mounting ext3 with -o delalloc is explicitly rejected. install(1) from coreutils uses SEEK_DATA to locate data in its source file, so installing a sparse file that has not been written back silently produces a destination of the right size holding none of the data: truncate -s 1G img && mkfs.ext3 -F img && mount -t ext4 img mnt echo | dd of=mnt/src bs=1 count=1 seek=64K install mnt/src mnt/dst cmp mnt/src mnt/dst # differ: char 65537 Reconciling a hole with the extent status tree does not depend on how the hole was found, so instead of open coding it a second time, split the delalloc handling out of ext4_ext_determine_insert_hole() into ext4_determine_insert_hole(), which takes the hole the caller located, and call that from ext4_ind_map_blocks() as well. All the special cases and the comments explaining them stay in one place. Two things change for indirect-mapped inodes. They now cache the holes they report, as the extent-mapped path already does: ext4_punch_hole() already puts EXTENT_STATUS_HOLE on such inodes, ext4_map_blocks() and ext4_da_map_blocks() already handle a cached hole, the latter by replacing it with the delayed extent, and consecutive hole entries merge, so the tree does not grow with the length of a scan. And when a delayed extent covers the queried block itself - a race, since ext4_map_blocks() found nothing in the tree just before - the hole is now reported only up to the end of that extent instead of in full. The indirect path passes hole_start == lblk, so the "delalloc extent in front of the queried range" case cannot be reached there: __es_tree_search() never returns an extent ending before the block it was searched for. With this the sweep above returns N << 12 for every N, while the nodelalloc and extent-mapped controls are unchanged. generic/225, generic/285, generic/448 and generic/490 pass on ext4 made both with and without the extent feature. generic/286 and generic/436 pass on extent-mapped ext4 and are skipped without it, since they need fallocate. Fixes: facab4d9711e ("ext4: return hole from ext4_map_blocks()") Reported-by: Alexander Monakov <amonakov@ispras.ru> Closes: https://lore.kernel.org/linux-ext4/594c17d9-c00f-e485-96fb-cedf27ce3aa3@ispras.ru/ Suggested-by: Jan Kara <jack@suse.cz> Cc: stable@vger.kernel.org Signed-off-by: Daejun Park <daejun7.park@samsung.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Zhang Yi <yi.zhang@huawei.com> Link: https://patch.msgid.link/20260827084829epcms2p6ecc0c39a71d0c3eebf9cb1ade77314f6@epcms2p6 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions