io_uring: cancel by ->task not pid
authorPavel Begunkov <asml.silence@gmail.com>
Mon, 15 Jun 2020 07:33:14 +0000 (10:33 +0300)
committerJens Axboe <axboe@kernel.dk>
Mon, 15 Jun 2020 14:51:38 +0000 (08:51 -0600)
For an exiting process it tries to cancel all its inflight requests. Use
req->task to match such instead of work.pid. We always have req->task
set, and it will be valid because we're matching only current exiting
task.

Also, remove work.pid and everything related, it's useless now.

Reported-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io-wq.h
fs/io_uring.c

index b72538f..071f1a9 100644 (file)
@@ -90,7 +90,6 @@ struct io_wq_work {
        const struct cred *creds;
        struct fs_struct *fs;
        unsigned flags;
-       pid_t task_pid;
 };
 
 static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
index 5f946eb..e17df66 100644 (file)
@@ -1063,8 +1063,6 @@ static inline void io_req_work_grab_env(struct io_kiocb *req,
                }
                spin_unlock(&current->fs->lock);
        }
-       if (!req->work.task_pid)
-               req->work.task_pid = task_pid_vnr(current);
 }
 
 static inline void io_req_work_drop_env(struct io_kiocb *req)
@@ -7451,11 +7449,12 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx,
        }
 }
 
-static bool io_cancel_pid_cb(struct io_wq_work *work, void *data)
+static bool io_cancel_task_cb(struct io_wq_work *work, void *data)
 {
-       pid_t pid = (pid_t) (unsigned long) data;
+       struct io_kiocb *req = container_of(work, struct io_kiocb, work);
+       struct task_struct *task = data;
 
-       return work->task_pid == pid;
+       return req->task == task;
 }
 
 static int io_uring_flush(struct file *file, void *data)
@@ -7467,11 +7466,8 @@ static int io_uring_flush(struct file *file, void *data)
        /*
         * If the task is going away, cancel work it may have pending
         */
-       if (fatal_signal_pending(current) || (current->flags & PF_EXITING)) {
-               void *data = (void *) (unsigned long)task_pid_vnr(current);
-
-               io_wq_cancel_cb(ctx->io_wq, io_cancel_pid_cb, data, true);
-       }
+       if (fatal_signal_pending(current) || (current->flags & PF_EXITING))
+               io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, current, true);
 
        return 0;
 }