mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 10:31:33 -04:00
fuse: Fix the condition to enable over-io-uring
The existing condition in fuse_uring_cmd() is there only to avoid
disabling io-uring for connections that already run with it, missing
was a condition to refuse any IORING_OP_URING_CMD if the
connection/channel didn't get enabled because of missing FUSE_INIT
reply flag FUSE_OVER_IO_URING. Without the reply flag the barrier in
fuse_uring_ready() doesn't work and IO could already be going on and
cause deadlock states (at a minimum one between fch->bg_lock and
queue->lock).
The change itself is trivial, but brings behavior change,
FUSE_OVER_IO_URING has to be set in the FUSE_INIT_REPLY by fuse servers
to accept any IORING_OP_URING_CMD. Libfuse does that and the only
non-libfuse implementation I found (fractal-fuse) also does it.
Qemu patches for fuse-io-uring are not merged yet, as far as I know.
Moved up is the smp_load_acquire(&fch->initialized) check, as a
fuse-server implementation might try to setup io-uring before FUSE_INIT
is processed and might have gotten -EOPNOTSUPP instead of -EAGAIN.
Also fixed is a stale comment that explains the handling of the
FUSE_OVER_IO_URING flag in early RFC versions.
If there should be a report from any library or application we
probably need to revert this commit.
Fixes: 3393ff964e ("fuse: block request allocation until io-uring init is complete")
Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
committed by
Miklos Szeredi
parent
26d7e1f5c4
commit
1f59015e95
@@ -1665,25 +1665,30 @@ int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
|
||||
}
|
||||
fch = fud->chan;
|
||||
|
||||
/* Once a connection has io-uring enabled on it, it can't be disabled */
|
||||
if (!enable_uring && !fch->io_uring) {
|
||||
pr_info_ratelimited("fuse-io-uring is disabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
/*
|
||||
* The ring is sized from values negotiated by FUSE_INIT
|
||||
*
|
||||
* Pairs with smp_store_release() in fuse_chan_set_initialized()
|
||||
*/
|
||||
if (!smp_load_acquire(&fch->initialized))
|
||||
return -EAGAIN;
|
||||
|
||||
if (fch->abort_with_err)
|
||||
return -ECONNABORTED;
|
||||
if (!fch->connected)
|
||||
return -ENOTCONN;
|
||||
|
||||
/*
|
||||
* fuse_uring_register() needs the ring to be initialized,
|
||||
* we need to know the max payload size
|
||||
*
|
||||
* Pairs with smp_store_release() in fuse_chan_set_initialized()
|
||||
*/
|
||||
if (!smp_load_acquire(&fch->initialized))
|
||||
return -EAGAIN;
|
||||
/* Once a connection has io-uring enabled on it, it can't be disabled */
|
||||
if (!enable_uring && !fch->io_uring) {
|
||||
pr_info_ratelimited("fuse-io-uring is disabled by module parameter\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (!fch->io_uring) {
|
||||
pr_info_ratelimited(
|
||||
"fuse-io-uring not enabled on this connection\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
switch (cmd_op) {
|
||||
case FUSE_IO_URING_CMD_REGISTER:
|
||||
|
||||
@@ -1480,10 +1480,6 @@ static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm)
|
||||
if (IS_ENABLED(CONFIG_FUSE_PASSTHROUGH))
|
||||
flags |= FUSE_PASSTHROUGH;
|
||||
|
||||
/*
|
||||
* This is just an information flag for fuse server. No need to check
|
||||
* the reply - server is either sending IORING_OP_URING_CMD or not.
|
||||
*/
|
||||
if (fuse_uring_enabled())
|
||||
flags |= FUSE_OVER_IO_URING | FUSE_HAS_IO_URING_BUFPOOL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user