All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@kernel.dk>
To: linux-fsdevel@vger.kernel.org
Cc: torvalds@linux-foundation.org, viro@zeniv.linux.org.uk,
	Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 4/4] io_uring: enable LOOKUP_NONBLOCK path resolution for filename lookups
Date: Mon, 14 Dec 2020 12:13:24 -0700	[thread overview]
Message-ID: <20201214191323.173773-5-axboe@kernel.dk> (raw)
In-Reply-To: <20201214191323.173773-1-axboe@kernel.dk>

Instead of being pessimistic and assume that path lookup will block, use
LOOKUP_NONBLOCK to attempt just a cached lookup. This ensures that the
fast path is always done inline, and we only punt to async context if
IO is needed to satisfy the lookup.

For forced nonblock open attempts, mark the file O_NONBLOCK over the
actual ->open() call as well. We can safely clear this again before
doing fd_install(), so it'll never be user visible that we fiddled with
it.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 fs/io_uring.c | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 9d7baf8ba77a..6734a2616990 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -487,7 +487,6 @@ struct io_sr_msg {
 struct io_open {
 	struct file			*file;
 	int				dfd;
-	bool				ignore_nonblock;
 	struct filename			*filename;
 	struct open_how			how;
 	unsigned long			nofile;
@@ -3998,7 +3997,6 @@ static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
 		return ret;
 	}
 	req->open.nofile = rlimit(RLIMIT_NOFILE);
-	req->open.ignore_nonblock = false;
 	req->flags |= REQ_F_NEED_CLEANUP;
 	return 0;
 }
@@ -4040,39 +4038,45 @@ static int io_openat2(struct io_kiocb *req, bool force_nonblock)
 {
 	struct open_flags op;
 	struct file *file;
+	bool nonblock_set;
 	int ret;
 
-	if (force_nonblock && !req->open.ignore_nonblock)
-		return -EAGAIN;
-
 	ret = build_open_flags(&req->open.how, &op);
 	if (ret)
 		goto err;
+	nonblock_set = op.open_flag & O_NONBLOCK;
+	if (force_nonblock) {
+		/*
+		 * Don't bother trying for O_TRUNC or O_CREAT open, it'll
+		 * always -EAGAIN
+		 */
+		if (req->open.how.flags & (O_TRUNC | O_CREAT))
+			return -EAGAIN;
+		op.lookup_flags |= LOOKUP_NONBLOCK;
+		op.open_flag |= O_NONBLOCK;
+	}
 
 	ret = __get_unused_fd_flags(req->open.how.flags, req->open.nofile);
 	if (ret < 0)
 		goto err;
 
 	file = do_filp_open(req->open.dfd, req->open.filename, &op);
+	if (force_nonblock && file == ERR_PTR(-EAGAIN)) {
+		/*
+		 * We could hang on to this 'fd', but seems like marginal
+		 * gain for something that is now known to be a slower path.
+		 * So just put it, and we'll get a new one when we retry.
+		 */
+		put_unused_fd(ret);
+		return -EAGAIN;
+	}
+
 	if (IS_ERR(file)) {
 		put_unused_fd(ret);
 		ret = PTR_ERR(file);
-		/*
-		 * A work-around to ensure that /proc/self works that way
-		 * that it should - if we get -EOPNOTSUPP back, then assume
-		 * that proc_self_get_link() failed us because we're in async
-		 * context. We should be safe to retry this from the task
-		 * itself with force_nonblock == false set, as it should not
-		 * block on lookup. Would be nice to know this upfront and
-		 * avoid the async dance, but doesn't seem feasible.
-		 */
-		if (ret == -EOPNOTSUPP && io_wq_current_is_worker()) {
-			req->open.ignore_nonblock = true;
-			refcount_inc(&req->refs);
-			io_req_task_queue(req);
-			return 0;
-		}
 	} else {
+		if (force_nonblock && !nonblock_set)
+			file->f_flags &= ~O_NONBLOCK;
 		fsnotify_open(file);
 		fd_install(ret, file);
 	}
-- 
2.29.2


  parent reply	other threads:[~2020-12-14 19:14 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-14 19:13 [PATCHSET v3 0/4] fs: Support for LOOKUP_NONBLOCK / RESOLVE_NONBLOCK Jens Axboe
2020-12-14 19:13 ` [PATCH 1/4] fs: make unlazy_walk() error handling consistent Jens Axboe
2020-12-14 19:13 ` [PATCH 2/4] fs: add support for LOOKUP_NONBLOCK Jens Axboe
2020-12-15 12:24   ` Matthew Wilcox
2020-12-15 15:29     ` Jens Axboe
2020-12-15 15:33       ` Matthew Wilcox
2020-12-15 15:37         ` Jens Axboe
2020-12-15 16:08           ` Jens Axboe
2020-12-15 16:14             ` Jens Axboe
2020-12-15 18:29             ` Linus Torvalds
2020-12-15 18:44               ` Jens Axboe
2020-12-15 18:47                 ` Linus Torvalds
2020-12-15 19:03                   ` Jens Axboe
2020-12-15 19:32                     ` Linus Torvalds
2020-12-15 19:38                       ` Jens Axboe
2020-12-16  2:36   ` Al Viro
2020-12-16  3:30     ` Jens Axboe
2020-12-16  2:43   ` Al Viro
2020-12-16  3:32     ` Jens Axboe
2020-12-14 19:13 ` [PATCH 3/4] fs: expose LOOKUP_NONBLOCK through openat2() RESOLVE_NONBLOCK Jens Axboe
2020-12-15 22:25   ` Dave Chinner
2020-12-15 22:31     ` Linus Torvalds
2020-12-15 23:25       ` Jens Axboe
2020-12-16  2:37   ` Al Viro
2020-12-16  3:39     ` Linus Torvalds
2020-12-14 19:13 ` Jens Axboe [this message]
2020-12-15  3:06 ` [PATCHSET v3 0/4] fs: Support for LOOKUP_NONBLOCK / RESOLVE_NONBLOCK Linus Torvalds
2020-12-15  3:18   ` Jens Axboe
2020-12-15  6:11 ` Al Viro
2020-12-15 15:29   ` Jens Axboe
2021-01-04  5:31 ` Al Viro
2021-01-04 14:43   ` Jens Axboe
2021-01-04 16:54     ` Al Viro
2021-01-04 17:03       ` Jens Axboe
     [not found] ` <m1lfbrwrgq.fsf@fess.ebiederm.org>
2021-02-14 16:38   ` [PATCHSET v3 0/4] fs: Support for LOOKUP_NONBLOCK / RESOLVE_NONBLOCK (Insufficiently faking current?) Jens Axboe
2021-02-14 20:30     ` Linus Torvalds
2021-02-14 21:24       ` Al Viro
2021-02-15 18:07       ` Eric W. Biederman
2021-02-15 18:24         ` Jens Axboe
2021-02-15 21:09           ` Jens Axboe
2021-02-15 22:41             ` Eric W. Biederman
2021-02-16  2:41               ` Jens Axboe
2021-02-17  1:18                 ` Jens Axboe
2021-02-17  1:26                   ` Jens Axboe
2021-02-17  3:11                     ` Jens Axboe
2021-02-15 17:56     ` Eric W. Biederman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201214191323.173773-5-axboe@kernel.dk \
    --to=axboe@kernel.dk \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.