summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2020-12-14 10:57:13 -0700
committerJens Axboe <axboe@kernel.dk>2021-01-25 18:07:29 -0700
commit4f63722b938e8a14d9f4b3f9e9a259a5e3f67f21 (patch)
tree19f204bacf08a2af529bad1faf5aacef39c8fa82
parent8dde16ca7b0cd8d1715cb8c4f5d81419cc981fe7 (diff)
io_uring: use AT_STATX_CACHED for IORING_OP_STATX fast pathnonblock-path-lookup
Instead of always going async, we can now attempt a cached attempt by using AT_STATX_CACHED. This turns into LOOKUP_CACHED, and ensures that we'll only do a fast path dentry lookup for path resolution. Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--fs/io_uring.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 63050e17e75a..71fafba41221 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -4452,20 +4452,27 @@ static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
static int io_statx(struct io_kiocb *req, bool force_nonblock)
{
struct io_statx *ctx = &req->statx;
+ bool cached_set;
int ret;
- if (force_nonblock) {
- /* only need file table for an actual valid fd */
- if (ctx->dfd == -1 || ctx->dfd == AT_FDCWD)
- req->flags |= REQ_F_NO_FILE_TABLE;
- return -EAGAIN;
- }
+ cached_set = ctx->flags & AT_STATX_CACHED;
+ if (force_nonblock)
+ ctx->flags |= AT_STATX_CACHED;
ret = do_statx(ctx->dfd, ctx->filename, ctx->flags, ctx->mask,
ctx->buffer);
- if (ret < 0)
+ if (ret < 0) {
+ /* only retry if nonblock wasn't set */
+ if (ret == -EAGAIN && (!cached_set && force_nonblock)) {
+ /* only need file table for an actual valid fd */
+ if (ctx->dfd == -1 || ctx->dfd == AT_FDCWD)
+ req->flags |= REQ_F_NO_FILE_TABLE;
+ ctx->flags &= ~AT_STATX_CACHED;
+ return -EAGAIN;
+ }
req_set_fail_links(req);
+ }
io_req_complete(req, ret);
return 0;
}