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