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.h" 12 #include "statx.h" 13 14 struct io_statx { 15 struct file *file; 16 int dfd; 17 unsigned int mask; 18 unsigned int flags; 19 struct delayed_filename filename; 20 struct statx __user *buffer; 21 }; 22 23 int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 24 { 25 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 26 const char __user *path; 27 int ret; 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 ret = delayed_getname_uflags(&sx->filename, path, sx->flags); 41 42 if (unlikely(ret)) 43 return ret; 44 45 req->flags |= REQ_F_NEED_CLEANUP; 46 req->flags |= REQ_F_FORCE_ASYNC; 47 return 0; 48 } 49 50 int io_statx(struct io_kiocb *req, unsigned int issue_flags) 51 { 52 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 53 CLASS(filename_complete_delayed, name)(&sx->filename); 54 int ret; 55 56 WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 57 58 ret = do_statx(sx->dfd, name, sx->flags, sx->mask, sx->buffer); 59 io_req_set_res(req, ret, 0); 60 return IOU_COMPLETE; 61 } 62 63 void io_statx_cleanup(struct io_kiocb *req) 64 { 65 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 66 67 dismiss_delayed_filename(&sx->filename); 68 } 69