History

io_uring: add support for IORING_OP_STATX

This provides support for async statx(2) through io_uring.

Jens Axboe committed 6 years ago

Commit eddc7ef1 parent 3934e362 files · +87 −1Browse files

Unified · Split

2 files
  1. fs/io_uring.c +85 −1
  2. include/uapi/linux/io_uring.h +2 −0
fs/io_uring.c+85−1
@@ -379,9 +379,13 @@ struct io_sr_msg { · 378 unmodified lines
379379 struct io_open {
380380 struct file *file;
381381 int dfd;
382− umode_t mode;
382+ union {
383+ umode_t mode;
384+ unsigned mask;
385+ };
383386 const char __user *fname;
384387 struct filename *filename;
388+ struct statx __user *buffer;
385389 int flags;
386390 };
387391
@@ -2266,6 +2270,74 @@ err: · 1878 unmodified lines
22662270 return 0;
22672271 }
22682272
2273+static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
2274+{
2275+ unsigned lookup_flags;
2276+ int ret;
2277+
2278+ if (sqe->ioprio || sqe->buf_index)
2279+ return -EINVAL;
2280+
2281+ req->open.dfd = READ_ONCE(sqe->fd);
2282+ req->open.mask = READ_ONCE(sqe->len);
2283+ req->open.fname = u64_to_user_ptr(READ_ONCE(sqe->addr));
2284+ req->open.buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
2285+ req->open.flags = READ_ONCE(sqe->statx_flags);
2286+
2287+ if (vfs_stat_set_lookup_flags(&lookup_flags, req->open.flags))
2288+ return -EINVAL;
2289+
2290+ req->open.filename = getname_flags(req->open.fname, lookup_flags, NULL);
2291+ if (IS_ERR(req->open.filename)) {
2292+ ret = PTR_ERR(req->open.filename);
2293+ req->open.filename = NULL;
2294+ return ret;
2295+ }
2296+
2297+ return 0;
2298+}
2299+
2300+static int io_statx(struct io_kiocb *req, struct io_kiocb **nxt,
2301+ bool force_nonblock)
2302+{
2303+ struct io_open *ctx = &req->open;
2304+ unsigned lookup_flags;
2305+ struct path path;
2306+ struct kstat stat;
2307+ int ret;
2308+
2309+ if (force_nonblock)
2310+ return -EAGAIN;
2311+
2312+ if (vfs_stat_set_lookup_flags(&lookup_flags, ctx->flags))
2313+ return -EINVAL;
2314+
2315+retry:
2316+ /* filename_lookup() drops it, keep a reference */
2317+ ctx->filename->refcnt++;
2318+
2319+ ret = filename_lookup(ctx->dfd, ctx->filename, lookup_flags, &path,
2320+ NULL);
2321+ if (ret)
2322+ goto err;
2323+
2324+ ret = vfs_getattr(&path, &stat, ctx->mask, ctx->flags);
2325+ path_put(&path);
2326+ if (retry_estale(ret, lookup_flags)) {
2327+ lookup_flags |= LOOKUP_REVAL;
2328+ goto retry;
2329+ }
2330+ if (!ret)
2331+ ret = cp_statx(&stat, ctx->buffer);
2332+err:
2333+ putname(ctx->filename);
2334+ if (ret < 0)
2335+ req_set_fail_links(req);
2336+ io_cqring_add_event(req, ret);
2337+ io_put_req_find_next(req, nxt);
2338+ return 0;
2339+}
2340+
22692341 static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
22702342 {
22712343 /*
@@ -3427,6 +3499,9 @@ static int io_req_defer_prep(struct io_kiocb *req, · 1155 unmodified lines
34273499 case IORING_OP_FILES_UPDATE:
34283500 ret = io_files_update_prep(req, sqe);
34293501 break;
3502+ case IORING_OP_STATX:
3503+ ret = io_statx_prep(req, sqe);
3504+ break;
34303505 default:
34313506 printk_once(KERN_WARNING "io_uring: unhandled opcode %d\n",
34323507 req->opcode);
@@ -3613,6 +3688,14 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 180 unmodified lines
36133688 }
36143689 ret = io_files_update(req, force_nonblock);
36153690 break;
3691+ case IORING_OP_STATX:
3692+ if (sqe) {
3693+ ret = io_statx_prep(req, sqe);
3694+ if (ret)
3695+ break;
3696+ }
3697+ ret = io_statx(req, nxt, force_nonblock);
3698+ break;
36163699 default:
36173700 ret = -EINVAL;
36183701 break;
@@ -3699,6 +3782,7 @@ static int io_req_needs_file(struct io_kiocb *req, int fd) · 80 unmodified lines
36993782 case IORING_OP_LINK_TIMEOUT:
37003783 return 0;
37013784 case IORING_OP_OPENAT:
3785+ case IORING_OP_STATX:
37023786 return fd != -1;
37033787 default:
37043788 if (io_req_op_valid(req->opcode))
include/uapi/linux/io_uring.h+2−0
@@ -35,6 +35,7 @@ struct io_uring_sqe { · 34 unmodified lines
3535 __u32 accept_flags;
3636 __u32 cancel_flags;
3737 __u32 open_flags;
38+ __u32 statx_flags;
3839 };
3940 __u64 user_data; /* data to be passed back at completion time */
4041 union {
@@ -81,6 +82,7 @@ enum { · 40 unmodified lines
8182 IORING_OP_OPENAT,
8283 IORING_OP_CLOSE,
8384 IORING_OP_FILES_UPDATE,
85+ IORING_OP_STATX,
8486
8587 /* this goes last, obviously */
8688 IORING_OP_LAST,