On 11/27/24 13:40, Bernd Schubert wrote:
This adds support for fuse request completion through ring SQEs (FUSE_URING_REQ_COMMIT_AND_FETCH handling). After committing the ring entry it becomes available for new fuse requests. Handling of requests through the ring (SQE/CQE handling) is complete now. Fuse request data are copied through the mmaped ring buffer, there is no support for any zero copy yet. Signed-off-by: Bernd Schubert <bschubert@xxxxxxx> ---
...
diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index af9c5f116ba1dcf6c01d0359d1a06491c92c32f9..7bb07f5ba436fcb89537f0821f08a7167da52902 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -24,6 +24,19 @@ bool fuse_uring_enabled(void)
...
+/* + * 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 *ring_ent) +{ + int err = 0; + struct fuse_ring_queue *queue = ring_ent->queue; + + err = fuse_uring_prepare_send(ring_ent); + if (err) + goto err; + + spin_lock(&queue->lock); + ring_ent->state = FRRS_USERSPACE; + list_move(&ring_ent->list, &queue->ent_in_userspace); + spin_unlock(&queue->lock); + + io_uring_cmd_complete_in_task(ring_ent->cmd, + fuse_uring_async_send_to_ring);
Just io_uring_cmd_done should be enough. io_uring_cmd_done(cmd, 0, 0, issue_flags);
+ return 0; + +err: + return err; +} + /* * Make a ring entry available for fuse_req assignment */ @@ -148,6 +385,189 @@ static void fuse_uring_ent_avail(struct fuse_ring_ent *ring_ent, ring_ent->state = FRRS_WAIT; }
...
+ +/* FUSE_URING_REQ_COMMIT_AND_FETCH handler */ +static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags, + struct fuse_conn *fc) +{ + const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe_cmd(cmd->sqe);
Same comment about checking SQE128, fuse_uring_cmd() sounds like a good place for it.
+ struct fuse_ring_ent *ring_ent; + int err; + struct fuse_ring *ring = fc->ring; + struct fuse_ring_queue *queue; + uint64_t commit_id = cmd_req->commit_id; + struct fuse_pqueue fpq; + struct fuse_req *req; + + err = -ENOTCONN; + if (!ring) + return err; + + queue = ring->queues[cmd_req->qid];
READ_ONCE()
+ if (!queue) + return err; + fpq = queue->fpq; +
-- Pavel Begunkov