xref: /openbmc/linux/io_uring/statx.c (revision aebb224f)
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