[PATCH 16/17] io_uring: add support for non-inline uring-cmd

Kanchan Joshi
2022-03-08T15:43:26Z

Lifetime of inline commands (within sqe) is upto submission, and maximum
length is 80 bytes. This can be limiting for certain commands.
Add option to accept command pointer via same sqe->cmd field. User need to
set IORING_URING_CMD_INDIRECT flag in sqe->uring_cmd_flags.

Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
---
fs/io_uring.c | 13 +++++++++++--
include/linux/io_uring.h | 1 +
include/uapi/linux/io_uring.h | 6 ++++++
3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 8bd9401f9964..d88c6601a556 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -4189,8 +4189,12 @@ static int io_uring_cmd_prep(struct io_kiocb *req,
{
struct io_ring_ctx *ctx = req->ctx;
struct io_uring_cmd *ioucmd = &req->uring_cmd;
+ u32 ucmd_flags = READ_ONCE(sqe->uring_cmd_flags);

- if (!req->file->f_op->async_cmd || !(req->ctx->flags & IORING_SETUP_SQE128))
+ if (!req->file->f_op->async_cmd)
+ return -EOPNOTSUPP;
+ if (!(req->ctx->flags & IORING_SETUP_SQE128) &&
+ !(ucmd_flags & IORING_URING_CMD_INDIRECT))
return -EOPNOTSUPP;
if (req->ctx->flags & IORING_SETUP_IOPOLL) {
ioucmd->flags = IO_URING_F_UCMD_POLLED;
@@ -4206,7 +4210,12 @@ static int io_uring_cmd_prep(struct io_kiocb *req,
ioucmd->flags |= IO_URING_F_UCMD_FIXEDBUFS;
}

- ioucmd->cmd = (void *) &sqe->cmd;
+ if (ucmd_flags & IORING_URING_CMD_INDIRECT) {
+ ioucmd->flags |= IO_URING_F_UCMD_INDIRECT;
+ ioucmd->cmd = (void *) sqe->cmd;
+ } else {
+ ioucmd->cmd = (void *) &sqe->cmd;
+ }
ioucmd->cmd_op = READ_ONCE(sqe->cmd_op);
ioucmd->cmd_len = READ_ONCE(sqe->cmd_len);
return 0;
diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
index 65db83d703b7..c534a6fcef4f 100644
--- a/include/linux/io_uring.h
+++ b/include/linux/io_uring.h
@@ -10,6 +10,7 @@ enum io_uring_cmd_flags {
IO_URING_F_UNLOCKED = 2,
IO_URING_F_UCMD_FIXEDBUFS = 4,
IO_URING_F_UCMD_POLLED = 8,
+ IO_URING_F_UCMD_INDIRECT = 16,
/* int's last bit, sign checks are usually faster than a bit test */
IO_URING_F_NONBLOCK = INT_MIN,
};
diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h
index ee84be4b6be8..a4b9db37ecf1 100644
--- a/include/uapi/linux/io_uring.h
+++ b/include/uapi/linux/io_uring.h
@@ -47,6 +47,7 @@ struct io_uring_sqe {
__u32 rename_flags;
__u32 unlink_flags;
__u32 hardlink_flags;
+ __u32 uring_cmd_flags;
};
__u64 user_data; /* data to be passed back at completion time */
/* pack this to avoid bogus arm OABI complaints */
@@ -198,6 +199,11 @@ enum {
#define IORING_POLL_UPDATE_EVENTS (1U << 1)
#define IORING_POLL_UPDATE_USER_DATA (1U << 2)

+/*
+ * sqe->uring_cmd_flags
+ */
+#define IORING_URING_CMD_INDIRECT (1U << 0)
+
/*
* IO completion data structure (Completion Queue Entry)
*/
--
2.25.1