mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 10:02:02 +02:00
ext4: zero out whole block for clean edges in WRITE_ZEROES
FALLOC_FL_WRITE_ZEROES requires that all blocks in the requested range
end up as written extents with zeroed content. For unaligned edges that
were already allocated, ext4_zero_partial_blocks() zeros them directly.
However, for unaligned edges whose underlying extent is a clean
unwritten extent or a hole, the extent type remains unwritten after
partial zeroing, which does not align with the semantics of
WRITE_ZEROES.
Therefore, when ext4_zero_partial_blocks() skips partial zeroing, it
indicates that the corresponding edges are clean unwritten extents or
holes. In this case, we need to expand the aligned allocation range
outward to cover such edges, so that ext4_alloc_file_blocks() can
correctly allocate blocks for the unaligned range. Edges that were
partial-zeroed (i.e., written or dirty) are left untouched.
Fixes: f4265b8d32 ("ext4: add FALLOC_FL_WRITE_ZEROES support")
Cc: stable@vger.kernel.org
Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260714080044.4038124-8-yi.zhang@huaweicloud.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
4c1f693139
commit
a5179156ac
|
|
@ -4760,6 +4760,21 @@ static long ext4_zero_range(struct file *file, loff_t offset,
|
|||
/* Zero range excluding the unaligned edges */
|
||||
align_start = round_up(offset, blocksize);
|
||||
align_end = round_down(end, blocksize);
|
||||
|
||||
/*
|
||||
* In WRITE_ZEROES mode, edges that were not partial-zeroed (clean
|
||||
* unwritten or hole) must be allocated and zeroed as whole blocks.
|
||||
* Expand the aligned range outward to cover them.
|
||||
*/
|
||||
if (mode & FALLOC_FL_WRITE_ZEROES) {
|
||||
if (!IS_ALIGNED(offset, blocksize) &&
|
||||
!(partial_zeroed & EXT4_PARTIAL_ZERO_START))
|
||||
align_start = round_down(offset, blocksize);
|
||||
if (!IS_ALIGNED(end, blocksize) &&
|
||||
!(partial_zeroed & EXT4_PARTIAL_ZERO_END))
|
||||
align_end = round_up(end, blocksize);
|
||||
}
|
||||
|
||||
if (align_end > align_start) {
|
||||
if (mode & FALLOC_FL_WRITE_ZEROES)
|
||||
flags = EXT4_GET_BLOCKS_CREATE_ZERO | EXT4_EX_NOCACHE;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user