Skip to content

[Deepin-Kernel-SIG] [linux 6.18.y] [Upstream] fuse: use iomap for buffered reads + readahead#1851

Open
opsiff wants to merge 16 commits into
deepin-community:linux-6.18.yfrom
opsiff:linux-6.18.y-2026-06-12-iomap
Open

[Deepin-Kernel-SIG] [linux 6.18.y] [Upstream] fuse: use iomap for buffered reads + readahead#1851
opsiff wants to merge 16 commits into
deepin-community:linux-6.18.yfrom
opsiff:linux-6.18.y-2026-06-12-iomap

Conversation

@opsiff

@opsiff opsiff commented Jun 12, 2026

Copy link
Copy Markdown
Member

Link: https://lore.kernel.org/all/20250926002609.1302233-1-joannelkoong@gmail.com/

This series adds fuse iomap support for buffered reads and readahead.
This is needed so that granular uptodate tracking can be used in fuse when
large folios are enabled so that only the non-uptodate portions of the folio
need to be read in instead of having to read in the entire folio. It also is
needed in order to turn on large folios for servers that use the writeback
cache since otherwise there is a race condition that may lead to data
corruption if there is a partial write, then a read and the read happens
before the write has undergone writeback, since otherwise the folio will not
be marked uptodate from the partial write so the read will read in the entire
folio from disk, which will overwrite the partial write.

This is on top of two locally-patched iomap patches [1] [2] patched on top of
commit f1c864be6e88 ("Merge branch 'vfs-6.18.async' into vfs.all") in
Christian's vfs.all tree.

This series was run through fstests on fuse passthrough_hp with an
out-of kernel patch enabling fuse large folios.

This patchset does not enable large folios on fuse yet. That will be part
of a different patchset.

Thanks,
Joanne

[1] https://lore.kernel.org/linux-fsdevel/20250919214250.4144807-1-joannelkoong@gmail.com/
[2] https://lore.kernel.org/linux-fsdevel/20250922180042.1775241-1-joannelkoong@gmail.com/

Changelog

v4:
https://lore.kernel.org/linux-fsdevel/20250923002353.2961514-1-joannelkoong@gmail.com/
v4 -> v5:

  • Add commit for tracking pending read bytes more optimally (patch 7), which
    was suggested by Darrick and improves both the performance and the interface
  • Merged "track read/readahead folio ownership internally" patch into patch 7
  • Split iomap iter pos change into its own commit (Darrick) (patch 8)

v3:
https://lore.kernel.org/linux-fsdevel/20250916234425.1274735-1-joannelkoong@gmail.com/
v3 -> v4:

  • Rebase this on top of patches [1] and [2]
  • Fix readahead logic back to checking offset == 0 (patch 4)
  • Bias needs to be before/after iomap_iter() (patch 10)
  • Rename cur_folio_owned to folio_owned for read_folio (patch 7) (Darrick)

v2:
https://lore.kernel.org/linux-fsdevel/20250908185122.3199171-1-joannelkoong@gmail.com/
v2 -> v3:

  • Incorporate Christoph's feedback
  • Change naming to iomap_bio_* instead of iomap_xxx_bio
  • Take his patch for moving bio logic into its own file (patch 11)
  • Make ->read_folio_range interface not need pos arg (patch 9)
  • Make ->submit_read return void (patch 9)
  • Merge cur_folio_in_bio rename w/ tracking folio_owned internally (patch 7)
  • Drop patch propagating error and replace with void return (patch 12)
  • Make bias code better to read (patch 10)
  • Add WARN_ON_ONCE check in iteration refactoring (patch 4)
  • Rename ->read_submit to ->submit_read (patch 9)

v1:
https://lore.kernel.org/linux-fsdevel/20250829235627.4053234-1-joannelkoong@gmail.com/
v1 -> v2:

  • Don't pass in caller-provided arg through iter->private, pass it through
    ctx->private instead (Darrick & Christoph)
  • Separate 'bias' for ifs->read_bytes_pending into separate patch (Christoph)
  • Rework read/readahead interface to take in struct iomap_read_folio_ctx
    (Christoph)
  • Add patch for removing fuse fc->blkbits workaround, now that Miklos's tree
    has been merged into Christian's

