Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iomap: use largest_zero_folio() in iomap_dio_zero()

iomap_dio_zero() uses a custom allocated memory of zeroes for padding
zeroes. This was a temporary solution until there was a way to request a
zero folio that was greater than the PAGE_SIZE.

Use largest_zero_folio() function instead of using the custom allocated
memory of zeroes. There is no guarantee from largest_zero_folio()
function that it will always return a PMD sized folio. Adapt the code so
that it can also work if largest_zero_folio() returns a ZERO_PAGE.

Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Pankaj Raghav and committed by
Christian Brauner
10436adf b2c43efc

+15 -23
+15 -23
fs/iomap/direct-io.c
··· 24 24 #define IOMAP_DIO_WRITE (1U << 30) 25 25 #define IOMAP_DIO_DIRTY (1U << 31) 26 26 27 - /* 28 - * Used for sub block zeroing in iomap_dio_zero() 29 - */ 30 - #define IOMAP_ZERO_PAGE_SIZE (SZ_64K) 31 - #define IOMAP_ZERO_PAGE_ORDER (get_order(IOMAP_ZERO_PAGE_SIZE)) 32 - static struct page *zero_page; 33 - 34 27 struct iomap_dio { 35 28 struct kiocb *iocb; 36 29 const struct iomap_dio_ops *dops; ··· 278 285 { 279 286 struct inode *inode = file_inode(dio->iocb->ki_filp); 280 287 struct bio *bio; 288 + struct folio *zero_folio = largest_zero_folio(); 289 + int nr_vecs = max(1, i_blocksize(inode) / folio_size(zero_folio)); 281 290 282 291 if (!len) 283 292 return 0; 293 + 284 294 /* 285 - * Max block size supported is 64k 295 + * This limit shall never be reached as most filesystems have a 296 + * maximum blocksize of 64k. 286 297 */ 287 - if (WARN_ON_ONCE(len > IOMAP_ZERO_PAGE_SIZE)) 298 + if (WARN_ON_ONCE(nr_vecs > BIO_MAX_VECS)) 288 299 return -EINVAL; 289 300 290 - bio = iomap_dio_alloc_bio(iter, dio, 1, REQ_OP_WRITE | REQ_SYNC | REQ_IDLE); 301 + bio = iomap_dio_alloc_bio(iter, dio, nr_vecs, 302 + REQ_OP_WRITE | REQ_SYNC | REQ_IDLE); 291 303 fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits, 292 304 GFP_KERNEL); 293 305 bio->bi_iter.bi_sector = iomap_sector(&iter->iomap, pos); 294 306 bio->bi_private = dio; 295 307 bio->bi_end_io = iomap_dio_bio_end_io; 296 308 297 - __bio_add_page(bio, zero_page, len, 0); 309 + while (len > 0) { 310 + unsigned int io_len = min(len, folio_size(zero_folio)); 311 + 312 + bio_add_folio_nofail(bio, zero_folio, io_len, 0); 313 + len -= io_len; 314 + } 298 315 iomap_dio_submit_bio(iter, dio, bio, pos); 316 + 299 317 return 0; 300 318 } 301 319 ··· 829 825 return iomap_dio_complete(dio); 830 826 } 831 827 EXPORT_SYMBOL_GPL(iomap_dio_rw); 832 - 833 - static int __init iomap_dio_init(void) 834 - { 835 - zero_page = alloc_pages(GFP_KERNEL | __GFP_ZERO, 836 - IOMAP_ZERO_PAGE_ORDER); 837 - 838 - if (!zero_page) 839 - return -ENOMEM; 840 - 841 - return 0; 842 - } 843 - fs_initcall(iomap_dio_init);