Skip to content

Commit 6016fc9

Browse files
committed
Merge tag 'iomap-6.6-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull iomap updates from Darrick Wong: "We've got some big changes for this release -- I'm very happy to be landing willy's work to enable large folios for the page cache for general read and write IOs when the fs can make contiguous space allocations, and Ritesh's work to track sub-folio dirty state to eliminate the write amplification problems inherent in using large folios. As a bonus, io_uring can now process write completions in the caller's context instead of bouncing through a workqueue, which should reduce io latency dramatically. IOWs, XFS should see a nice performance bump for both IO paths. Summary: - Make large writes to the page cache fill sparse parts of the cache with large folios, then use large memcpy calls for the large folio. - Track the per-block dirty state of each large folio so that a buffered write to a single byte on a large folio does not result in a (potentially) multi-megabyte writeback IO. - Allow some directio completions to be performed in the initiating task's context instead of punting through a workqueue. This will reduce latency for some io_uring requests" * tag 'iomap-6.6-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (26 commits) iomap: support IOCB_DIO_CALLER_COMP io_uring/rw: add write support for IOCB_DIO_CALLER_COMP fs: add IOCB flags related to passing back dio completions iomap: add IOMAP_DIO_INLINE_COMP iomap: only set iocb->private for polled bio iomap: treat a write through cache the same as FUA iomap: use an unsigned type for IOMAP_DIO_* defines iomap: cleanup up iomap_dio_bio_end_io() iomap: Add per-block dirty state tracking to improve performance iomap: Allocate ifs in ->write_begin() early iomap: Refactor iomap_write_delalloc_punch() function out iomap: Use iomap_punch_t typedef iomap: Fix possible overflow condition in iomap_write_delalloc_scan iomap: Add some uptodate state handling helpers for ifs state bitmap iomap: Drop ifs argument from iomap_set_range_uptodate() iomap: Rename iomap_page to iomap_folio_state and others iomap: Copy larger chunks from userspace iomap: Create large folios in the buffered write path filemap: Allow __filemap_get_folio to allocate large folios filemap: Add fgf_t typedef ...
2 parents dd2c019 + 377698d commit 6016fc9

File tree

19 files changed

+659
-281
lines changed

19 files changed

+659
-281
lines changed

Documentation/filesystems/locking.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,17 @@ invalidate_lock before invalidating page cache in truncate / hole punch
376376
path (and thus calling into ->invalidate_folio) to block races between page
377377
cache invalidation and page cache filling functions (fault, read, ...).
378378

379-
->release_folio() is called when the kernel is about to try to drop the
380-
buffers from the folio in preparation for freeing it. It returns false to
381-
indicate that the buffers are (or may be) freeable. If ->release_folio is
382-
NULL, the kernel assumes that the fs has no private interest in the buffers.
379+
->release_folio() is called when the MM wants to make a change to the
380+
folio that would invalidate the filesystem's private data. For example,
381+
it may be about to be removed from the address_space or split. The folio
382+
is locked and not under writeback. It may be dirty. The gfp parameter
383+
is not usually used for allocation, but rather to indicate what the
384+
filesystem may do to attempt to free the private data. The filesystem may
385+
return false to indicate that the folio's private data cannot be freed.
386+
If it returns true, it should have already removed the private data from
387+
the folio. If a filesystem does not provide a ->release_folio method,
388+
the pagecache will assume that private data is buffer_heads and call
389+
try_to_free_buffers().
383390

384391
->free_folio() is called when the kernel has dropped the folio
385392
from the page cache.

fs/btrfs/file.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,9 @@ static int prepare_uptodate_page(struct inode *inode,
876876
return 0;
877877
}
878878

879-
static unsigned int get_prepare_fgp_flags(bool nowait)
879+
static fgf_t get_prepare_fgp_flags(bool nowait)
880880
{
881-
unsigned int fgp_flags = FGP_LOCK | FGP_ACCESSED | FGP_CREAT;
881+
fgf_t fgp_flags = FGP_LOCK | FGP_ACCESSED | FGP_CREAT;
882882

883883
if (nowait)
884884
fgp_flags |= FGP_NOWAIT;
@@ -910,7 +910,7 @@ static noinline int prepare_pages(struct inode *inode, struct page **pages,
910910
int i;
911911
unsigned long index = pos >> PAGE_SHIFT;
912912
gfp_t mask = get_prepare_gfp_flags(inode, nowait);
913-
unsigned int fgp_flags = get_prepare_fgp_flags(nowait);
913+
fgf_t fgp_flags = get_prepare_fgp_flags(nowait);
914914
int err = 0;
915915
int faili;
916916

fs/f2fs/compress.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ static int prepare_compress_overwrite(struct compress_ctx *cc,
10451045
struct address_space *mapping = cc->inode->i_mapping;
10461046
struct page *page;
10471047
sector_t last_block_in_bio;
1048-
unsigned fgp_flag = FGP_LOCK | FGP_WRITE | FGP_CREAT;
1048+
fgf_t fgp_flag = FGP_LOCK | FGP_WRITE | FGP_CREAT;
10491049
pgoff_t start_idx = start_idx_of_cluster(cc);
10501050
int i, ret;
10511051

fs/f2fs/f2fs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2736,7 +2736,7 @@ static inline struct page *f2fs_grab_cache_page(struct address_space *mapping,
27362736

27372737
static inline struct page *f2fs_pagecache_get_page(
27382738
struct address_space *mapping, pgoff_t index,
2739-
int fgp_flags, gfp_t gfp_mask)
2739+
fgf_t fgp_flags, gfp_t gfp_mask)
27402740
{
27412741
if (time_to_inject(F2FS_M_SB(mapping), FAULT_PAGE_GET))
27422742
return NULL;

fs/gfs2/aops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ static const struct address_space_operations gfs2_aops = {
747747
.writepages = gfs2_writepages,
748748
.read_folio = gfs2_read_folio,
749749
.readahead = gfs2_readahead,
750-
.dirty_folio = filemap_dirty_folio,
750+
.dirty_folio = iomap_dirty_folio,
751751
.release_folio = iomap_release_folio,
752752
.invalidate_folio = iomap_invalidate_folio,
753753
.bmap = gfs2_bmap,

fs/gfs2/bmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ gfs2_iomap_get_folio(struct iomap_iter *iter, loff_t pos, unsigned len)
971971
if (status)
972972
return ERR_PTR(status);
973973

974-
folio = iomap_get_folio(iter, pos);
974+
folio = iomap_get_folio(iter, pos, len);
975975
if (IS_ERR(folio))
976976
gfs2_trans_end(sdp);
977977
return folio;

0 commit comments

Comments
 (0)