@@ -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;
@@ -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,
};
@@ -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)
*/