]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
iomap: guard io_size EOF trim against concurrent truncate underflow
authorMorduan Zang <zhangdandan@uniontech.com>
Wed, 24 Jun 2026 06:26:22 +0000 (14:26 +0800)
committerChristian Brauner <brauner@kernel.org>
Wed, 1 Jul 2026 13:26:27 +0000 (15:26 +0200)
commit55ec50d046c03b3724741957f7b007856e36dbe7
tree98618f03cf56bc16fed23c3f382bbb680ceecc80
parent597a7bc7630035580e941a548cb646618c1c5933
iomap: guard io_size EOF trim against concurrent truncate underflow

iomap: fix zero padding data issue in concurrent append writes
changed ioend accounting so that io_size tracks only valid data
within EOF.  This trims io_size when a writeback range extends
past end_pos:

    ioend->io_size += map_len;
    if (ioend->io_offset + ioend->io_size > end_pos)
        ioend->io_size = end_pos - ioend->io_offset;

However, if end_pos ends up below ioend->io_offset, the subtraction
becomes negative and is stored in size_t io_size, causing an unsigned
wrap to a huge value.  This can happen when writeback continues past
byte-level EOF up to a block-aligned range, or when a concurrent
truncate shrinks the file after end_pos was sampled in
iomap_writeback_handle_eof().

A wrapped io_size can mislead append detection and corrupt
completion-time size handling, since filesystem end_io paths consume
io_size for decisions such as on-disk EOF updates and unwritten/COW
completion ranges.

Fix this by clamping io_size to zero when EOF has moved to or before
the ioend start offset.  This preserves the original intent of trimming
io_size to valid in-EOF data while avoiding the underflow.

Fixes: 51d20d1dacbe ("iomap: fix zero padding data issue in concurrent append writes")
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Morduan Zang <zhangdandan@uniontech.com>
Link: https://patch.msgid.link/9E38E2659B47DC2A+20260624062622.337469-1-zhangdandan@uniontech.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/iomap/ioend.c