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/fs.h>
0005 #include <linux/file.h>
0006 #include <linux/mm.h>
0007 #include <linux/slab.h>
0008 #include <linux/namei.h>
0009 #include <linux/io_uring.h>
0010 
0011 #include <uapi/linux/fadvise.h>
0012 #include <uapi/linux/io_uring.h>
0013 
0014 #include "io_uring.h"
0015 #include "advise.h"
0016 
0017 struct io_fadvise {
0018     struct file         *file;
0019     u64             offset;
0020     u32             len;
0021     u32             advice;
0022 };
0023 
0024 struct io_madvise {
0025     struct file         *file;
0026     u64             addr;
0027     u32             len;
0028     u32             advice;
0029 };
0030 
0031 int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
0032 {
0033 #if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
0034     struct io_madvise *ma = io_kiocb_to_cmd(req, struct io_madvise);
0035 
0036     if (sqe->buf_index || sqe->off || sqe->splice_fd_in)
0037         return -EINVAL;
0038 
0039     ma->addr = READ_ONCE(sqe->addr);
0040     ma->len = READ_ONCE(sqe->len);
0041     ma->advice = READ_ONCE(sqe->fadvise_advice);
0042     return 0;
0043 #else
0044     return -EOPNOTSUPP;
0045 #endif
0046 }
0047 
0048 int io_madvise(struct io_kiocb *req, unsigned int issue_flags)
0049 {
0050 #if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
0051     struct io_madvise *ma = io_kiocb_to_cmd(req, struct io_madvise);
0052     int ret;
0053 
0054     if (issue_flags & IO_URING_F_NONBLOCK)
0055         return -EAGAIN;
0056 
0057     ret = do_madvise(current->mm, ma->addr, ma->len, ma->advice);
0058     io_req_set_res(req, ret, 0);
0059     return IOU_OK;
0060 #else
0061     return -EOPNOTSUPP;
0062 #endif
0063 }
0064 
0065 int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
0066 {
0067     struct io_fadvise *fa = io_kiocb_to_cmd(req, struct io_fadvise);
0068 
0069     if (sqe->buf_index || sqe->addr || sqe->splice_fd_in)
0070         return -EINVAL;
0071 
0072     fa->offset = READ_ONCE(sqe->off);
0073     fa->len = READ_ONCE(sqe->len);
0074     fa->advice = READ_ONCE(sqe->fadvise_advice);
0075     return 0;
0076 }
0077 
0078 int io_fadvise(struct io_kiocb *req, unsigned int issue_flags)
0079 {
0080     struct io_fadvise *fa = io_kiocb_to_cmd(req, struct io_fadvise);
0081     int ret;
0082 
0083     if (issue_flags & IO_URING_F_NONBLOCK) {
0084         switch (fa->advice) {
0085         case POSIX_FADV_NORMAL:
0086         case POSIX_FADV_RANDOM:
0087         case POSIX_FADV_SEQUENTIAL:
0088             break;
0089         default:
0090             return -EAGAIN;
0091         }
0092     }
0093 
0094     ret = vfs_fadvise(req->file, fa->offset, fa->len, fa->advice);
0095     if (ret < 0)
0096         req_set_fail(req);
0097     io_req_set_res(req, ret, 0);
0098     return IOU_OK;
0099 }