Skip to content

Commit a298feb

Browse files
joannekoongbrauner
authored andcommitted
iomap: simplify when reads can be skipped for writes
Currently, the logic for skipping the read range for a write is if (!(iter->flags & IOMAP_UNSHARE) && (from <= poff || from >= poff + plen) && (to <= poff || to >= poff + plen)) which breaks down to skipping the read if any of these are true: a) from <= poff && to <= poff b) from <= poff && to >= poff + plen c) from >= poff + plen && to <= poff d) from >= poff + plen && to >= poff + plen This can be simplified to if (!(iter->flags & IOMAP_UNSHARE) && from <= poff && to >= poff + plen) from the following reasoning: a) from <= poff && to <= poff This reduces to 'to <= poff' since it is guaranteed that 'from <= to' (since to = from + len). It is not possible for 'from <= to' to be true here because we only reach here if plen > 0 (thanks to the preceding 'if (plen == 0)' check that would break us out of the loop). If 'to <= poff', plen would have to be 0 since poff and plen get adjusted in lockstep for uptodate blocks. This means we can eliminate this check. c) from >= poff + plen && to <= poff This is not possible since 'from <= to' and 'plen > 0'. We can eliminate this check. d) from >= poff + plen && to >= poff + plen This reduces to 'from >= poff + plen' since 'from <= to'. It is not possible for 'from >= poff + plen' to be true here. We only reach here if plen > 0 and for writes, poff and plen will always be block-aligned, which means poff <= from < poff + plen. We can eliminate this check. The only valid check is b) from <= poff && to >= poff + plen. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Link: https://patch.msgid.link/20251111193658.3495942-7-joannelkoong@gmail.com Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent f8eaf79 commit a298feb

1 file changed

Lines changed: 6 additions & 3 deletions

File tree

fs/iomap/buffered-io.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -758,9 +758,12 @@ static int __iomap_write_begin(const struct iomap_iter *iter,
758758
if (plen == 0)
759759
break;
760760

761-
if (!(iter->flags & IOMAP_UNSHARE) &&
762-
(from <= poff || from >= poff + plen) &&
763-
(to <= poff || to >= poff + plen))
761+
/*
762+
* If the read range will be entirely overwritten by the write,
763+
* we can skip having to zero/read it in.
764+
*/
765+
if (!(iter->flags & IOMAP_UNSHARE) && from <= poff &&
766+
to >= poff + plen)
764767
continue;
765768

766769
if (iomap_block_needs_zeroing(iter, block_start)) {

0 commit comments

Comments
 (0)