Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/io_uring/advise.c
25923 views
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
17
struct io_fadvise {
18
struct file *file;
19
u64 offset;
20
u64 len;
21
u32 advice;
22
};
23
24
struct io_madvise {
25
struct file *file;
26
u64 addr;
27
u64 len;
28
u32 advice;
29
};
30
31
int 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->splice_fd_in)
37
return -EINVAL;
38
39
ma->addr = READ_ONCE(sqe->addr);
40
ma->len = READ_ONCE(sqe->off);
41
if (!ma->len)
42
ma->len = READ_ONCE(sqe->len);
43
ma->advice = READ_ONCE(sqe->fadvise_advice);
44
req->flags |= REQ_F_FORCE_ASYNC;
45
return 0;
46
#else
47
return -EOPNOTSUPP;
48
#endif
49
}
50
51
int io_madvise(struct io_kiocb *req, unsigned int issue_flags)
52
{
53
#if defined(CONFIG_ADVISE_SYSCALLS) && defined(CONFIG_MMU)
54
struct io_madvise *ma = io_kiocb_to_cmd(req, struct io_madvise);
55
int ret;
56
57
WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
58
59
ret = do_madvise(current->mm, ma->addr, ma->len, ma->advice);
60
io_req_set_res(req, ret, 0);
61
return IOU_COMPLETE;
62
#else
63
return -EOPNOTSUPP;
64
#endif
65
}
66
67
static bool io_fadvise_force_async(struct io_fadvise *fa)
68
{
69
switch (fa->advice) {
70
case POSIX_FADV_NORMAL:
71
case POSIX_FADV_RANDOM:
72
case POSIX_FADV_SEQUENTIAL:
73
return false;
74
default:
75
return true;
76
}
77
}
78
79
int io_fadvise_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
80
{
81
struct io_fadvise *fa = io_kiocb_to_cmd(req, struct io_fadvise);
82
83
if (sqe->buf_index || sqe->splice_fd_in)
84
return -EINVAL;
85
86
fa->offset = READ_ONCE(sqe->off);
87
fa->len = READ_ONCE(sqe->addr);
88
if (!fa->len)
89
fa->len = READ_ONCE(sqe->len);
90
fa->advice = READ_ONCE(sqe->fadvise_advice);
91
if (io_fadvise_force_async(fa))
92
req->flags |= REQ_F_FORCE_ASYNC;
93
return 0;
94
}
95
96
int io_fadvise(struct io_kiocb *req, unsigned int issue_flags)
97
{
98
struct io_fadvise *fa = io_kiocb_to_cmd(req, struct io_fadvise);
99
int ret;
100
101
WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK && io_fadvise_force_async(fa));
102
103
ret = vfs_fadvise(req->file, fa->offset, fa->len, fa->advice);
104
if (ret < 0)
105
req_set_fail(req);
106
io_req_set_res(req, ret, 0);
107
return IOU_COMPLETE;
108
}
109
110