Commit 8165b566 authored by Jens Axboe's avatar Jens Axboe

io_uring/cancel: add IORING_ASYNC_CANCEL_USERDATA

Add a flag to explicitly match on user_data in the request for
cancelation purposes. This is the default behavior if none of the
other match flags are set, but if we ALSO want to match on user_data,
then this flag can be set.
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent a30badf6
...@@ -299,11 +299,13 @@ enum io_uring_op { ...@@ -299,11 +299,13 @@ enum io_uring_op {
* request 'user_data' * request 'user_data'
* IORING_ASYNC_CANCEL_ANY Match any request * IORING_ASYNC_CANCEL_ANY Match any request
* IORING_ASYNC_CANCEL_FD_FIXED 'fd' passed in is a fixed descriptor * IORING_ASYNC_CANCEL_FD_FIXED 'fd' passed in is a fixed descriptor
* IORING_ASYNC_CANCEL_USERDATA Match on user_data, default for no other key
*/ */
#define IORING_ASYNC_CANCEL_ALL (1U << 0) #define IORING_ASYNC_CANCEL_ALL (1U << 0)
#define IORING_ASYNC_CANCEL_FD (1U << 1) #define IORING_ASYNC_CANCEL_FD (1U << 1)
#define IORING_ASYNC_CANCEL_ANY (1U << 2) #define IORING_ASYNC_CANCEL_ANY (1U << 2)
#define IORING_ASYNC_CANCEL_FD_FIXED (1U << 3) #define IORING_ASYNC_CANCEL_FD_FIXED (1U << 3)
#define IORING_ASYNC_CANCEL_USERDATA (1U << 4)
/* /*
* send/sendmsg and recv/recvmsg flags (sqe->ioprio) * send/sendmsg and recv/recvmsg flags (sqe->ioprio)
......
...@@ -25,24 +25,30 @@ struct io_cancel { ...@@ -25,24 +25,30 @@ struct io_cancel {
}; };
#define CANCEL_FLAGS (IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_FD | \ #define CANCEL_FLAGS (IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_FD | \
IORING_ASYNC_CANCEL_ANY | IORING_ASYNC_CANCEL_FD_FIXED) IORING_ASYNC_CANCEL_ANY | IORING_ASYNC_CANCEL_FD_FIXED | \
IORING_ASYNC_CANCEL_USERDATA)
/* /*
* Returns true if the request matches the criteria outlined by 'cd'. * Returns true if the request matches the criteria outlined by 'cd'.
*/ */
bool io_cancel_req_match(struct io_kiocb *req, struct io_cancel_data *cd) bool io_cancel_req_match(struct io_kiocb *req, struct io_cancel_data *cd)
{ {
bool match_user_data = cd->flags & IORING_ASYNC_CANCEL_USERDATA;
if (req->ctx != cd->ctx) if (req->ctx != cd->ctx)
return false; return false;
if (cd->flags & IORING_ASYNC_CANCEL_ANY) {
if (!(cd->flags & (IORING_ASYNC_CANCEL_FD)))
match_user_data = true;
if (cd->flags & IORING_ASYNC_CANCEL_ANY)
goto check_seq; goto check_seq;
} else if (cd->flags & IORING_ASYNC_CANCEL_FD) { if (cd->flags & IORING_ASYNC_CANCEL_FD) {
if (req->file != cd->file) if (req->file != cd->file)
return false; return false;
} else {
if (req->cqe.user_data != cd->data)
return false;
} }
if (match_user_data && req->cqe.user_data != cd->data)
return false;
if (cd->flags & IORING_ASYNC_CANCEL_ALL) { if (cd->flags & IORING_ASYNC_CANCEL_ALL) {
check_seq: check_seq:
if (cd->seq == req->work.cancel_seq) if (cd->seq == req->work.cancel_seq)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment