io_uring: use AT_STATX_CACHED for IORING_OP_STATX fast path nonblock-path-lookup
authorJens Axboe <axboe@kernel.dk>
Mon, 14 Dec 2020 17:57:13 +0000 (10:57 -0700)
committerJens Axboe <axboe@kernel.dk>
Tue, 26 Jan 2021 01:07:29 +0000 (18:07 -0700)
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>
fs/io_uring.c

index 63050e17e75af4c5f16388ed9091a6209b13940c..71fafba41221b80f9b5cbc57749487d0ac118f93 100644 (file)
@@ -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;
 }