On Fri, Aug 29, 2025 at 10:50:23PM -0400, Brian Song wrote:
> https://docs.kernel.org/filesystems/fuse-io-uring.html
> 
> As described in the kernel documentation, after FUSE-over-io_uring
> initialization and handshake, FUSE interacts with the kernel using
> SQE/CQE to send requests and receive responses. This corresponds to
> the "Sending requests with CQEs" section in the docs.
> 
> This patch implements three key parts: registering the CQE handler
> (fuse_uring_cqe_handler), processing FUSE requests (fuse_uring_co_
> process_request), and sending response results (fuse_uring_send_
> response). It also merges the traditional /dev/fuse request handling
> with the FUSE-over-io_uring handling functions.
> 
> Suggested-by: Kevin Wolf <[email protected]>
> Suggested-by: Stefan Hajnoczi <[email protected]>
> Signed-off-by: Brian Song <[email protected]>
> ---
>  block/export/fuse.c | 457 ++++++++++++++++++++++++++++++--------------
>  1 file changed, 309 insertions(+), 148 deletions(-)
> 
> diff --git a/block/export/fuse.c b/block/export/fuse.c
> index 19bf9e5f74..07f74fc8ec 100644
> --- a/block/export/fuse.c
> +++ b/block/export/fuse.c
> @@ -310,6 +310,47 @@ static const BlockDevOps fuse_export_blk_dev_ops = {
>  };
>  
>  #ifdef CONFIG_LINUX_IO_URING
> +static void coroutine_fn fuse_uring_co_process_request(FuseRingEnt *ent);
> +
> +static void coroutine_fn co_fuse_uring_queue_handle_cqes(void *opaque)

This function appears to handle exactly one cqe. A singular function
name would be clearer than a plural: co_fuse_uring_queue_handle_cqe().

> +{
> +    FuseRingEnt *ent = opaque;
> +    FuseExport *exp = ent->rq->q->exp;
> +
> +    /* Going to process requests */
> +    fuse_inc_in_flight(exp);

What is the rationale for taking a reference here? Normally something
already holds a reference (e.g. the request itself) and it will be
dropped somewhere inside a function we're about to call, but we still
need to access exp afterwards, so we temporarily take a reference.
Please document the specifics in a comment.

I think blk_exp_ref()/blk_exp_unref() are appropriate instead of
fuse_inc_in_flight()/fuse_dec_in_flight() since we only need to hold
onto the export and don't care about drain behavior.

> +
> +    /* A ring entry returned */
> +    fuse_uring_co_process_request(ent);
> +
> +    /* Finished processing requests */
> +    fuse_dec_in_flight(exp);
> +}
> +
> +static void fuse_uring_cqe_handler(CqeHandler *cqe_handler)
> +{
> +    FuseRingEnt *ent = container_of(cqe_handler, FuseRingEnt, 
> fuse_cqe_handler);
> +    Coroutine *co;
> +    FuseExport *exp = ent->rq->q->exp;
> +
> +    if (unlikely(exp->halted)) {
> +        return;
> +    }
> +
> +    int err = cqe_handler->cqe.res;
> +
> +    if (err != 0) {
> +        /* -ENOTCONN is ok on umount  */
> +        if (err != -EINTR && err != -EAGAIN &&
> +            err != -ENOTCONN) {
> +            fuse_export_halt(exp);
> +        }

How are EINTR and EAGAIN handled if they are silently ignored? When did
you encounter these error codes?

Attachment: signature.asc
Description: PGP signature

Reply via email to