--- /dev/null
+From 5b0bbee4732cbd58aa98213d4c11a366356bba3d Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Mon, 27 Apr 2020 10:41:22 -0600
+Subject: io_uring: statx must grab the file table for valid fd
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 5b0bbee4732cbd58aa98213d4c11a366356bba3d upstream.
+
+Clay reports that OP_STATX fails for a test case with a valid fd
+and empty path:
+
+ -- Test 0: statx:fd 3: SUCCEED, file mode 100755
+ -- Test 1: statx:path ./uring_statx: SUCCEED, file mode 100755
+ -- Test 2: io_uring_statx:fd 3: FAIL, errno 9: Bad file descriptor
+ -- Test 3: io_uring_statx:path ./uring_statx: SUCCEED, file mode 100755
+
+This is due to statx not grabbing the process file table, hence we can't
+lookup the fd in async context. If the fd is valid, ensure that we grab
+the file table so we can grab the file from async context.
+
+Cc: stable@vger.kernel.org # v5.6
+Reported-by: Clay Harris <bugs@claycon.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -479,6 +479,7 @@ enum {
+ REQ_F_COMP_LOCKED_BIT,
+ REQ_F_NEED_CLEANUP_BIT,
+ REQ_F_OVERFLOW_BIT,
++ REQ_F_NO_FILE_TABLE_BIT,
+ };
+
+ enum {
+@@ -521,6 +522,8 @@ enum {
+ REQ_F_NEED_CLEANUP = BIT(REQ_F_NEED_CLEANUP_BIT),
+ /* in overflow list */
+ REQ_F_OVERFLOW = BIT(REQ_F_OVERFLOW_BIT),
++ /* doesn't need file table for this request */
++ REQ_F_NO_FILE_TABLE = BIT(REQ_F_NO_FILE_TABLE_BIT),
+ };
+
+ /*
+@@ -711,6 +714,7 @@ static const struct io_op_def io_op_defs
+ .needs_file = 1,
+ .fd_non_neg = 1,
+ .needs_fs = 1,
++ .file_table = 1,
+ },
+ [IORING_OP_READ] = {
+ .needs_mm = 1,
+@@ -2843,8 +2847,12 @@ static int io_statx(struct io_kiocb *req
+ struct kstat stat;
+ int ret;
+
+- if (force_nonblock)
++ 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;
++ }
+
+ if (vfs_stat_set_lookup_flags(&lookup_flags, ctx->how.flags))
+ return -EINVAL;
+@@ -4632,7 +4640,7 @@ static int io_grab_files(struct io_kiocb
+ int ret = -EBADF;
+ struct io_ring_ctx *ctx = req->ctx;
+
+- if (req->work.files)
++ if (req->work.files || (req->flags & REQ_F_NO_FILE_TABLE))
+ return 0;
+ if (!ctx->ring_file)
+ return -EBADF;