Some ops recycle or cache async data when they are done. Build this into the framework for async data so that we can rely on io_uring to know when a request is done (rather than doing it inline in a handler). Signed-off-by: Dylan Yudaken <dylany@xxxxxx> --- io_uring/io_uring.c | 8 ++++++-- io_uring/opdef.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 32110c5b4059..3e9fdaf9c72c 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1578,8 +1578,12 @@ static void io_clean_op(struct io_kiocb *req) if (req->flags & REQ_F_CREDS) put_cred(req->creds); if (req->flags & REQ_F_ASYNC_DATA) { - kfree(req->async_data); - req->async_data = NULL; + const struct io_op_def *def = &io_op_defs[req->opcode]; + + if (!(def->recycle_async && def->recycle_async(req))) { + kfree(req->async_data); + req->async_data = NULL; + } } req->flags &= ~IO_REQ_CLEAN_FLAGS; } diff --git a/io_uring/opdef.h b/io_uring/opdef.h index ece8ed4f96c4..3de64731fc5f 100644 --- a/io_uring/opdef.h +++ b/io_uring/opdef.h @@ -34,6 +34,7 @@ struct io_op_def { int (*issue)(struct io_kiocb *, unsigned int); int (*prep_async)(struct io_kiocb *); void (*cleanup)(struct io_kiocb *); + bool (*recycle_async)(struct io_kiocb *); }; extern const struct io_op_def io_op_defs[]; -- 2.30.2