hi,
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?
In the begin of __io_splice_prep or io_close_prep, current io_uring mainline codes will
modify req->work.flags firstly, so we need to call io_req_init_async to initialize
io_wq_work before the work.flags modification.
For below codes:
static inline void io_req_init_async(struct io_kiocb *req,
void (*func)(struct io_wq_work **))
{
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;
}
}
if we not pass NULL to parameter 'func', e.g. pass io_wq_submit_work, then
we can not use io_req_init_async() to pass io_close_finish again.
Now I'm confused how to write better codes based on current io_uring mainline codes :)
If you have some free time, please have a deeper look, thanks.
Regards,
Xiaoguang Wang