From: Pankaj Raghav <p.raghav@xxxxxxxxxxx> Instead of looping with ZERO_PAGE, use a huge zero folio to zero pad the block. Fallback to ZERO_PAGE if mm_get_huge_zero_folio() fails. Suggested-by: Christoph Hellwig <hch@xxxxxx> Signed-off-by: Pankaj Raghav <p.raghav@xxxxxxxxxxx> --- I rebased on top of mm-unstable to get mm_get_huge_zero_folio(). @Christoph is this inline with what you had in mind? fs/iomap/direct-io.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index 5f481068de5b..7f584f9ff2c5 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -236,11 +236,18 @@ static void iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio, loff_t pos, unsigned len) { struct inode *inode = file_inode(dio->iocb->ki_filp); - struct page *page = ZERO_PAGE(0); + struct folio *zero_page_folio = page_folio(ZERO_PAGE(0)); + struct folio *folio = zero_page_folio; struct bio *bio; WARN_ON_ONCE(len > (BIO_MAX_VECS * PAGE_SIZE)); + if (len > PAGE_SIZE) { + folio = mm_get_huge_zero_folio(current->mm); + if (!folio) + folio = zero_page_folio; + } + bio = iomap_dio_alloc_bio(iter, dio, BIO_MAX_VECS, REQ_OP_WRITE | REQ_SYNC | REQ_IDLE); fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits, @@ -251,10 +258,10 @@ static void iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio, bio->bi_end_io = iomap_dio_bio_end_io; while (len) { - unsigned int io_len = min_t(unsigned int, len, PAGE_SIZE); + unsigned int size = min(len, folio_size(folio)); - __bio_add_page(bio, page, io_len, 0); - len -= io_len; + bio_add_folio_nofail(bio, folio, size, 0); + len -= size; } iomap_dio_submit_bio(iter, dio, bio, pos); } -- 2.34.1