This patch supports IORING_URING_CMD_FIXED flags in io-uring cmd. It means that user provided buf_index in sqe that is registered before submitting requests. In this patch, btrfs_uring_encoded_read() makes iov_iter bvec type by checking the io-uring cmd flag. And there is additional iou_vec field in btrfs_uring_priv for remaining bvecs lifecycle. Signed-off-by: Sidong Yang <sidong.yang@xxxxxxxxxx> --- fs/btrfs/ioctl.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6c18bad53cd3..586671eea622 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -4643,6 +4643,7 @@ struct btrfs_uring_priv { struct page **pages; unsigned long nr_pages; struct kiocb iocb; + struct iou_vec iou_vec; struct iovec *iov; struct iov_iter iter; struct extent_state *cached_state; @@ -4711,6 +4712,8 @@ static void btrfs_uring_read_finished(struct io_uring_cmd *cmd, unsigned int iss kfree(priv->pages); kfree(priv->iov); + if (priv->iou_vec.iovec) + kfree(priv->iou_vec.iovec); kfree(priv); } @@ -4730,7 +4733,8 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, struct extent_state *cached_state, u64 disk_bytenr, u64 disk_io_size, size_t count, bool compressed, - struct iovec *iov, struct io_uring_cmd *cmd) + struct iovec *iov, struct io_uring_cmd *cmd, + struct iou_vec *iou_vec) { struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp)); struct extent_io_tree *io_tree = &inode->io_tree; @@ -4767,6 +4771,7 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, priv->start = start; priv->lockend = lockend; priv->err = 0; + priv->iou_vec = *iou_vec; ret = btrfs_encoded_read_regular_fill_pages(inode, disk_bytenr, disk_io_size, pages, priv); @@ -4818,6 +4823,7 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue u64 start, lockend; void __user *sqe_addr; struct btrfs_uring_encoded_data *data = io_uring_cmd_get_async_data(cmd)->op_data; + struct iou_vec iou_vec = {}; if (!capable(CAP_SYS_ADMIN)) { ret = -EPERM; @@ -4875,9 +4881,19 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue } data->iov = data->iovstack; - ret = import_iovec(ITER_DEST, data->args.iov, data->args.iovcnt, - ARRAY_SIZE(data->iovstack), &data->iov, - &data->iter); + + if (cmd && (cmd->flags & IORING_URING_CMD_FIXED)) { + ret = io_uring_cmd_import_fixed_vec( + data->args.iov, data->args.iovcnt, ITER_DEST, + &data->iter, cmd, &iou_vec, false, issue_flags); + data->iov = NULL; + } else { + ret = import_iovec(ITER_DEST, data->args.iov, + data->args.iovcnt, + ARRAY_SIZE(data->iovstack), + &data->iov, &data->iter); + } + if (ret < 0) goto out_acct; @@ -4929,7 +4945,7 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue ret = btrfs_uring_read_extent(&kiocb, &data->iter, start, lockend, cached_state, disk_bytenr, disk_io_size, count, data->args.compression, - data->iov, cmd); + data->iov, cmd, &iou_vec); goto out_acct; } -- 2.43.0