xref: /openbmc/linux/io_uring/advise.c (revision f4c163dd)
1*f4c163ddSJens Axboe // SPDX-License-Identifier: GPL-2.0
2*f4c163ddSJens Axboe #include <linux/kernel.h>
3*f4c163ddSJens Axboe #include <linux/errno.h>
4*f4c163ddSJens Axboe #include <linux/fs.h>
5*f4c163ddSJens Axboe #include <linux/file.h>
6*f4c163ddSJens Axboe #include <linux/mm.h>
7*f4c163ddSJens Axboe #include <linux/slab.h>
8*f4c163ddSJens Axboe #include <linux/namei.h>
9*f4c163ddSJens Axboe #include <linux/io_uring.h>
10*f4c163ddSJens Axboe 
11*f4c163ddSJens Axboe #include <uapi/linux/fadvise.h>
12*f4c163ddSJens Axboe #include <uapi/linux/io_uring.h>
13*f4c163ddSJens Axboe 
14*f4c163ddSJens Axboe #include "io_uring_types.h"
15*f4c163ddSJens Axboe #include "io_uring.h"
16*f4c163ddSJens Axboe #include "advise.h"
17*f4c163ddSJens Axboe 
18*f4c163ddSJens Axboe struct io_fadvise {
19*f4c163ddSJens Axboe 	struct file			*file;
20*f4c163ddSJens Axboe 	u64				offset;
21*f4c163ddSJens Axboe 	u32				len;
22*f4c163ddSJens Axboe 	u32				advice;
23*f4c163ddSJens Axboe };
24*f4c163ddSJens Axboe 
25*f4c163ddSJens Axboe struct io_madvise {
26*f4c163ddSJens Axboe 	struct file			*file;
27*f4c163ddSJens Axboe 	u64				addr;
28*f4c163ddSJens Axboe 	u32				len;
29*f4c163ddSJens Axboe 	u32				advice;
30*f4c163ddSJens Axboe };
31*f4c163ddSJens Axboe 
32*f4c163ddSJens Axboe int io_madvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
33*f4c163ddSJens Axboe {
34*f4c163ddSJens Axboe #if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
35*f4c163ddSJens Axboe 	struct io_madvise *ma = io_kiocb_to_cmd(req);
36*f4c163ddSJens Axboe 
37*f4c163ddSJens Axboe 	if (sqe->buf_index || sqe->off || sqe->splice_fd_in)
38*f4c163ddSJens Axboe 		return -EINVAL;
39*f4c163ddSJens Axboe 
40*f4c163ddSJens Axboe 	ma->addr = READ_ONCE(sqe->addr);
41*f4c163ddSJens Axboe 	ma->len = READ_ONCE(sqe->len);
42*f4c163ddSJens Axboe 	ma->advice = READ_ONCE(sqe->fadvise_advice);
43*f4c163ddSJens Axboe 	return 0;
44*f4c163ddSJens Axboe #else
45*f4c163ddSJens Axboe 	return -EOPNOTSUPP;
46*f4c163ddSJens Axboe #endif
47*f4c163ddSJens Axboe }
48*f4c163ddSJens Axboe 
49*f4c163ddSJens Axboe int io_madvise(struct io_kiocb *req, unsigned int issue_flags)
50*f4c163ddSJens Axboe {
51*f4c163ddSJens Axboe #if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
52*f4c163ddSJens Axboe 	struct io_madvise *ma = io_kiocb_to_cmd(req);
53*f4c163ddSJens Axboe 	int ret;
54*f4c163ddSJens Axboe 
55*f4c163ddSJens Axboe 	if (issue_flags & IO_URING_F_NONBLOCK)
56*f4c163ddSJens Axboe 		return -EAGAIN;
57*f4c163ddSJens Axboe 
58*f4c163ddSJens Axboe 	ret = do_madvise(current->mm, ma->addr, ma->len, ma->advice);
59*f4c163ddSJens Axboe 	io_req_set_res(req, ret, 0);
60*f4c163ddSJens Axboe 	return IOU_OK;
61*f4c163ddSJens Axboe #else
62*f4c163ddSJens Axboe 	return -EOPNOTSUPP;
63*f4c163ddSJens Axboe #endif
64*f4c163ddSJens Axboe }
65*f4c163ddSJens Axboe 
66*f4c163ddSJens Axboe int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
67*f4c163ddSJens Axboe {
68*f4c163ddSJens Axboe 	struct io_fadvise *fa = io_kiocb_to_cmd(req);
69*f4c163ddSJens Axboe 
70*f4c163ddSJens Axboe 	if (sqe->buf_index || sqe->addr || sqe->splice_fd_in)
71*f4c163ddSJens Axboe 		return -EINVAL;
72*f4c163ddSJens Axboe 
73*f4c163ddSJens Axboe 	fa->offset = READ_ONCE(sqe->off);
74*f4c163ddSJens Axboe 	fa->len = READ_ONCE(sqe->len);
75*f4c163ddSJens Axboe 	fa->advice = READ_ONCE(sqe->fadvise_advice);
76*f4c163ddSJens Axboe 	return 0;
77*f4c163ddSJens Axboe }
78*f4c163ddSJens Axboe 
79*f4c163ddSJens Axboe int io_fadvise(struct io_kiocb *req, unsigned int issue_flags)
80*f4c163ddSJens Axboe {
81*f4c163ddSJens Axboe 	struct io_fadvise *fa = io_kiocb_to_cmd(req);
82*f4c163ddSJens Axboe 	int ret;
83*f4c163ddSJens Axboe 
84*f4c163ddSJens Axboe 	if (issue_flags & IO_URING_F_NONBLOCK) {
85*f4c163ddSJens Axboe 		switch (fa->advice) {
86*f4c163ddSJens Axboe 		case POSIX_FADV_NORMAL:
87*f4c163ddSJens Axboe 		case POSIX_FADV_RANDOM:
88*f4c163ddSJens Axboe 		case POSIX_FADV_SEQUENTIAL:
89*f4c163ddSJens Axboe 			break;
90*f4c163ddSJens Axboe 		default:
91*f4c163ddSJens Axboe 			return -EAGAIN;
92*f4c163ddSJens Axboe 		}
93*f4c163ddSJens Axboe 	}
94*f4c163ddSJens Axboe 
95*f4c163ddSJens Axboe 	ret = vfs_fadvise(req->file, fa->offset, fa->len, fa->advice);
96*f4c163ddSJens Axboe 	if (ret < 0)
97*f4c163ddSJens Axboe 		req_set_fail(req);
98*f4c163ddSJens Axboe 	io_req_set_res(req, ret, 0);
99*f4c163ddSJens Axboe 	return IOU_OK;
100*f4c163ddSJens Axboe }
101