>> diff --git a/fs/io_uring.c b/fs/io_uring.c >> index 12296ce3e8b9..2a3a02838f7b 100644 >> --- a/fs/io_uring.c >> +++ b/fs/io_uring.c >> @@ -907,9 +907,10 @@ static void io_file_put_work(struct work_struct *work); >> static inline void io_req_init_async(struct io_kiocb *req, >> void (*func)(struct io_wq_work **)) >> { >> - if (req->flags & REQ_F_WORK_INITIALIZED) >> - req->work.func = func; >> - else { >> + if (req->flags & REQ_F_WORK_INITIALIZED) { >> + if (!req->work.func) >> + req->work.func = func; >> + } else { >> req->work = (struct io_wq_work){ .func = func }; >> req->flags |= REQ_F_WORK_INITIALIZED; >> } >> @@ -2920,6 +2921,8 @@ static int __io_splice_prep(struct io_kiocb *req, >> return ret; >> req->flags |= REQ_F_NEED_CLEANUP; >> >> + /* Splice will be punted aync, so initialize io_wq_work firstly_*/ >> + io_req_init_async(req, io_wq_submit_work); >> if (!S_ISREG(file_inode(sp->file_in)->i_mode)) >> req->work.flags |= IO_WQ_WORK_UNBOUND; >> >> @@ -3592,6 +3595,9 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock) >> >> static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) >> { >> + /* Close may be punted aync, so initialize io_wq_work firstly */ >> + io_req_init_async(req, io_wq_submit_work); >> + > For splice and close requests, these two about io_req_init_async() calls should be > io_req_init_async(req, NULL), because they change req->work.flags firstly. Please no. Such assumptions/dependencies are prone to break. It'll get us subtle bugs in no time. BTW, why not io_wq_submit_work in place of NULL? -- Pavel Begunkov