0001
0002 #include <linux/kernel.h>
0003 #include <linux/errno.h>
0004 #include <linux/file.h>
0005 #include <linux/io_uring.h>
0006
0007 #include <uapi/linux/io_uring.h>
0008
0009 #include "../fs/internal.h"
0010
0011 #include "io_uring.h"
0012 #include "statx.h"
0013
0014 struct io_statx {
0015 struct file *file;
0016 int dfd;
0017 unsigned int mask;
0018 unsigned int flags;
0019 struct filename *filename;
0020 struct statx __user *buffer;
0021 };
0022
0023 int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
0024 {
0025 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
0026 const char __user *path;
0027
0028 if (sqe->buf_index || sqe->splice_fd_in)
0029 return -EINVAL;
0030 if (req->flags & REQ_F_FIXED_FILE)
0031 return -EBADF;
0032
0033 sx->dfd = READ_ONCE(sqe->fd);
0034 sx->mask = READ_ONCE(sqe->len);
0035 path = u64_to_user_ptr(READ_ONCE(sqe->addr));
0036 sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
0037 sx->flags = READ_ONCE(sqe->statx_flags);
0038
0039 sx->filename = getname_flags(path,
0040 getname_statx_lookup_flags(sx->flags),
0041 NULL);
0042
0043 if (IS_ERR(sx->filename)) {
0044 int ret = PTR_ERR(sx->filename);
0045
0046 sx->filename = NULL;
0047 return ret;
0048 }
0049
0050 req->flags |= REQ_F_NEED_CLEANUP;
0051 return 0;
0052 }
0053
0054 int io_statx(struct io_kiocb *req, unsigned int issue_flags)
0055 {
0056 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
0057 int ret;
0058
0059 if (issue_flags & IO_URING_F_NONBLOCK)
0060 return -EAGAIN;
0061
0062 ret = do_statx(sx->dfd, sx->filename, sx->flags, sx->mask, sx->buffer);
0063 io_req_set_res(req, ret, 0);
0064 return IOU_OK;
0065 }
0066
0067 void io_statx_cleanup(struct io_kiocb *req)
0068 {
0069 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
0070
0071 if (sx->filename)
0072 putname(sx->filename);
0073 }