Joanne Koong (14):
iomap: move bio read logic into helper function
iomap: move read/readahead bio submission logic into helper function
iomap: store read/readahead bio generically
iomap: iterate over folio mapping in iomap_readpage_iter()
iomap: rename iomap_readpage_iter() to iomap_read_folio_iter()
iomap: rename iomap_readpage_ctx struct to iomap_read_folio_ctx
iomap: track pending read bytes more optimally
iomap: set accurate iter->pos when reading folio ranges
iomap: add caller-provided callbacks for read and readahead
iomap: move buffered io bio logic into new file
iomap: make iomap_read_folio() a void return
fuse: use iomap for read_folio
fuse: use iomap for readahead
fuse: remove fc->blkbits workaround for partial writes

.../filesystems/iomap/operations.rst | 44 +++
block/fops.c | 5 +-
fs/erofs/data.c | 5 +-
fs/fuse/dir.c | 2 +-
fs/fuse/file.c | 288 +++++++++++-------
fs/fuse/fuse_i.h | 8 -
fs/fuse/inode.c | 13 +-
fs/gfs2/aops.c | 6 +-
fs/iomap/Makefile | 3 +-
fs/iomap/bio.c | 88 ++++++
fs/iomap/buffered-io.c | 246 +++++++--------
fs/iomap/internal.h | 12 +
fs/xfs/xfs_aops.c | 5 +-
fs/zonefs/file.c | 5 +-
include/linux/iomap.h | 63 +++-
15 files changed, 505 insertions(+), 288 deletions(-)
create mode 100644 fs/iomap/bio.c

--
2.47.3

Summary by Sourcery

Adopt iomap-based buffered read and readahead for FUSE and refactor iomap buffered read paths to support granular folio uptodate tracking while removing the legacy FUSE blkbits workaround.

New Features:

  • Introduce pluggable iomap read operations and context structures to support filesystem-specific buffered read and readahead implementations, including async issuance.
  • Add a shared iomap bio helper module that encapsulates block-based buffered read submission for multiple filesystems.
  • Enable FUSE to use iomap for buffered reads and readahead, including asynchronous batched reads via fuse_io_args.

Enhancements:

  • Refine iomap folio read tracking to account pending read bytes more efficiently and finish folio reads per-range via a new helper.
  • Simplify iomap iterator advancement by changing iomap_iter_advance to take a raw count and updating all callers accordingly.
  • Adjust existing filesystems using iomap (block devices, XFS, EROFS, GFS2, zonefs, DAX) to use the new bio-based read helpers without changing external behaviour.
  • Remove the FUSE-specific blkbits workaround by deriving block size from the superblock and simplifying attribute handling.

opsiff and others added 16 commits June 12, 2026 10:57
This reverts commit 01f84e4.
This is a partial work of the next commit series,
revert it and merge whole series.

Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Most callers of iomap_iter_advance() do not need the remaining length
returned. Get rid of the extra iomap_length() call that
iomap_iter_advance() does.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit ca82a7e)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Move the iomap_readpage_iter() bio read logic into a separate helper
function, iomap_bio_read_folio_range(). This is needed to make iomap
read/readahead more generically usable, especially for filesystems that
do not require CONFIG_BLOCK.

Additionally rename buffered write's iomap_read_folio_range() function
to iomap_bio_read_folio_range_sync() to better describe its synchronous
behavior.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 573c14c)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Move the read/readahead bio submission logic into a separate helper.
This is needed to make iomap read/readahead more generically usable,
especially for filesystems that do not require CONFIG_BLOCK.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 7588469)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Store the iomap_readpage_ctx bio generically as a "void *read_ctx".
This makes the read/readahead interface more generic, which allows it to
be used by filesystems that may not be block-based and may not have
CONFIG_BLOCK set.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit d1f9893)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Iterate over all non-uptodate ranges of a folio mapping in a single call
to iomap_readpage_iter() instead of leaving the partial iteration to the
caller.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit e0e1534)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

