]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fuse-uring: separate next request fetching from sending logic
authorJoanne Koong <joannelkoong@gmail.com>
Fri, 12 Jun 2026 21:05:04 +0000 (14:05 -0700)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Jun 2026 12:06:20 +0000 (14:06 +0200)
Simplify the logic for fetching + sending off the next request.

This gets rid of fuse_uring_send_next_to_ring() which contained
duplicated logic from fuse_uring_send(). This decouples request fetching
from the send operation, which makes the control flow clearer and
reduces unnecessary parameter passing.

Reviewed-by: Bernd Schubert <bschubert@ddn.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Baokun Li <libaokun@linux.alibaba.com>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/dev_uring.c

index 87f5f9eba5345f27addfaec6f47d49ed8712fbd1..0b66fe3a5da0921fdddc559d860ac4d283b425be 100644 (file)
@@ -741,35 +741,6 @@ static void fuse_uring_add_to_pq(struct fuse_ring_ent *ent)
        list_move_tail(&req->list, &fpq->processing[hash]);
 }
 
-/*
- * Write data to the ring buffer and send the request to userspace,
- * userspace will read it
- * This is comparable with classical read(/dev/fuse)
- */
-static int fuse_uring_send_next_to_ring(struct fuse_ring_ent *ent,
-                                       struct fuse_req *req,
-                                       unsigned int issue_flags)
-{
-       struct fuse_ring_queue *queue = ent->queue;
-       int err;
-       struct io_uring_cmd *cmd;
-
-       err = fuse_uring_prepare_send(ent, req);
-       if (err)
-               return err;
-
-       spin_lock(&queue->lock);
-       cmd = ent->cmd;
-       ent->cmd = NULL;
-       ent->state = FRRS_USERSPACE;
-       list_move_tail(&ent->list, &queue->ent_in_userspace);
-       fuse_uring_add_to_pq(ent);
-       spin_unlock(&queue->lock);
-
-       io_uring_cmd_done(cmd, 0, issue_flags);
-       return 0;
-}
-
 /*
  * Make a ring entry available for fuse_req assignment
  */
@@ -852,11 +823,13 @@ out:
 }
 
 /*
- * Get the next fuse req and send it
+ * Get the next fuse req.
+ *
+ * Returns true if the next fuse request has been assigned to the ent.
+ * Else, there is no next fuse request and this returns false.
  */
-static void fuse_uring_next_fuse_req(struct fuse_ring_ent *ent,
-                                    struct fuse_ring_queue *queue,
-                                    unsigned int issue_flags)
+static bool fuse_uring_get_next_fuse_req(struct fuse_ring_ent *ent,
+                                        struct fuse_ring_queue *queue)
 {
        int err;
        struct fuse_req *req;
@@ -868,10 +841,12 @@ retry:
        spin_unlock(&queue->lock);
 
        if (req) {
-               err = fuse_uring_send_next_to_ring(ent, req, issue_flags);
+               err = fuse_uring_prepare_send(ent, req);
                if (err)
                        goto retry;
        }
+
+       return req != NULL;
 }
 
 static int fuse_ring_ent_set_commit(struct fuse_ring_ent *ent)
@@ -889,6 +864,21 @@ static int fuse_ring_ent_set_commit(struct fuse_ring_ent *ent)
        return 0;
 }
 
+static void fuse_uring_send(struct fuse_ring_ent *ent, struct io_uring_cmd *cmd,
+                           ssize_t ret, unsigned int issue_flags)
+{
+       struct fuse_ring_queue *queue = ent->queue;
+
+       spin_lock(&queue->lock);
+       ent->state = FRRS_USERSPACE;
+       list_move_tail(&ent->list, &queue->ent_in_userspace);
+       ent->cmd = NULL;
+       fuse_uring_add_to_pq(ent);
+       spin_unlock(&queue->lock);
+
+       io_uring_cmd_done(cmd, ret, issue_flags);
+}
+
 /* FUSE_URING_CMD_COMMIT_AND_FETCH handler */
 static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
                                   struct fuse_chan *fch)
@@ -966,7 +956,8 @@ static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
         * and fetching is done in one step vs legacy fuse, which has separated
         * read (fetch request) and write (commit result).
         */
-       fuse_uring_next_fuse_req(ent, queue, issue_flags);
+       if (fuse_uring_get_next_fuse_req(ent, queue))
+               fuse_uring_send(ent, cmd, 0, issue_flags);
        return 0;
 }
 
@@ -1225,21 +1216,6 @@ int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
        return -EIOCBQUEUED;
 }
 
-static void fuse_uring_send(struct fuse_ring_ent *ent, struct io_uring_cmd *cmd,
-                           ssize_t ret, unsigned int issue_flags)
-{
-       struct fuse_ring_queue *queue = ent->queue;
-
-       spin_lock(&queue->lock);
-       ent->state = FRRS_USERSPACE;
-       list_move_tail(&ent->list, &queue->ent_in_userspace);
-       ent->cmd = NULL;
-       fuse_uring_add_to_pq(ent);
-       spin_unlock(&queue->lock);
-
-       io_uring_cmd_done(cmd, ret, issue_flags);
-}
-
 /*
  * This prepares and sends the ring request in fuse-uring task context.
  * User buffers are not mapped yet - the application does not have permission
@@ -1256,8 +1232,9 @@ static void fuse_uring_send_in_task(struct io_tw_req tw_req, io_tw_token_t tw)
        if (!tw.cancel) {
                err = fuse_uring_prepare_send(ent, ent->fuse_req);
                if (err) {
-                       fuse_uring_next_fuse_req(ent, queue, issue_flags);
-                       return;
+                       if (!fuse_uring_get_next_fuse_req(ent, queue))
+                               return;
+                       err = 0;
                }
                fuse_uring_send(ent, cmd, err, issue_flags);
        } else {