Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / fs / io_uring.c
index c9aea6c..ccc259c 100644 (file)
@@ -3049,6 +3049,7 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,
        if (!wake_page_match(wpq, key))
                return 0;
 
+       req->rw.kiocb.ki_flags &= ~IOCB_WAITQ;
        list_del_init(&wait->entry);
 
        init_task_work(&req->task_work, io_req_task_submit);
@@ -3106,6 +3107,7 @@ static bool io_rw_should_retry(struct io_kiocb *req)
        wait->wait.flags = 0;
        INIT_LIST_HEAD(&wait->wait.entry);
        kiocb->ki_flags |= IOCB_WAITQ;
+       kiocb->ki_flags &= ~IOCB_NOWAIT;
        kiocb->ki_waitq = wait;
 
        io_get_req_task(req);
@@ -3172,10 +3174,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
                        goto done;
                /* some cases will consume bytes even on error returns */
                iov_iter_revert(iter, iov_count - iov_iter_count(iter));
-               ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false);
-               if (ret)
-                       goto out_free;
-               return -EAGAIN;
+               ret = 0;
+               goto copy_iov;
        } else if (ret < 0) {
                /* make sure -ERESTARTSYS -> -EINTR is done */
                goto done;
@@ -4745,6 +4745,8 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
        if (mask && !(mask & poll->events))
                return 0;
 
+       list_del_init(&wait->entry);
+
        if (poll && poll->head) {
                bool done;
 
@@ -5677,6 +5679,11 @@ static void __io_clean_op(struct io_kiocb *req)
                        io_put_file(req, req->splice.file_in,
                                    (req->splice.flags & SPLICE_F_FD_IN_FIXED));
                        break;
+               case IORING_OP_OPENAT:
+               case IORING_OP_OPENAT2:
+                       if (req->open.filename)
+                               putname(req->open.filename);
+                       break;
                }
                req->flags &= ~REQ_F_NEED_CLEANUP;
        }
@@ -6354,9 +6361,6 @@ static void io_submit_state_start(struct io_submit_state *state,
                                  struct io_ring_ctx *ctx, unsigned int max_ios)
 {
        blk_start_plug(&state->plug);
-#ifdef CONFIG_BLOCK
-       state->plug.nowait = true;
-#endif
        state->comp.nr = 0;
        INIT_LIST_HEAD(&state->comp.list);
        state->comp.ctx = ctx;
@@ -8418,11 +8422,19 @@ static int io_uring_show_cred(int id, void *p, void *data)
 
 static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
 {
+       bool has_lock;
        int i;
 
-       mutex_lock(&ctx->uring_lock);
+       /*
+        * Avoid ABBA deadlock between the seq lock and the io_uring mutex,
+        * since fdinfo case grabs it in the opposite direction of normal use
+        * cases. If we fail to get the lock, we just don't iterate any
+        * structures that could be going away outside the io_uring mutex.
+        */
+       has_lock = mutex_trylock(&ctx->uring_lock);
+
        seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files);
-       for (i = 0; i < ctx->nr_user_files; i++) {
+       for (i = 0; has_lock && i < ctx->nr_user_files; i++) {
                struct fixed_file_table *table;
                struct file *f;
 
@@ -8434,13 +8446,13 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
                        seq_printf(m, "%5u: <none>\n", i);
        }
        seq_printf(m, "UserBufs:\t%u\n", ctx->nr_user_bufs);
-       for (i = 0; i < ctx->nr_user_bufs; i++) {
+       for (i = 0; has_lock && i < ctx->nr_user_bufs; i++) {
                struct io_mapped_ubuf *buf = &ctx->user_bufs[i];
 
                seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf,
                                                (unsigned int) buf->len);
        }
-       if (!idr_is_empty(&ctx->personality_idr)) {
+       if (has_lock && !idr_is_empty(&ctx->personality_idr)) {
                seq_printf(m, "Personalities:\n");
                idr_for_each(&ctx->personality_idr, io_uring_show_cred, m);
        }
@@ -8455,7 +8467,8 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
                                        req->task->task_works != NULL);
        }
        spin_unlock_irq(&ctx->completion_lock);
-       mutex_unlock(&ctx->uring_lock);
+       if (has_lock)
+               mutex_unlock(&ctx->uring_lock);
 }
 
 static void io_uring_show_fdinfo(struct seq_file *m, struct file *f)