Skip to content

Commit 419e9c3

Browse files
jankaradjwong
authored andcommitted
iomap: Fix pipe page leakage during splicing
When splicing using iomap_dio_rw() to a pipe, we may leak pipe pages because bio_iov_iter_get_pages() records that the pipe will have full extent worth of data however if file size is not block size aligned iomap_dio_rw() returns less than what bio_iov_iter_get_pages() set up and splice code gets confused leaking a pipe page with the file tail. Handle the situation similarly to the old direct IO implementation and revert iter to actually returned read amount which makes iter consistent with value returned from iomap_dio_rw() and thus the splice code is happy. Fixes: ff6a929 ("iomap: implement direct I/O") CC: [email protected] Reported-by: [email protected] Signed-off-by: Jan Kara <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 6334b91 commit 419e9c3

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

fs/iomap/direct-io.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,15 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
502502
}
503503
pos += ret;
504504

505-
if (iov_iter_rw(iter) == READ && pos >= dio->i_size)
505+
if (iov_iter_rw(iter) == READ && pos >= dio->i_size) {
506+
/*
507+
* We only report that we've read data up to i_size.
508+
* Revert iter to a state corresponding to that as
509+
* some callers (such as splice code) rely on it.
510+
*/
511+
iov_iter_revert(iter, pos - dio->i_size);
506512
break;
513+
}
507514
} while ((count = iov_iter_count(iter)) > 0);
508515
blk_finish_plug(&plug);
509516

0 commit comments

Comments
 (0)