From: Chi Zhiling This is a prep patch for shmem folio batching in the read path, where non-uptodate folios need to be handled in the main iteration loop. A large non-uptodate folio should be treated as a hole. Currently, holes larger than PAGE_SIZE cannot be handled because ZERO_PAGE is limited to a single page. Add copy_zero_to_iter() as a wrapper to support copying larger zero ranges to the iterator. Signed-off-by: Chi Zhiling --- mm/shmem.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/mm/shmem.c b/mm/shmem.c index 458853c506ea..96ea5a4c0aff 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3336,6 +3336,20 @@ shmem_write_end(const struct kiocb *iocb, struct address_space *mapping, return copied; } +static size_t copy_zero_to_iter(size_t bytes, struct iov_iter *i) +{ + struct folio *zero = largest_zero_folio(); + unsigned long nr, ret, written = 0; + + do { + nr = min(bytes - written, folio_size(zero)); + ret = copy_folio_to_iter(zero, 0, nr, i); + written += ret; + } while (written < bytes && ret == nr); + + return written; +} + static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; @@ -3430,7 +3444,7 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to) * clear_user() not so much, that it is noticeably * faster to copy the zero page instead of clearing. */ - ret = copy_page_to_iter(ZERO_PAGE(0), offset, nr, to); + ret = copy_zero_to_iter(nr, to); } else { /* * But submitting the same page twice in a row to -- 2.43.0