0001
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 }