Skip to content

Commit 5b0bbee

Browse files
committed
io_uring: statx must grab the file table for valid fd
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: [email protected] # v5.6 Reported-by: Clay Harris <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 44575a6 commit 5b0bbee

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

fs/io_uring.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ enum {
524524
REQ_F_OVERFLOW_BIT,
525525
REQ_F_POLLED_BIT,
526526
REQ_F_BUFFER_SELECTED_BIT,
527+
REQ_F_NO_FILE_TABLE_BIT,
527528

528529
/* not a real bit, just to check we're not overflowing the space */
529530
__REQ_F_LAST_BIT,
@@ -577,6 +578,8 @@ enum {
577578
REQ_F_POLLED = BIT(REQ_F_POLLED_BIT),
578579
/* buffer already selected */
579580
REQ_F_BUFFER_SELECTED = BIT(REQ_F_BUFFER_SELECTED_BIT),
581+
/* doesn't need file table for this request */
582+
REQ_F_NO_FILE_TABLE = BIT(REQ_F_NO_FILE_TABLE_BIT),
580583
};
581584

582585
struct async_poll {
@@ -799,6 +802,7 @@ static const struct io_op_def io_op_defs[] = {
799802
.needs_file = 1,
800803
.fd_non_neg = 1,
801804
.needs_fs = 1,
805+
.file_table = 1,
802806
},
803807
[IORING_OP_READ] = {
804808
.needs_mm = 1,
@@ -3355,8 +3359,12 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock)
33553359
struct kstat stat;
33563360
int ret;
33573361

3358-
if (force_nonblock)
3362+
if (force_nonblock) {
3363+
/* only need file table for an actual valid fd */
3364+
if (ctx->dfd == -1 || ctx->dfd == AT_FDCWD)
3365+
req->flags |= REQ_F_NO_FILE_TABLE;
33593366
return -EAGAIN;
3367+
}
33603368

33613369
if (vfs_stat_set_lookup_flags(&lookup_flags, ctx->how.flags))
33623370
return -EINVAL;
@@ -5429,7 +5437,7 @@ static int io_grab_files(struct io_kiocb *req)
54295437
int ret = -EBADF;
54305438
struct io_ring_ctx *ctx = req->ctx;
54315439

5432-
if (req->work.files)
5440+
if (req->work.files || (req->flags & REQ_F_NO_FILE_TABLE))
54335441
return 0;
54345442
if (!ctx->ring_file)
54355443
return -EBADF;

0 commit comments

Comments
 (0)