->readpage was deprecated and reads are now on folios.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 8805a9c)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

->readpage was deprecated and reads are now on folios.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 87a1381)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Instead of incrementing read_bytes_pending for every folio range read in
(which requires acquiring the spinlock to do so), set read_bytes_pending
to the folio size when the first range is asynchronously read in, keep
track of how many bytes total are asynchronously read in, and adjust
read_bytes_pending accordingly after issuing requests to read in all the
necessary ranges.

iomap_read_folio_ctx->cur_folio_in_bio can be removed since a non-zero
value for pending bytes necessarily indicates the folio is in the bio.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Suggested-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit d43558a)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Advance iter to the correct position before calling an IO helper to read
in a folio range. This allows the helper to reliably use iter->pos to
determine the starting offset for reading.

This will simplify the interface for reading in folio ranges when iomap
read/readahead supports caller-provided callbacks.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit fb7a10a)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Add caller-provided callbacks for read and readahead so that it can be
used generically, especially by filesystems that are not block-based.

In particular, this:
* Modifies the read and readahead interface to take in a
  struct iomap_read_folio_ctx that is publicly defined as:

  struct iomap_read_folio_ctx {
	const struct iomap_read_ops *ops;
	struct folio *cur_folio;
	struct readahead_control *rac;
	void *read_ctx;
  };

  where struct iomap_read_ops is defined as:

  struct iomap_read_ops {
      int (*read_folio_range)(const struct iomap_iter *iter,
                             struct iomap_read_folio_ctx *ctx,
                             size_t len);
      void (*read_submit)(struct iomap_read_folio_ctx *ctx);
  };

  read_folio_range() reads in the folio range and is required by the
  caller to provide. read_submit() is optional and is used for
  submitting any pending read requests.

* Modifies existing filesystems that use iomap for read and readahead to
  use the new API, through the new statically inlined helpers
  iomap_bio_read_folio() and iomap_bio_readahead(). There is no change
  in functionality for those filesystems.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit b2f35ac)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Move bio logic in the buffered io code into its own file and remove
CONFIG_BLOCK gating for iomap read/readahead.

[1] https://lore.kernel.org/linux-fsdevel/aMK2GuumUf93ep99@infradead.org/

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit c2b1adc)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

No errors are propagated in iomap_read_folio(). Change
iomap_read_folio() to a void return to make this clearer to callers.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit d4e88bb)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Read folio data into the page cache using iomap. This gives us granular
uptodate tracking for large folios, which optimizes how much data needs
to be read in. If some portions of the folio are already uptodate (eg
through a prior write), we only need to read in the non-uptodate
portions.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 03e9618)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Do readahead in fuse using iomap. This gives us granular uptodate
tracking for large folios, which optimizes how much data needs to be
read in. If some portions of the folio are already uptodate (eg through
a prior write), we only need to read in the non-uptodate portions.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 4ea9071)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
mainline inclusion
from mainline-v6.19-rc1
category: feature

Now that fuse is integrated with iomap for read/readahead, we can remove
the workaround that was added in commit bd24d21 ("fuse: fix fuseblk
i_blkbits for iomap partial writes"), which was previously needed to
avoid a race condition where an iomap partial write may be overwritten
by a read if blocksize < PAGE_SIZE. Now that fuse does iomap
read/readahead, this is protected against since there is granular
uptodate tracking of blocks, which means this workaround can be removed.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 93570c6)
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
@sourcery-ai

sourcery-ai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors iomap buffered read infrastructure to support pluggable read backends and granular uptodate tracking, then ports FUSE buffered reads and readahead to iomap (removing the blkbits workaround) while updating existing iomap users to the new interfaces.

