diff options
author | Jens Axboe <axboe@kernel.dk> | 2020-12-14 10:57:13 -0700 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2021-01-25 18:07:29 -0700 |
commit | 4f63722b938e8a14d9f4b3f9e9a259a5e3f67f21 (patch) | |
tree | 19f204bacf08a2af529bad1faf5aacef39c8fa82 | |
parent | 8dde16ca7b0cd8d1715cb8c4f5d81419cc981fe7 (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.c | 21 |
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; } |