diff options
| author | Tal Zussman <tz2294@columbia.edu> | 2026-09-07 11:18:38 -0400 |
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2026-09-08 11:17:46 +0200 |
| commit | 12255a04ec331a9da0bf049ed48c92af57dfafae (patch) | |
| tree | 54d527129481e1918c1d0f7bbe1175addf1e4579 | |
| parent | 43de050fa4a31f7e7a73cf8974dcf6037e161a39 (diff) | |
| download | linux-next-12255a04ec331a9da0bf049ed48c92af57dfafae.tar.gz linux-next-12255a04ec331a9da0bf049ed48c92af57dfafae.zip | |
isofs: convert the zisofs read path to use folios
Store folios in the array that zisofs_read_folio() passes to
zisofs_fill_pages() and zisofs_uncompress_block(), use the folio APIs on
them, and grab the folios with __filemap_get_folio() instead of
grab_cache_page_nowait(). This removes six compound_head() calls, from
page_offset(), the three SetPageUptodate() calls, unlock_page() and
put_page(), and the last struct page usage in isofs.
isofs only uses order-0 folios, so folio_size() is PAGE_SIZE and the
logic is unchanged.
grab_cache_page_nowait() passed FGP_NOFS as well, but FGP_NOWAIT already
prevents reclaim entirely, so leave it out, as FGP_NOFS is on its way
out [1].
Change poffset to be unsigned int rather than just unsigned while at
it.
[1] https://lore.kernel.org/linux-mm/20260830041901.2668-9-willy@infradead.org/
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Link: https://patch.msgid.link/20260907-isofs-zisofs-folio-v2-1-c2e430abfcbc@columbia.edu
Signed-off-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/isofs/compress.c | 77 |
1 files changed, 43 insertions, 34 deletions
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c index f9869d62b850..2d23abaeb874 100644 --- a/fs/isofs/compress.c +++ b/fs/isofs/compress.c @@ -39,7 +39,7 @@ static DEFINE_MUTEX(zisofs_zlib_lock); */ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start, loff_t block_end, int pcount, - struct page **pages, unsigned poffset, + struct folio **folios, unsigned int poffset, int *errp) { unsigned int zisofs_block_shift = ISOFS_I(inode)->i_format_parm[1]; @@ -66,11 +66,12 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start, if (block_size == 0) { for ( i = 0 ; i < pcount ; i++ ) { unsigned int off = i ? 0 : poffset; + struct folio *folio = folios[i]; - if (!pages[i]) + if (!folio) continue; - memzero_page(pages[i], off, PAGE_SIZE - off); - SetPageUptodate(pages[i]); + folio_zero_range(folio, off, folio_size(folio) - off); + folio_mark_uptodate(folio); } return (((loff_t)pcount) << PAGE_SHIFT) - poffset; } @@ -119,11 +120,12 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start, while (curpage < pcount && curbh < haveblocks && zerr != Z_STREAM_END) { + struct folio *folio = folios[curpage]; + if (!stream.avail_out) { - if (pages[curpage]) { - stream.next_out = kmap_local_page(pages[curpage]) - + poffset; - stream.avail_out = PAGE_SIZE - poffset; + if (folio) { + stream.next_out = kmap_local_folio(folio, poffset); + stream.avail_out = folio_size(folio) - poffset; poffset = 0; } else { stream.next_out = (void *)&zisofs_sink_page; @@ -173,9 +175,9 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start, if (!stream.avail_out) { /* This page completed */ - if (pages[curpage]) { - flush_dcache_page(pages[curpage]); - SetPageUptodate(pages[curpage]); + if (folio) { + flush_dcache_folio(folio); + folio_mark_uptodate(folio); } if (stream.next_out != (unsigned char *)zisofs_sink_page) { kunmap_local(stream.next_out); @@ -206,7 +208,7 @@ b_eio: * fills in other pages if we have data for them. */ static int zisofs_fill_pages(struct inode *inode, int full_page, int pcount, - struct page **pages) + struct folio **folios) { loff_t start_off, end_off; loff_t block_start, block_end; @@ -221,14 +223,14 @@ static int zisofs_fill_pages(struct inode *inode, int full_page, int pcount, int err; loff_t ret; - BUG_ON(!pages[full_page]); + BUG_ON(!folios[full_page]); /* * We want to read at least 'full_page' page. Because we have to * uncompress the whole compression block anyway, fill the surrounding * pages with the data we have anyway... */ - start_off = page_offset(pages[full_page]); + start_off = folio_pos(folios[full_page]); end_off = min_t(loff_t, start_off + PAGE_SIZE, inode->i_size); cstart_block = start_off >> zisofs_block_shift; @@ -267,9 +269,9 @@ static int zisofs_fill_pages(struct inode *inode, int full_page, int pcount, } err = 0; ret = zisofs_uncompress_block(inode, block_start, block_end, - pcount, pages, poffset, &err); + pcount, folios, poffset, &err); poffset += ret; - pages += poffset >> PAGE_SHIFT; + folios += poffset >> PAGE_SHIFT; pcount -= poffset >> PAGE_SHIFT; full_page -= poffset >> PAGE_SHIFT; poffset &= ~PAGE_MASK; @@ -289,9 +291,11 @@ static int zisofs_fill_pages(struct inode *inode, int full_page, int pcount, cstart_block++; } - if (poffset && *pages) { - memzero_page(*pages, poffset, PAGE_SIZE - poffset); - SetPageUptodate(*pages); + if (poffset && *folios) { + struct folio *folio = *folios; + + folio_zero_range(folio, poffset, folio_size(folio) - poffset); + folio_mark_uptodate(folio); } brelse(bh); return 0; @@ -312,7 +316,7 @@ static int zisofs_read_folio(struct file *file, struct folio *folio) unsigned int zisofs_pages_per_cblock = PAGE_SHIFT <= zisofs_block_shift ? (1 << (zisofs_block_shift - PAGE_SHIFT)) : 0; - struct page **pages; + struct folio **folios; pgoff_t index = folio->index, end_index; end_index = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT; @@ -336,33 +340,38 @@ static int zisofs_read_folio(struct file *file, struct folio *folio) full_page = 0; pcount = 1; } - pages = kzalloc_objs(*pages, - max_t(unsigned int, zisofs_pages_per_cblock, 1)); - if (!pages) { + folios = kzalloc_objs(*folios, + max_t(unsigned int, zisofs_pages_per_cblock, 1)); + if (!folios) { folio_unlock(folio); return -ENOMEM; } - pages[full_page] = &folio->page; + folios[full_page] = folio; for (i = 0; i < pcount; i++, index++) { - if (i != full_page) - pages[i] = grab_cache_page_nowait(mapping, index); + if (i == full_page) + continue; + folios[i] = __filemap_get_folio(mapping, index, + FGP_LOCK | FGP_CREAT | FGP_NOWAIT, + mapping_gfp_mask(mapping)); + if (IS_ERR(folios[i])) + folios[i] = NULL; } - err = zisofs_fill_pages(inode, full_page, pcount, pages); + err = zisofs_fill_pages(inode, full_page, pcount, folios); - /* Release any residual pages, do not SetPageUptodate */ + /* Release any residual folios, do not mark them uptodate */ for (i = 0; i < pcount; i++) { - if (pages[i]) { - flush_dcache_page(pages[i]); - unlock_page(pages[i]); + if (folios[i]) { + flush_dcache_folio(folios[i]); + folio_unlock(folios[i]); if (i != full_page) - put_page(pages[i]); + folio_put(folios[i]); } - } + } /* At this point, err contains 0 or -EIO depending on the "critical" page */ - kfree(pages); + kfree(folios); return err; } |
