Line data Source code
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 filename *filename; 20 : struct statx __user *buffer; 21 : }; 22 : 23 0 : int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 24 : { 25 0 : struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 26 : const char __user *path; 27 : 28 0 : if (sqe->buf_index || sqe->splice_fd_in) 29 : return -EINVAL; 30 0 : if (req->flags & REQ_F_FIXED_FILE) 31 : return -EBADF; 32 : 33 0 : sx->dfd = READ_ONCE(sqe->fd); 34 0 : sx->mask = READ_ONCE(sqe->len); 35 0 : path = u64_to_user_ptr(READ_ONCE(sqe->addr)); 36 0 : sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2)); 37 0 : sx->flags = READ_ONCE(sqe->statx_flags); 38 : 39 0 : sx->filename = getname_flags(path, 40 : getname_statx_lookup_flags(sx->flags), 41 : NULL); 42 : 43 0 : if (IS_ERR(sx->filename)) { 44 0 : int ret = PTR_ERR(sx->filename); 45 : 46 0 : sx->filename = NULL; 47 0 : return ret; 48 : } 49 : 50 0 : req->flags |= REQ_F_NEED_CLEANUP; 51 0 : req->flags |= REQ_F_FORCE_ASYNC; 52 0 : return 0; 53 : } 54 : 55 0 : int io_statx(struct io_kiocb *req, unsigned int issue_flags) 56 : { 57 0 : struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 58 : int ret; 59 : 60 0 : WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 61 : 62 0 : ret = do_statx(sx->dfd, sx->filename, sx->flags, sx->mask, sx->buffer); 63 0 : io_req_set_res(req, ret, 0); 64 0 : return IOU_OK; 65 : } 66 : 67 0 : void io_statx_cleanup(struct io_kiocb *req) 68 : { 69 0 : struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 70 : 71 0 : if (sx->filename) 72 0 : putname(sx->filename); 73 0 : }