diff options
author | Jens Axboe <axboe@kernel.dk> | 2020-04-03 14:55:49 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-04-03 14:55:49 -0600 |
commit | 7bd314cdd7a88ff53043f24d02f64cf9b89c023d (patch) | |
tree | b28d8655b744c8c34bfce1e4d93689e1f6e7710e /fs | |
parent | 08b24342b2c0f2661d7c3691f5369465e8c62ef6 (diff) | |
parent | 581f981034890dfd27be7e98946e8f0461f3967a (diff) | |
download | linux-next-7bd314cdd7a88ff53043f24d02f64cf9b89c023d.tar.gz |
Merge branch 'io_uring-5.7' into for-next
* io_uring-5.7:
io_uring: process requests completed with -EAGAIN on poll list
io_uring: remove bogus RLIMIT_NOFILE check in file registration
Diffstat (limited to 'fs')
-rw-r--r-- | fs/io_uring.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 2460c3333f70..78ae8e8ed5bf 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1744,11 +1744,24 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, io_free_req_many(ctx, &rb); } +static void io_iopoll_queue(struct list_head *again) +{ + struct io_kiocb *req; + + do { + req = list_first_entry(again, struct io_kiocb, list); + list_del(&req->list); + refcount_inc(&req->refs); + io_queue_async_work(req); + } while (!list_empty(again)); +} + static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, long min) { struct io_kiocb *req, *tmp; LIST_HEAD(done); + LIST_HEAD(again); bool spin; int ret; @@ -1763,9 +1776,9 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, struct kiocb *kiocb = &req->rw.kiocb; /* - * Move completed entries to our local list. If we find a - * request that requires polling, break out and complete - * the done list first, if we have entries there. + * Move completed and retryable entries to our local lists. + * If we find a request that requires polling, break out + * and complete those lists first, if we have entries there. */ if (req->flags & REQ_F_IOPOLL_COMPLETED) { list_move_tail(&req->list, &done); @@ -1774,6 +1787,13 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, if (!list_empty(&done)) break; + if (req->result == -EAGAIN) { + list_move_tail(&req->list, &again); + continue; + } + if (!list_empty(&again)) + break; + ret = kiocb->ki_filp->f_op->iopoll(kiocb, spin); if (ret < 0) break; @@ -1786,6 +1806,9 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events, if (!list_empty(&done)) io_iopoll_complete(ctx, nr_events, &done); + if (!list_empty(&again)) + io_iopoll_queue(&again); + return ret; } @@ -6216,13 +6239,6 @@ static int __io_sqe_files_scm(struct io_ring_ctx *ctx, int nr, int offset) struct sk_buff *skb; int i, nr_files; - if (!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) { - unsigned long inflight = ctx->user->unix_inflight + nr; - - if (inflight > task_rlimit(current, RLIMIT_NOFILE)) - return -EMFILE; - } - fpl = kzalloc(sizeof(*fpl), GFP_KERNEL); if (!fpl) return -ENOMEM; |