Linux Audio

Check our new training course

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