1e0da14deSJens Axboe // SPDX-License-Identifier: GPL-2.0
2e0da14deSJens Axboe #include <linux/kernel.h>
3e0da14deSJens Axboe #include <linux/errno.h>
4e0da14deSJens Axboe #include <linux/file.h>
5e0da14deSJens Axboe #include <linux/io_uring.h>
6e0da14deSJens Axboe
7e0da14deSJens Axboe #include <uapi/linux/io_uring.h>
8e0da14deSJens Axboe
9e0da14deSJens Axboe #include "../fs/internal.h"
10e0da14deSJens Axboe
11e0da14deSJens Axboe #include "io_uring.h"
12e0da14deSJens Axboe #include "statx.h"
13e0da14deSJens Axboe
14e0da14deSJens Axboe struct io_statx {
15e0da14deSJens Axboe struct file *file;
16e0da14deSJens Axboe int dfd;
17e0da14deSJens Axboe unsigned int mask;
18e0da14deSJens Axboe unsigned int flags;
19e0da14deSJens Axboe struct filename *filename;
20e0da14deSJens Axboe struct statx __user *buffer;
21e0da14deSJens Axboe };
22e0da14deSJens Axboe
io_statx_prep(struct io_kiocb * req,const struct io_uring_sqe * sqe)23e0da14deSJens Axboe int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
24e0da14deSJens Axboe {
25f2ccb5aeSStefan Metzmacher struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
26e0da14deSJens Axboe const char __user *path;
27e0da14deSJens Axboe
28e0da14deSJens Axboe if (sqe->buf_index || sqe->splice_fd_in)
29e0da14deSJens Axboe return -EINVAL;
30e0da14deSJens Axboe if (req->flags & REQ_F_FIXED_FILE)
31e0da14deSJens Axboe return -EBADF;
32e0da14deSJens Axboe
33e0da14deSJens Axboe sx->dfd = READ_ONCE(sqe->fd);
34e0da14deSJens Axboe sx->mask = READ_ONCE(sqe->len);
35e0da14deSJens Axboe path = u64_to_user_ptr(READ_ONCE(sqe->addr));
36e0da14deSJens Axboe sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
37e0da14deSJens Axboe sx->flags = READ_ONCE(sqe->statx_flags);
38e0da14deSJens Axboe
39e0da14deSJens Axboe sx->filename = getname_flags(path,
40e0da14deSJens Axboe getname_statx_lookup_flags(sx->flags),
41e0da14deSJens Axboe NULL);
42e0da14deSJens Axboe
43e0da14deSJens Axboe if (IS_ERR(sx->filename)) {
44e0da14deSJens Axboe int ret = PTR_ERR(sx->filename);
45e0da14deSJens Axboe
46e0da14deSJens Axboe sx->filename = NULL;
47e0da14deSJens Axboe return ret;
48e0da14deSJens Axboe }
49e0da14deSJens Axboe
50e0da14deSJens Axboe req->flags |= REQ_F_NEED_CLEANUP;
51*aebb224fSDylan Yudaken req->flags |= REQ_F_FORCE_ASYNC;
52e0da14deSJens Axboe return 0;
53e0da14deSJens Axboe }
54e0da14deSJens Axboe
io_statx(struct io_kiocb * req,unsigned int issue_flags)55e0da14deSJens Axboe int io_statx(struct io_kiocb *req, unsigned int issue_flags)
56e0da14deSJens Axboe {
57f2ccb5aeSStefan Metzmacher struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
58e0da14deSJens Axboe int ret;
59e0da14deSJens Axboe
60*aebb224fSDylan Yudaken WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
61e0da14deSJens Axboe
62e0da14deSJens Axboe ret = do_statx(sx->dfd, sx->filename, sx->flags, sx->mask, sx->buffer);
63e0da14deSJens Axboe io_req_set_res(req, ret, 0);
64e0da14deSJens Axboe return IOU_OK;
65e0da14deSJens Axboe }
66e0da14deSJens Axboe
io_statx_cleanup(struct io_kiocb * req)67e0da14deSJens Axboe void io_statx_cleanup(struct io_kiocb *req)
68e0da14deSJens Axboe {
69f2ccb5aeSStefan Metzmacher struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
70e0da14deSJens Axboe
71e0da14deSJens Axboe if (sx->filename)
72e0da14deSJens Axboe putname(sx->filename);
73e0da14deSJens Axboe }
74