@@ -6348,7 +6348,8 @@ static struct io_kiocb *io_poll_file_find(struct io_ring_ctx *ctx,
63486348
63496349 list = & ctx -> cancel_hash [i ];
63506350 hlist_for_each_entry (req , list , hash_node ) {
6351- if (req -> file != cd -> file )
6351+ if (!(cd -> flags & IORING_ASYNC_CANCEL_ANY ) &&
6352+ req -> file != cd -> file )
63526353 continue ;
63536354 if (cd -> seq == req -> work .cancel_seq )
63546355 continue ;
@@ -6374,7 +6375,7 @@ static int io_poll_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd)
63746375{
63756376 struct io_kiocb * req ;
63766377
6377- if (cd -> flags & IORING_ASYNC_CANCEL_FD )
6378+ if (cd -> flags & ( IORING_ASYNC_CANCEL_FD | IORING_ASYNC_CANCEL_ANY ) )
63786379 req = io_poll_file_find (ctx , cd );
63796380 else
63806381 req = io_poll_find (ctx , false, cd );
@@ -6543,9 +6544,10 @@ static struct io_kiocb *io_timeout_extract(struct io_ring_ctx *ctx,
65436544 bool found = false;
65446545
65456546 list_for_each_entry (req , & ctx -> timeout_list , timeout .list ) {
6546- if (cd -> data != req -> cqe .user_data )
6547+ if (!(cd -> flags & IORING_ASYNC_CANCEL_ANY ) &&
6548+ cd -> data != req -> cqe .user_data )
65476549 continue ;
6548- if (cd -> flags & IORING_ASYNC_CANCEL_ALL ) {
6550+ if (cd -> flags & ( IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_ANY ) ) {
65496551 if (cd -> seq == req -> work .cancel_seq )
65506552 continue ;
65516553 req -> work .cancel_seq = cd -> seq ;
@@ -6827,14 +6829,16 @@ static bool io_cancel_cb(struct io_wq_work *work, void *data)
68276829
68286830 if (req -> ctx != cd -> ctx )
68296831 return false;
6830- if (cd -> flags & IORING_ASYNC_CANCEL_FD ) {
6832+ if (cd -> flags & IORING_ASYNC_CANCEL_ANY ) {
6833+ ;
6834+ } else if (cd -> flags & IORING_ASYNC_CANCEL_FD ) {
68316835 if (req -> file != cd -> file )
68326836 return false;
68336837 } else {
68346838 if (req -> cqe .user_data != cd -> data )
68356839 return false;
68366840 }
6837- if (cd -> flags & IORING_ASYNC_CANCEL_ALL ) {
6841+ if (cd -> flags & ( IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_ANY ) ) {
68386842 if (cd -> seq == req -> work .cancel_seq )
68396843 return false;
68406844 req -> work .cancel_seq = cd -> seq ;
@@ -6847,12 +6851,13 @@ static int io_async_cancel_one(struct io_uring_task *tctx,
68476851{
68486852 enum io_wq_cancel cancel_ret ;
68496853 int ret = 0 ;
6854+ bool all ;
68506855
68516856 if (!tctx || !tctx -> io_wq )
68526857 return - ENOENT ;
68536858
6854- cancel_ret = io_wq_cancel_cb ( tctx -> io_wq , io_cancel_cb , cd ,
6855- cd -> flags & IORING_ASYNC_CANCEL_ALL );
6859+ all = cd -> flags & ( IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_ANY );
6860+ cancel_ret = io_wq_cancel_cb ( tctx -> io_wq , io_cancel_cb , cd , all );
68566861 switch (cancel_ret ) {
68576862 case IO_WQ_CANCEL_OK :
68586863 ret = 0 ;
@@ -6894,6 +6899,9 @@ static int io_try_cancel(struct io_kiocb *req, struct io_cancel_data *cd)
68946899 return ret ;
68956900}
68966901
6902+ #define CANCEL_FLAGS (IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_FD | \
6903+ IORING_ASYNC_CANCEL_ANY)
6904+
68976905static int io_async_cancel_prep (struct io_kiocb * req ,
68986906 const struct io_uring_sqe * sqe )
68996907{
@@ -6906,18 +6914,21 @@ static int io_async_cancel_prep(struct io_kiocb *req,
69066914
69076915 req -> cancel .addr = READ_ONCE (sqe -> addr );
69086916 req -> cancel .flags = READ_ONCE (sqe -> cancel_flags );
6909- if (req -> cancel .flags & ~( IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_FD ) )
6917+ if (req -> cancel .flags & ~CANCEL_FLAGS )
69106918 return - EINVAL ;
6911- if (req -> cancel .flags & IORING_ASYNC_CANCEL_FD )
6919+ if (req -> cancel .flags & IORING_ASYNC_CANCEL_FD ) {
6920+ if (req -> cancel .flags & IORING_ASYNC_CANCEL_ANY )
6921+ return - EINVAL ;
69126922 req -> cancel .fd = READ_ONCE (sqe -> fd );
6923+ }
69136924
69146925 return 0 ;
69156926}
69166927
69176928static int __io_async_cancel (struct io_cancel_data * cd , struct io_kiocb * req ,
69186929 unsigned int issue_flags )
69196930{
6920- bool cancel_all = cd -> flags & IORING_ASYNC_CANCEL_ALL ;
6931+ bool all = cd -> flags & ( IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_ANY ) ;
69216932 struct io_ring_ctx * ctx = cd -> ctx ;
69226933 struct io_tctx_node * node ;
69236934 int ret , nr = 0 ;
@@ -6926,7 +6937,7 @@ static int __io_async_cancel(struct io_cancel_data *cd, struct io_kiocb *req,
69266937 ret = io_try_cancel (req , cd );
69276938 if (ret == - ENOENT )
69286939 break ;
6929- if (!cancel_all )
6940+ if (!all )
69306941 return ret ;
69316942 nr ++ ;
69326943 } while (1 );
@@ -6939,13 +6950,13 @@ static int __io_async_cancel(struct io_cancel_data *cd, struct io_kiocb *req,
69396950
69406951 ret = io_async_cancel_one (tctx , cd );
69416952 if (ret != - ENOENT ) {
6942- if (!cancel_all )
6953+ if (!all )
69436954 break ;
69446955 nr ++ ;
69456956 }
69466957 }
69476958 io_ring_submit_unlock (ctx , issue_flags );
6948- return cancel_all ? nr : ret ;
6959+ return all ? nr : ret ;
69496960}
69506961
69516962static int io_async_cancel (struct io_kiocb * req , unsigned int issue_flags )
0 commit comments