public inbox for gfs2@lists.linux.dev
 help / color / mirror / Atom feed
From: Gao Xiang <hsiangkao@linux.alibaba.com>
To: Joanne Koong <joannelkoong@gmail.com>,
	djwong@kernel.org, hch@infradead.org, brauner@kernel.org,
	miklos@szeredi.hu, linux-block@vger.kernel.org,
	gfs2@lists.linux.dev, linux-fsdevel@vger.kernel.org,
	kernel-team@meta.com, linux-xfs@vger.kernel.org,
	linux-doc@vger.kernel.org
Subject: Re: [PATCH v2 11/16] iomap: add caller-provided callbacks for read and readahead
Date: Wed, 10 Sep 2025 07:21:48 +0800	[thread overview]
Message-ID: <488d246b-13c7-4e36-9510-8ae2de450647@linux.alibaba.com> (raw)
In-Reply-To: <CAJnrk1YPpNs811dwWo+ts1xwFi-57OgWvSO4_8WLL_3fJgzrFw@mail.gmail.com>

Hi Joanne,

On 2025/9/9 23:24, Joanne Koong wrote:
> On Mon, Sep 8, 2025 at 8:14 PM Gao Xiang <xiang@kernel.org> wrote:
>>
>> Hi Joanne,
>>
>> On Mon, Sep 08, 2025 at 11:51:17AM -0700, Joanne Koong wrote:
>>> 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 *private;
>>>    };
>>>
>>>    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,
>>>                               loff_t pos, size_t len);
>>>        int (*read_submit)(struct iomap_read_folio_ctx *ctx);
>>>    };
>>>
>>
>> No, I don't think `struct iomap_read_folio_ctx` has another
>> `.private` makes any sense, because:
>>
>>   - `struct iomap_iter *iter` already has `.private` and I think
>>     it's mainly used for per-request usage; and your new
>>     `.read_folio_range` already passes
>>      `const struct iomap_iter *iter` which has `.private`
>>     I don't think some read-specific `.private` is useful in any
>>     case, also below.
>>
>>   - `struct iomap_read_folio_ctx` cannot be accessed by previous
>>     .iomap_{begin,end} helpers, which means `struct iomap_read_ops`
>>     is only useful for FUSE read iter/submit logic.
>>
>> Also after my change, the prototype will be:
>>
>> int iomap_read_folio(const struct iomap_ops *ops,
>>                       struct iomap_read_folio_ctx *ctx, void *private2);
>> void iomap_readahead(const struct iomap_ops *ops,
>>                       struct iomap_read_folio_ctx *ctx, void *private2);
>>
>> Is it pretty weird due to `.iomap_{begin,end}` in principle can
>> only use `struct iomap_iter *` but have no way to access
>> ` struct iomap_read_folio_ctx` to get more enough content for
>> read requests.
> 
> Hi Gao,
> 
> imo I don't think it makes sense to, if I'm understanding what you're
> proposing correctly, have one shared data pointer between iomap
> read/readahead and the iomap_{begin,end} helpers because

My main concern is two `private` naming here: I would like to add
`private` to iomap_read/readahead() much like __iomap_dio_rw() at
least to make our new feature work efficiently.

> 
> a) I don't think it's guaranteed that the data needed by
> read/readahead and iomap_{begin,end} is the same.  I guess we could
> combine the data each needs altogether into one struct, but it seems
> simpler and cleaner to me to just have the two be separate.
> 
> b) I'm not sure about the erofs use case, but at least for what I'm
> seeing for fuse and the block-based filesystems currently using iomap,
> the data needed by iomap read/readahead (eg bios, the fuse
> fuse_fill_read_data) is irrelevant for iomap_{begin/end} and it seems
> unclean to expose that extraneous info. (btw I don't think it's true
> that iomap_iter is mainly used for per-request usage - for readahead
> for example, iomap_{begin,end} is called before and after we service
> the entire readahead, not called per request, whereas
> .read_folio_range() is called per request).

I said `per-request` meant a single sync read or readahead request,
which is triggered by vfs or mm for example.

> 
> c) imo iomap_{begin,end} is meant to be a more generic interface and I
> don't think it makes sense to tie read-specific data to it. For
> example, some filesystems (eg gfs2) use the same iomap_ops across
> different file operations (eg buffered writes, direct io, reads, bmap,
> etc).

Previously `.iomap_{begin,end}` participates in buffer read and write
I/O paths (except for page writeback of course) as you said, in
principle users only need to care about fields in `struct iomap_iter`.

`struct iomap_readpage_ctx` is currently used as an internal structure
which is completely invisible to filesystems (IOWs, filesystems don't
need to care or specify any of that).

After your proposal, new renamed `struct iomap_read_folio_ctx` will be
exposed to individual filesystems too, but that makes two external
context structures for the buffer I/O reads (`struct iomap_iter` and
`struct iomap_read_folio_ctx`) instead of one.

I'm not saying your proposal doesn't work, but:

  - which is unlike `struct iomap_writepage_ctx` because writeback path
    doesn't have `struct iomap_iter` involved, and it has only that
    exact one `struct iomap_writepage_ctx` context and all callbacks
    use that only;

  - take a look at `iomap_dio_rw` and `iomap_dio_ops`, I think it's
    somewhat similiar to the new `struct iomap_read_ops` in some
    extent, but dio currently also exposes the exact one context
    (`struct iomap_iter`) to users.

  - take a look at `iomap_write_ops`, it also exposes
    `struct iomap_iter` only. you may say `folio`, `pos`, `len` can be
    wrapped as another `struct iomap_write_ctx` if needed, but that is
    not designed to be exposed to be specfied by write_iter (e.g.
    fuse_cache_write_iter)

In short, traditionally the buffered read/write external context is
the only unique one `struct iomap_iter` (`struct iomap_readpage_ctx`
is only for iomap internal use), after your proposal there will be
two external contexts specified by users (.read_folio and .readahead)
but `.iomap_{begin,end}` is unable to get one of them, which is
unlike the current writeback and direct i/o paths (they uses one
external context too.)

Seperate into two contexts works for your use case, but it may
cause issues since future developers have to decide where to
place those new context fields for buffer I/O paths (
`struct iomap_iter` or `struct iomap_read_folio_ctx`), it's still
possible but may cause further churn on the codebase perspective.

That is my minor concern, but my main concern is still `private`
naming.

Thanks,
Gao Xiang


> 
> 
> Thanks,
> Joanne
> 
>>
>> Thanks,
>> Gao Xiang


  reply	other threads:[~2025-09-09 23:21 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-08 18:51 [PATCH v2 00/16] fuse: use iomap for buffered reads + readahead Joanne Koong
2025-09-08 18:51 ` [PATCH v2 01/16] iomap: move async bio read logic into helper function Joanne Koong
2025-09-11 11:09   ` Christoph Hellwig
2025-09-12 16:01     ` Joanne Koong
2025-09-08 18:51 ` [PATCH v2 02/16] iomap: move read/readahead bio submission " Joanne Koong
2025-09-11 11:09   ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 03/16] iomap: rename cur_folio_in_bio to folio_owned Joanne Koong
2025-09-11 11:10   ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 04/16] iomap: store read/readahead bio generically Joanne Koong
2025-09-11 11:11   ` Christoph Hellwig
2025-09-12 16:10     ` Joanne Koong
2025-09-08 18:51 ` [PATCH v2 05/16] iomap: propagate iomap_read_folio() error to caller Joanne Koong
2025-09-11 11:13   ` Christoph Hellwig
2025-09-12 16:28     ` Joanne Koong
2025-09-15 16:05       ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 06/16] iomap: iterate over entire folio in iomap_readpage_iter() Joanne Koong
2025-09-11 11:15   ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 07/16] iomap: rename iomap_readpage_iter() to iomap_read_folio_iter() Joanne Koong
2025-09-11 11:16   ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 08/16] iomap: rename iomap_readpage_ctx struct to iomap_read_folio_ctx Joanne Koong
2025-09-11 11:16   ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 09/16] iomap: add public start/finish folio read helpers Joanne Koong
2025-09-11 11:16   ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 10/16] iomap: make iomap_read_folio_ctx->folio_owned internal Joanne Koong
2025-09-11 11:17   ` Christoph Hellwig
2025-09-08 18:51 ` [PATCH v2 11/16] iomap: add caller-provided callbacks for read and readahead Joanne Koong
2025-09-09  0:14   ` Gao Xiang
2025-09-09  0:40     ` Gao Xiang
2025-09-09 15:24     ` Joanne Koong
2025-09-09 23:21       ` Gao Xiang [this message]
2025-09-10 17:41         ` Joanne Koong
2025-09-11 11:19           ` Christoph Hellwig
2025-09-11 11:26   ` Christoph Hellwig
2025-09-12 17:36     ` Joanne Koong
2025-09-08 18:51 ` [PATCH v2 12/16] iomap: add bias for async read requests Joanne Koong
2025-09-11 11:31   ` Christoph Hellwig
2025-09-12 17:30     ` Joanne Koong
2025-09-15 16:05       ` Christoph Hellwig
2025-09-16 19:14       ` Joanne Koong
2025-09-19 15:04         ` Christoph Hellwig
2025-09-19 17:58           ` Joanne Koong
2025-09-08 18:51 ` [PATCH v2 13/16] iomap: move read/readahead logic out of CONFIG_BLOCK guard Joanne Koong
2025-09-09  2:14   ` Gao Xiang
2025-09-09 15:33     ` Joanne Koong
2025-09-10  4:59       ` Gao Xiang
2025-09-11 11:37         ` Christoph Hellwig
2025-09-11 12:29           ` Gao Xiang
2025-09-11 19:45             ` Joanne Koong
2025-09-12  0:06               ` Gao Xiang
2025-09-12  1:09                 ` Gao Xiang
2025-09-12  1:10                   ` Gao Xiang
2025-09-12 19:56                     ` Joanne Koong
2025-09-12 20:09                       ` Joanne Koong
2025-09-12 23:35                         ` Gao Xiang
2025-09-12 23:20                       ` Gao Xiang
2025-09-11 11:44   ` Christoph Hellwig
2025-09-16 23:23     ` Joanne Koong
2025-09-08 18:51 ` [PATCH v2 14/16] fuse: use iomap for read_folio Joanne Koong
2025-09-08 18:51 ` [PATCH v2 15/16] fuse: use iomap for readahead Joanne Koong
2025-09-08 18:51 ` [PATCH v2 16/16] fuse: remove fc->blkbits workaround for partial writes Joanne Koong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=488d246b-13c7-4e36-9510-8ae2de450647@linux.alibaba.com \
    --to=hsiangkao@linux.alibaba.com \
    --cc=brauner@kernel.org \
    --cc=djwong@kernel.org \
    --cc=gfs2@lists.linux.dev \
    --cc=hch@infradead.org \
    --cc=joannelkoong@gmail.com \
    --cc=kernel-team@meta.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox