On 31/05/2020 19:15, Xiaoguang Wang wrote: > 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. It's not as bad, just the thing you poked is overused and don't have strict rules. I have a feeling, that for it to be done right it'd need more fundamental refactoring with putting everything related to ->work closer to io_queue_async_work(). > > 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. -- Pavel Begunkov