mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
fuse: add FUSE_IO_URING_CMD_ADD_QUEUE
fuse-over-io-uring queues are currently created lazily, as a side effect of the first FUSE_IO_URING_CMD_REGISTER command for a given qid. This ties queue creation to entry registration. Add a FUSE_IO_URING_CMD_ADD_QUEUE command so a server can create a queue explicitly, decoupling queue setup from entry registration. This is additionally a prerequisite for FUSE_IO_URING_CMD_ADD_BUFPOOL, which attaches a buffer pool to an existing queue and therefore needs the queue to have been created first. Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Signed-off-by: Joanne Koong <joannelkoong@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
committed by
Miklos Szeredi
parent
6330b1f61e
commit
ebed9ea5b4
@@ -281,7 +281,8 @@ void fuse_uring_conn_init(struct fuse_chan *fch)
|
||||
}
|
||||
|
||||
static struct fuse_ring_queue *fuse_uring_create_queue(struct fuse_ring *ring,
|
||||
int qid)
|
||||
int qid,
|
||||
bool fail_if_exists)
|
||||
{
|
||||
struct fuse_chan *fch = ring->chan;
|
||||
struct fuse_ring_queue *queue;
|
||||
@@ -289,11 +290,11 @@ static struct fuse_ring_queue *fuse_uring_create_queue(struct fuse_ring *ring,
|
||||
|
||||
queue = kzalloc_obj(*queue, GFP_KERNEL_ACCOUNT);
|
||||
if (!queue)
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
pq = fuse_pqueue_alloc();
|
||||
if (!pq) {
|
||||
kfree(queue);
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
queue->qid = qid;
|
||||
@@ -316,7 +317,7 @@ static struct fuse_ring_queue *fuse_uring_create_queue(struct fuse_ring *ring,
|
||||
spin_unlock(&fch->lock);
|
||||
kfree(queue->fpq.processing);
|
||||
kfree(queue);
|
||||
return ring->queues[qid];
|
||||
return fail_if_exists ? ERR_PTR(-EEXIST) : ring->queues[qid];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1189,9 +1190,9 @@ static int fuse_uring_register(struct io_uring_cmd *cmd,
|
||||
|
||||
queue = READ_ONCE(ring->queues[qid]);
|
||||
if (!queue) {
|
||||
queue = fuse_uring_create_queue(ring, qid);
|
||||
if (!queue)
|
||||
return -ENOMEM;
|
||||
queue = fuse_uring_create_queue(ring, qid, false);
|
||||
if (IS_ERR(queue))
|
||||
return PTR_ERR(queue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1206,6 +1207,30 @@ static int fuse_uring_register(struct io_uring_cmd *cmd,
|
||||
return fuse_uring_do_register(ent, cmd, issue_flags);
|
||||
}
|
||||
|
||||
static int fuse_uring_add_queue(struct io_uring_cmd *cmd, struct fuse_chan *fch)
|
||||
{
|
||||
const struct fuse_uring_cmd_req *cmd_req =
|
||||
io_uring_sqe128_cmd(cmd->sqe, struct fuse_uring_cmd_req);
|
||||
struct fuse_ring *ring = smp_load_acquire(&fch->ring);
|
||||
unsigned int qid = READ_ONCE(cmd_req->qid);
|
||||
uint64_t flags = READ_ONCE(cmd_req->flags);
|
||||
struct fuse_ring_queue *queue;
|
||||
|
||||
if (!ring || flags)
|
||||
return -EINVAL;
|
||||
|
||||
if (qid >= ring->nr_queues) {
|
||||
pr_info_ratelimited("fuse: Invalid ring qid %u\n", qid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
queue = fuse_uring_create_queue(ring, qid, true);
|
||||
if (IS_ERR(queue))
|
||||
return PTR_ERR(queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry function from io_uring to handle the given passthrough command
|
||||
* (op code IORING_OP_URING_CMD)
|
||||
@@ -1272,6 +1297,12 @@ int fuse_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
case FUSE_IO_URING_CMD_ADD_QUEUE:
|
||||
err = fuse_uring_add_queue(cmd, fch);
|
||||
if (err)
|
||||
pr_info_once("FUSE_IO_URING_CMD_ADD_QUEUE failed err=%d\n",
|
||||
err);
|
||||
return err;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -240,6 +240,9 @@
|
||||
* - add FUSE_COPY_FILE_RANGE_64
|
||||
* - add struct fuse_copy_file_range_out
|
||||
* - add FUSE_NOTIFY_PRUNE
|
||||
*
|
||||
* 7.46
|
||||
* - add FUSE_IO_URING_CMD_ADD_QUEUE
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FUSE_H
|
||||
@@ -275,7 +278,7 @@
|
||||
#define FUSE_KERNEL_VERSION 7
|
||||
|
||||
/** Minor version number of this interface */
|
||||
#define FUSE_KERNEL_MINOR_VERSION 45
|
||||
#define FUSE_KERNEL_MINOR_VERSION 46
|
||||
|
||||
/** The node ID of the root inode */
|
||||
#define FUSE_ROOT_ID 1
|
||||
@@ -1292,6 +1295,9 @@ enum fuse_uring_cmd {
|
||||
|
||||
/* commit fuse request result and fetch next request */
|
||||
FUSE_IO_URING_CMD_COMMIT_AND_FETCH = 2,
|
||||
|
||||
/* add a queue */
|
||||
FUSE_IO_URING_CMD_ADD_QUEUE = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user