Skip to content

Commit b961f8d

Browse files
committed
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
2 parents a58dfea + 65a6543 commit b961f8d

File tree

3 files changed

+201
-241
lines changed

3 files changed

+201
-241
lines changed

fs/io-wq.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct io_wq {
111111
unsigned long state;
112112

113113
free_work_fn *free_work;
114+
io_wq_work_fn *do_work;
114115

115116
struct task_struct *manager;
116117
struct user_struct *user;
@@ -523,7 +524,7 @@ static void io_worker_handle_work(struct io_worker *worker)
523524

524525
hash = io_get_work_hash(work);
525526
linked = old_work = work;
526-
linked->func(&linked);
527+
wq->do_work(&linked);
527528
linked = (old_work == linked) ? NULL : linked;
528529

529530
work = next_hashed;
@@ -780,7 +781,7 @@ static void io_run_cancel(struct io_wq_work *work, struct io_wqe *wqe)
780781
struct io_wq_work *old_work = work;
781782

782783
work->flags |= IO_WQ_WORK_CANCEL;
783-
work->func(&work);
784+
wq->do_work(&work);
784785
work = (work == old_work) ? NULL : work;
785786
wq->free_work(old_work);
786787
} while (work);
@@ -1018,7 +1019,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10181019
int ret = -ENOMEM, node;
10191020
struct io_wq *wq;
10201021

1021-
if (WARN_ON_ONCE(!data->free_work))
1022+
if (WARN_ON_ONCE(!data->free_work || !data->do_work))
10221023
return ERR_PTR(-EINVAL);
10231024

10241025
wq = kzalloc(sizeof(*wq), GFP_KERNEL);
@@ -1032,6 +1033,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10321033
}
10331034

10341035
wq->free_work = data->free_work;
1036+
wq->do_work = data->do_work;
10351037

10361038
/* caller must already hold a reference to this */
10371039
wq->user = data->user;
@@ -1088,7 +1090,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10881090

10891091
bool io_wq_get(struct io_wq *wq, struct io_wq_data *data)
10901092
{
1091-
if (data->free_work != wq->free_work)
1093+
if (data->free_work != wq->free_work || data->do_work != wq->do_work)
10921094
return false;
10931095

10941096
return refcount_inc_not_zero(&wq->use_refs);

fs/io-wq.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ static inline void wq_list_del(struct io_wq_work_list *list,
8585

8686
struct io_wq_work {
8787
struct io_wq_work_node list;
88-
void (*func)(struct io_wq_work **);
8988
struct files_struct *files;
9089
struct mm_struct *mm;
9190
const struct cred *creds;
@@ -94,11 +93,6 @@ struct io_wq_work {
9493
pid_t task_pid;
9594
};
9695

97-
#define INIT_IO_WORK(work, _func) \
98-
do { \
99-
*(work) = (struct io_wq_work){ .func = _func }; \
100-
} while (0) \
101-
10296
static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
10397
{
10498
if (!work->list.next)
@@ -108,10 +102,12 @@ static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
108102
}
109103

110104
typedef void (free_work_fn)(struct io_wq_work *);
105+
typedef void (io_wq_work_fn)(struct io_wq_work **);
111106

112107
struct io_wq_data {
113108
struct user_struct *user;
114109

110+
io_wq_work_fn *do_work;
115111
free_work_fn *free_work;
116112
};
117113

0 commit comments

Comments
 (0)