Re: [PATCH v6 2/6] fuse: add FUSE_IO_URING_CMD_ADD_QUEUE

Bernd Schubert <[email protected]>
Newsgroups dev.linux.lists.fuse-devel
Message-ID <[email protected]>

On 7/16/26 19:59, Joanne Koong wrote:
> 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.
> 
> Signed-off-by: Joanne Koong <[email protected]>
> ---
>  fs/fuse/dev_uring.c       | 45 +++++++++++++++++++++++++++++++++------
>  include/uapi/linux/fuse.h |  8 ++++++-
>  2 files changed, 45 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c
> index b7c6100c4176..fdf1058e582c 100644
> --- a/fs/fuse/dev_uring.c
> +++ b/fs/fuse/dev_uring.c
> @@ -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;
>  	}
> diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
> index c13e1f9a2f12..cfb055c0c764 100644
> --- a/include/uapi/linux/fuse.h
> +++ b/include/uapi/linux/fuse.h
> @@ -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,
>  };
>  
>  /**


Reviewed-by: Bernd Schubert <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.