This changes fuse_uring_next_fuse_req() and subfunctions to use req obtained with a lock to avoid possible issues by compiler induced re-ordering. Also fix a function comment, that was missed during previous code refactoring. Fixes: a4bdb3d786c0 ("fuse: enable fuse-over-io-uring") Signed-off-by: Bernd Schubert <bschubert@xxxxxxx> --- fs/fuse/dev_uring.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index 80bb7396a8410022bbef1efa0522974bda77c81a..e90dd4ae5b2133e427855f1b0e60b73f008f7bc9 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -75,16 +75,15 @@ static void fuse_uring_flush_bg(struct fuse_ring_queue *queue) } } -static void fuse_uring_req_end(struct fuse_ring_ent *ent, int error) +static void fuse_uring_req_end(struct fuse_ring_ent *ent, struct fuse_req *req, + int error) { struct fuse_ring_queue *queue = ent->queue; - struct fuse_req *req; struct fuse_ring *ring = queue->ring; struct fuse_conn *fc = ring->fc; lockdep_assert_not_held(&queue->lock); spin_lock(&queue->lock); - req = ent->fuse_req; ent->fuse_req = NULL; if (test_bit(FR_BACKGROUND, &req->flags)) { queue->active_background--; @@ -684,7 +683,7 @@ static int fuse_uring_prepare_send(struct fuse_ring_ent *ent, if (!err) set_bit(FR_SENT, &req->flags); else - fuse_uring_req_end(ent, err); + fuse_uring_req_end(ent, req, err); return err; } @@ -768,12 +767,8 @@ static void fuse_uring_add_req_to_ring_ent(struct fuse_ring_ent *ent, fuse_uring_add_to_pq(ent, req); } -/* - * Release the ring entry and fetch the next fuse request if available - * - * @return true if a new request has been fetched - */ -static bool fuse_uring_ent_assign_req(struct fuse_ring_ent *ent) +/* Fetch the next fuse request if available */ +static struct fuse_req *fuse_uring_ent_assign_req(struct fuse_ring_ent *ent) __must_hold(&queue->lock) { struct fuse_req *req; @@ -784,12 +779,10 @@ static bool fuse_uring_ent_assign_req(struct fuse_ring_ent *ent) /* get and assign the next entry while it is still holding the lock */ req = list_first_entry_or_null(req_queue, struct fuse_req, list); - if (req) { + if (req) fuse_uring_add_req_to_ring_ent(ent, req); - return true; - } - return false; + return req; } /* @@ -819,7 +812,7 @@ static void fuse_uring_commit(struct fuse_ring_ent *ent, struct fuse_req *req, err = fuse_uring_copy_from_ring(ring, req, ent); out: - fuse_uring_req_end(ent, err); + fuse_uring_req_end(ent, req, err); } /* @@ -830,17 +823,16 @@ static void fuse_uring_next_fuse_req(struct fuse_ring_ent *ent, unsigned int issue_flags) { int err; - bool has_next; + struct fuse_req *req; retry: spin_lock(&queue->lock); fuse_uring_ent_avail(ent, queue); - has_next = fuse_uring_ent_assign_req(ent); + req = fuse_uring_ent_assign_req(ent); spin_unlock(&queue->lock); - if (has_next) { - err = fuse_uring_send_next_to_ring(ent, ent->fuse_req, - issue_flags); + if (req) { + err = fuse_uring_send_next_to_ring(ent, req, issue_flags); if (err) goto retry; } -- 2.43.0