Sequence diagram for FUSE readahead using iomap

sequenceDiagram
    actor Kernel_readahead
    participant fuse_readahead
    participant iomap_readahead
    participant iomap_read_folio_iter
    participant fuse_iomap_read_folio_range_async
    participant fuse_handle_readahead
    participant fuse_send_readpages

    Kernel_readahead ->> fuse_readahead: fuse_readahead(rac)
    activate fuse_readahead
    fuse_readahead ->> iomap_readahead: iomap_readahead(&fuse_iomap_ops, &ctx)
    deactivate fuse_readahead
    activate iomap_readahead
    loop over folios
        iomap_readahead ->> iomap_read_folio_iter: iomap_read_folio_iter(iter, ctx, &cur_bytes_pending)
        activate iomap_read_folio_iter
        iomap_read_folio_iter ->> fuse_iomap_read_folio_range_async: read_folio_range(iter, ctx, len)
        activate fuse_iomap_read_folio_range_async
        fuse_iomap_read_folio_range_async ->> fuse_handle_readahead: fuse_handle_readahead(folio, rac, data, pos, len)
        activate fuse_handle_readahead
        alt need_to_send
            fuse_handle_readahead ->> fuse_send_readpages: fuse_send_readpages(ia, file, nr_bytes, async)
        end
        deactivate fuse_handle_readahead
        fuse_iomap_read_folio_range_async -->> iomap_read_folio_iter: ret
        deactivate fuse_iomap_read_folio_range_async
        iomap_read_folio_iter -->> iomap_readahead: iter.status
        deactivate iomap_read_folio_iter
    end
    iomap_readahead ->> fuse_iomap_read_submit: submit_read(ctx)
    deactivate iomap_readahead
    note over fuse_send_readpages: On reply, fuse_readpages_end() calls
    note over fuse_send_readpages: iomap_finish_folio_read(..., err)
Loading

File-Level Changes

Change Details Files
Introduce pluggable iomap buffered read backend with generic read_folio/readahead context and new iomap_read_ops.
  • Refactor buffered-io read paths to use iomap_read_folio_ctx carrying current folio, readahead control, and backend-specific context.
  • Add iomap_read_ops callbacks (read_folio_range/submit_read) and wire them into iomap_read_folio and iomap_readahead, replacing the old bio-specific logic.
  • Export iomap_finish_folio_read and add iomap_read_init/iomap_read_end to track read_bytes_pending with a biased accounting scheme for large folios.
  • Tighten iomap_iter_advance semantics to take a concrete length instead of in/out parameter and update all call sites accordingly.
fs/iomap/buffered-io.c
include/linux/iomap.h
fs/iomap/iter.c
fs/dax.c
fs/iomap/direct-io.c
fs/iomap/seek.c
Factor out iomap bio-based read helper backend and convert existing block filesystems to it.
  • Create fs/iomap/bio.c implementing iomap_bio_read_ops, bio submission helper, and a synchronous bio read fallback function.
  • Expose inline helpers iomap_bio_read_folio and iomap_bio_readahead for block-based iomap users.
  • Switch gfs2, erofs, xfs, zonefs, and the default block aops to use the new iomap_bio_* helpers for read_folio and readahead.
fs/iomap/bio.c
fs/iomap/Makefile
include/linux/iomap.h
fs/gfs2/aops.c
fs/erofs/data.c
fs/xfs/xfs_aops.c
fs/zonefs/file.c
block/fops.c
Port FUSE buffered read_folio and readahead to iomap and unify folio batching logic for reads and writeback.
  • Implement fuse_iomap_read_ops with async readahead batching that leverages existing fuse_io_args, and synchronous per-folio reads for non-readahead paths.
  • Rework fuse_read_folio to use iomap_read_folio via a small iomap_begin implementation, including early error handling and atime invalidation.
  • Replace custom fuse_readahead loop with iomap_readahead using a fuse-specific read_ctx, reusing fuse_folios_need_send for read batching thresholds.
  • Generalize fuse_writepage_need_send into fuse_folios_need_send with a direction flag and reuse it for both writeback and read batching; adjust writeback to handle pages array growth explicitly.
  • Update fuse_readpages_end to finish folio reads with iomap_finish_folio_read using the recorded offsets/lengths.
