mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
fuse-uring: Avoid queue->stopped races and set/read that value under lock
There are several readers of queue->stopped that check the value
under lock, but fuse_uring_commit_fetch() did not and actually
the value was not set under the lock in fuse_uring_abort_end_requests()
either. Especially in fuse_uring_commit_fetch it is important
to check under a lock, because due to races 'struct fuse_req'
might be freed with fuse_request_end, but another thread/cpu
might already do teardown work.
Cc: stable@kernel.org # 6.14
Fixes: 4a9bfb9b68 ("fuse: {io-uring} Handle teardown of ring entries")
Reported-by: Berkant Koc <me@berkoc.com>
Reported-by: xlabai <xlabai@tencent.com>
Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
d351da7506
commit
b70a3aca16
|
|
@ -130,10 +130,9 @@ void fuse_uring_abort_end_requests(struct fuse_ring *ring)
|
|||
if (!queue)
|
||||
continue;
|
||||
|
||||
queue->stopped = true;
|
||||
|
||||
WARN_ON_ONCE(ring->fc->max_background != UINT_MAX);
|
||||
spin_lock(&queue->lock);
|
||||
queue->stopped = true;
|
||||
spin_lock(&fc->bg_lock);
|
||||
fuse_uring_flush_bg(queue);
|
||||
spin_unlock(&fc->bg_lock);
|
||||
|
|
@ -470,7 +469,7 @@ static void fuse_uring_async_stop_queues(struct work_struct *work)
|
|||
FUSE_URING_TEARDOWN_INTERVAL);
|
||||
} else {
|
||||
wake_up_all(&ring->stop_waitq);
|
||||
fuse_conn_put(ring->chan->conn);
|
||||
fuse_conn_put(ring->fc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -482,7 +481,7 @@ void fuse_uring_stop_queues(struct fuse_ring *ring)
|
|||
fuse_uring_teardown_all_queues(ring);
|
||||
|
||||
if (atomic_read(&ring->queue_refs) > 0) {
|
||||
fuse_conn_get(ring->chan->conn);
|
||||
fuse_conn_get(ring->fc);
|
||||
ring->teardown_time = jiffies;
|
||||
INIT_DELAYED_WORK(&ring->async_teardown_work,
|
||||
fuse_uring_async_stop_queues);
|
||||
|
|
@ -903,10 +902,15 @@ static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags,
|
|||
return err;
|
||||
fpq = &queue->fpq;
|
||||
|
||||
if (!READ_ONCE(fc->connected) || READ_ONCE(queue->stopped))
|
||||
if (!READ_ONCE(fc->connected))
|
||||
return err;
|
||||
|
||||
spin_lock(&queue->lock);
|
||||
if (unlikely(queue->stopped)) {
|
||||
spin_unlock(&queue->lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Find a request based on the unique ID of the fuse request
|
||||
* This should get revised, as it needs a hash calculation and list
|
||||
* search. And full struct fuse_pqueue is needed (memory overhead).
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user