io_uring_cmd_data should not be exposed for drivers to avoid to be abused its private fields. io_async_cmd is new struct that has io_uring_cmd_data for offset 0. So driver could be use async_data as io_uring_cmd_data as used before. And private fields would be added in io_async_cmd. Signed-off-by: Sidong Yang <sidong.yang@xxxxxxxxxx> --- io_uring/io_uring.c | 2 +- io_uring/opdef.c | 2 +- io_uring/uring_cmd.c | 21 ++++++++++++++------- io_uring/uring_cmd.h | 6 ++++++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 5ff30a7092ed..513f036bccbb 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -335,7 +335,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) sizeof(struct io_async_rw), offsetof(struct io_async_rw, clear)); ret |= io_alloc_cache_init(&ctx->uring_cache, IO_ALLOC_CACHE_MAX, - sizeof(struct io_uring_cmd_data), 0); + sizeof(struct io_async_cmd), 0); spin_lock_init(&ctx->msg_lock); ret |= io_alloc_cache_init(&ctx->msg_cache, IO_ALLOC_CACHE_MAX, sizeof(struct io_kiocb), 0); diff --git a/io_uring/opdef.c b/io_uring/opdef.c index 7fd173197b1e..e4aa61a414fb 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -416,7 +416,7 @@ const struct io_issue_def io_issue_defs[] = { .plug = 1, .iopoll = 1, .iopoll_queue = 1, - .async_size = sizeof(struct io_uring_cmd_data), + .async_size = sizeof(struct io_async_cmd), .prep = io_uring_cmd_prep, .issue = io_uring_cmd, }, diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index de39b602aa82..e4cd6fe9fd47 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -19,7 +19,8 @@ static void io_req_uring_cleanup(struct io_kiocb *req, unsigned int issue_flags) { struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd); - struct io_uring_cmd_data *cache = req->async_data; + struct io_async_cmd *ac = req->async_data; + struct io_uring_cmd_data *cache = &ac->data; if (cache->op_data) { kfree(cache->op_data); @@ -169,12 +170,18 @@ static int io_uring_cmd_prep_setup(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd); - struct io_uring_cmd_data *cache; + struct io_async_cmd *ac; - cache = io_uring_alloc_async_data(&req->ctx->uring_cache, req); - if (!cache) + /* + * 'data' must be at offset 0 to allow casting io_async_cmd to + * io_uring_cmd_data in io_uring_cmd_get_async_data(). + */ + BUILD_BUG_ON(offsetof(struct io_async_cmd, data) != 0); + + ac = io_uring_alloc_async_data(&req->ctx->uring_cache, req); + if (!ac) return -ENOMEM; - cache->op_data = NULL; + ac->data.op_data = NULL; /* * Unconditionally cache the SQE for now - this is only needed for @@ -183,8 +190,8 @@ static int io_uring_cmd_prep_setup(struct io_kiocb *req, * that it doesn't read in per-op data, play it safe and ensure that * any SQE data is stable beyond prep. This can later get relaxed. */ - memcpy(cache->sqes, sqe, uring_sqe_size(req->ctx)); - ioucmd->sqe = cache->sqes; + memcpy(ac->data.sqes, sqe, uring_sqe_size(req->ctx)); + ioucmd->sqe = ac->data.sqes; return 0; } diff --git a/io_uring/uring_cmd.h b/io_uring/uring_cmd.h index f6837ee0955b..f3593012658c 100644 --- a/io_uring/uring_cmd.h +++ b/io_uring/uring_cmd.h @@ -1,5 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 +#include <linux/io_uring/cmd.h> + +struct io_async_cmd { + struct io_uring_cmd_data data; +}; + int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags); int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe); -- 2.43.0