fs/fuse/file.c
Remove FUSE blkbits workaround and rely on superblock blocksize for stat and attribute handling.
  • Drop fc->blkbits from fuse_conn and its usage in attribute fill paths.
  • Make fuse_change_attributes_common cache blkbits from attr->blksize or from the superblock's s_blocksize_bits instead of fuse_conn.
  • Stop overriding the superblock blocksize to PAGE_SIZE for writeback-cache safety; rely on iomap-based reads instead.
  • Adjust fuse_fillattr to derive stat->blksize from inode->i_sb->s_blocksize_bits.
fs/fuse/inode.c
fs/fuse/dir.c
fs/fuse/fuse_i.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="fs/iomap/buffered-io.c" line_range="580-589" />
<code_context>
  * the filesystem to be reentered.
  */
-void iomap_readahead(struct readahead_control *rac, const struct iomap_ops *ops)
+void iomap_readahead(const struct iomap_ops *ops,
+		struct iomap_read_folio_ctx *ctx)
 {
+	struct readahead_control *rac = ctx->rac;
 	struct iomap_iter iter = {
 		.inode	= rac->mapping->host,
 		.pos	= readahead_pos(rac),
 		.len	= readahead_length(rac),
 	};
-	struct iomap_readpage_ctx ctx = {
-		.rac	= rac,
-	};
+	size_t cur_bytes_pending;

 	trace_iomap_readahead(rac->mapping->host, readahead_count(rac));

 	while (iomap_iter(&iter, ops) > 0)
-		iter.status = iomap_readahead_iter(&iter, &ctx);
-
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Initialize cur_bytes_pending before first use to avoid relying on control-flow for correctness.

cur_bytes_pending is declared but never initialized before being passed by reference into iomap_readahead_iter. This currently works only because iomap_readahead_iter sets it before use and relies on ctx->cur_folio being NULL. Initializing cur_bytes_pending to 0 here would remove that control-flow dependency and make the code safer against future changes.
</issue_to_address>

### Comment 2
<location path="Documentation/filesystems/iomap/operations.rst" line_range="225-227" />
<code_context>
+``iomap_read_folio`` must set:
+ * ``ops->read_folio_range()`` and ``cur_folio``
+
+``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
+pass in any custom data the caller needs accessible in the ops callbacks for
+fulfilling reads.
+
 Buffered Writes
</code_context>
<issue_to_address>
**nitpick (typo):** Slight grammar improvement around "needs accessible".

Rephrase to "any custom data the caller needs to be accessible in the ops callbacks" for smoother grammar.

```suggestion
``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
pass in any custom data the caller needs to be accessible in the ops callbacks
for fulfilling reads.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread fs/iomap/buffered-io.c
Comment on lines +580 to +589
void iomap_readahead(const struct iomap_ops *ops,
struct iomap_read_folio_ctx *ctx)
{
struct readahead_control *rac = ctx->rac;
struct iomap_iter iter = {
.inode = rac->mapping->host,
.pos = readahead_pos(rac),
.len = readahead_length(rac),
};
struct iomap_readpage_ctx ctx = {
.rac = rac,
};
size_t cur_bytes_pending;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Initialize cur_bytes_pending before first use to avoid relying on control-flow for correctness.

cur_bytes_pending is declared but never initialized before being passed by reference into iomap_readahead_iter. This currently works only because iomap_readahead_iter sets it before use and relies on ctx->cur_folio being NULL. Initializing cur_bytes_pending to 0 here would remove that control-flow dependency and make the code safer against future changes.

Comment on lines +225 to +227
``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
pass in any custom data the caller needs accessible in the ops callbacks for
fulfilling reads.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (typo): Slight grammar improvement around "needs accessible".

Rephrase to "any custom data the caller needs to be accessible in the ops callbacks" for smoother grammar.

Suggested change
``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
pass in any custom data the caller needs accessible in the ops callbacks for
fulfilling reads.
``ops->submit_read()`` and ``read_ctx`` are optional. ``read_ctx`` is used to
pass in any custom data the caller needs to be accessible in the ops callbacks
for fulfilling reads.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors iomap’s buffered read/readahead path to use a callback-based iomap_read_ops interface (with a shared bio-backed implementation) and switches FUSE buffered reads + readahead to iomap so that large-folio + granular uptodate tracking works safely (and removes the old FUSE blkbits workaround).

Changes:

  • Introduce struct iomap_read_folio_ctx / struct iomap_read_ops, export iomap_finish_folio_read(), and rework iomap_read_folio() / iomap_readahead() around range-based read callbacks.
  • Add fs/iomap/bio.c and iomap_bio_read_ops helpers; update multiple filesystems (XFS/EROFS/GFS2/zonefs/blkdev) to use iomap_bio_read_folio() / iomap_bio_readahead().
  • Convert FUSE read_folio + readahead to use the iomap read callbacks; remove fc->blkbits workaround in favor of superblock blocksize bits.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
include/linux/iomap.h New iomap read ctx/ops API; iomap_iter_advance signature change; new exported helpers/wrappers.
fs/iomap/buffered-io.c Core refactor: range-based read iteration, pending-read tracking, exports iomap_finish_folio_read.
fs/iomap/bio.c New shared bio-based read/readahead helper implementing iomap_read_ops.
fs/iomap/internal.h Exposes iomap_bio_read_folio_range_sync() for buffered write read-before-write logic.
fs/iomap/Makefile Adds bio.o under CONFIG_BLOCK.
fs/iomap/iter.c Updates iomap_iter_advance() to take a raw count.
fs/iomap/seek.c Updates callers for new iomap_iter_advance() signature.
fs/iomap/direct-io.c Updates callers for new iomap_iter_advance() signature.
fs/dax.c Updates callers/loops for new iomap_iter_advance() signature semantics.
fs/fuse/file.c Switches FUSE read_folio + readahead to iomap read callbacks; batching changes for async readahead.
fs/fuse/inode.c Removes blkbits workaround; uses superblock blocksize bits when attr blksize absent.
fs/fuse/dir.c Uses superblock blocksize bits when attr blksize absent.
fs/fuse/fuse_i.h Removes struct fuse_conn::blkbits.
fs/xfs/xfs_aops.c Uses iomap_bio_read_folio / iomap_bio_readahead.
fs/erofs/data.c Uses iomap_bio_read_folio / iomap_bio_readahead.
fs/gfs2/aops.c Uses iomap_bio_read_folio / iomap_bio_readahead.
fs/zonefs/file.c Uses iomap_bio_read_folio / iomap_bio_readahead.
block/fops.c Uses iomap_bio_read_folio / iomap_bio_readahead for blkdev aops.
Documentation/filesystems/iomap/operations.rst Documents new iomap read ctx/ops interface.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread fs/fuse/file.c
Comment on lines 1037 to 1041
static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file,
unsigned int count)
unsigned int count, bool async)
{
struct fuse_file *ff = file->private_data;
struct fuse_mount *fm = ff->fm;
Comment thread fs/fuse/file.c
Comment on lines 1024 to +1028
fuse_invalidate_atime(inode);

for (i = 0; i < ap->num_folios; i++) {
folio_end_read(ap->folios[i], !err);
iomap_finish_folio_read(ap->folios[i], ap->descs[i].offset,
ap->descs[i].length, err);
Comment thread fs/fuse/file.c
Comment on lines +907 to +910
nr_pages = min(fc->max_pages, readahead_count(rac));
data->ia = fuse_io_alloc(NULL, nr_pages);
if (!data->ia)
return -ENOMEM;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants