Merge tag 'io_uring-5.8-2020-06-11' of git://git.kernel.dk/linux-block
Pull io_uring fixes from Jens Axboe: "A few late stragglers in here. In particular: - Validate full range for provided buffers (Bijan) - Fix bad use of kfree() in buffer registration failure (Denis) - Don't allow close of ring itself, it's not fully safe. Making it fully safe would require making the system call more expensive, which isn't worth it. - Buffer selection fix - Regression fix for O_NONBLOCK retry - Make IORING_OP_ACCEPT honor O_NONBLOCK (Jiufei) - Restrict opcode handling for SQ/IOPOLL (Pavel) - io-wq work handling cleanups and improvements (Pavel, Xiaoguang) - IOPOLL race fix (Xiaoguang)" * tag 'io_uring-5.8-2020-06-11' of git://git.kernel.dk/linux-block: io_uring: fix io_kiocb.flags modification race in IOPOLL mode io_uring: check file O_NONBLOCK state for accept io_uring: avoid unnecessary io_wq_work copy for fast poll feature io_uring: avoid whole io_wq_work copy for requests completed inline io_uring: allow O_NONBLOCK async retry io_wq: add per-wq work handler instead of per work io_uring: don't arm a timeout through work.func io_uring: remove custom ->func handlers io_uring: don't derive close state from ->func io_uring: use kvfree() in io_sqe_buffer_register() io_uring: validate the full range of provided buffers for access io_uring: re-set iov base/len for buffer select retry io_uring: move send/recv IOPOLL check into prep io_uring: deduplicate io_openat{,2}_prep() io_uring: do build_open_how() only once io_uring: fix {SQ,IO}POLL with unsupported opcodes io_uring: disallow close of ring itself
This commit is contained in:
10
fs/io-wq.c
10
fs/io-wq.c
@@ -111,6 +111,7 @@ struct io_wq {
|
||||
unsigned long state;
|
||||
|
||||
free_work_fn *free_work;
|
||||
io_wq_work_fn *do_work;
|
||||
|
||||
struct task_struct *manager;
|
||||
struct user_struct *user;
|
||||
@@ -523,7 +524,7 @@ get_next:
|
||||
|
||||
hash = io_get_work_hash(work);
|
||||
linked = old_work = work;
|
||||
linked->func(&linked);
|
||||
wq->do_work(&linked);
|
||||
linked = (old_work == linked) ? NULL : linked;
|
||||
|
||||
work = next_hashed;
|
||||
@@ -780,7 +781,7 @@ static void io_run_cancel(struct io_wq_work *work, struct io_wqe *wqe)
|
||||
struct io_wq_work *old_work = work;
|
||||
|
||||
work->flags |= IO_WQ_WORK_CANCEL;
|
||||
work->func(&work);
|
||||
wq->do_work(&work);
|
||||
work = (work == old_work) ? NULL : work;
|
||||
wq->free_work(old_work);
|
||||
} while (work);
|
||||
@@ -1018,7 +1019,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
|
||||
int ret = -ENOMEM, node;
|
||||
struct io_wq *wq;
|
||||
|
||||
if (WARN_ON_ONCE(!data->free_work))
|
||||
if (WARN_ON_ONCE(!data->free_work || !data->do_work))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
wq = kzalloc(sizeof(*wq), GFP_KERNEL);
|
||||
@@ -1032,6 +1033,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
|
||||
}
|
||||
|
||||
wq->free_work = data->free_work;
|
||||
wq->do_work = data->do_work;
|
||||
|
||||
/* caller must already hold a reference to this */
|
||||
wq->user = data->user;
|
||||
@@ -1088,7 +1090,7 @@ err:
|
||||
|
||||
bool io_wq_get(struct io_wq *wq, struct io_wq_data *data)
|
||||
{
|
||||
if (data->free_work != wq->free_work)
|
||||
if (data->free_work != wq->free_work || data->do_work != wq->do_work)
|
||||
return false;
|
||||
|
||||
return refcount_inc_not_zero(&wq->use_refs);
|
||||
|
Reference in New Issue
Block a user