Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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 }