at v6.19-rc4 1.6 kB view raw
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 14struct 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 23int 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 28 if (sqe->buf_index || sqe->splice_fd_in) 29 return -EINVAL; 30 if (req->flags & REQ_F_FIXED_FILE) 31 return -EBADF; 32 33 sx->dfd = READ_ONCE(sqe->fd); 34 sx->mask = READ_ONCE(sqe->len); 35 path = u64_to_user_ptr(READ_ONCE(sqe->addr)); 36 sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2)); 37 sx->flags = READ_ONCE(sqe->statx_flags); 38 39 sx->filename = getname_uflags(path, sx->flags); 40 41 if (IS_ERR(sx->filename)) { 42 int ret = PTR_ERR(sx->filename); 43 44 sx->filename = NULL; 45 return ret; 46 } 47 48 req->flags |= REQ_F_NEED_CLEANUP; 49 req->flags |= REQ_F_FORCE_ASYNC; 50 return 0; 51} 52 53int io_statx(struct io_kiocb *req, unsigned int issue_flags) 54{ 55 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 56 int ret; 57 58 WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 59 60 ret = do_statx(sx->dfd, sx->filename, sx->flags, sx->mask, sx->buffer); 61 io_req_set_res(req, ret, 0); 62 return IOU_COMPLETE; 63} 64 65void io_statx_cleanup(struct io_kiocb *req) 66{ 67 struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx); 68 69 if (sx->filename) 70 putname(sx->filename); 71}