Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/mm/fadvise.c
10814 views
1
/*
2
* mm/fadvise.c
3
*
4
* Copyright (C) 2002, Linus Torvalds
5
*
6
* 11Jan2003 Andrew Morton
7
* Initial version.
8
*/
9
10
#include <linux/kernel.h>
11
#include <linux/file.h>
12
#include <linux/fs.h>
13
#include <linux/mm.h>
14
#include <linux/pagemap.h>
15
#include <linux/backing-dev.h>
16
#include <linux/pagevec.h>
17
#include <linux/fadvise.h>
18
#include <linux/writeback.h>
19
#include <linux/syscalls.h>
20
21
#include <asm/unistd.h>
22
23
/*
24
* POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
25
* deactivate the pages and clear PG_Referenced.
26
*/
27
SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
28
{
29
struct file *file = fget(fd);
30
struct address_space *mapping;
31
struct backing_dev_info *bdi;
32
loff_t endbyte; /* inclusive */
33
pgoff_t start_index;
34
pgoff_t end_index;
35
unsigned long nrpages;
36
int ret = 0;
37
38
if (!file)
39
return -EBADF;
40
41
if (S_ISFIFO(file->f_path.dentry->d_inode->i_mode)) {
42
ret = -ESPIPE;
43
goto out;
44
}
45
46
mapping = file->f_mapping;
47
if (!mapping || len < 0) {
48
ret = -EINVAL;
49
goto out;
50
}
51
52
if (mapping->a_ops->get_xip_mem) {
53
switch (advice) {
54
case POSIX_FADV_NORMAL:
55
case POSIX_FADV_RANDOM:
56
case POSIX_FADV_SEQUENTIAL:
57
case POSIX_FADV_WILLNEED:
58
case POSIX_FADV_NOREUSE:
59
case POSIX_FADV_DONTNEED:
60
/* no bad return value, but ignore advice */
61
break;
62
default:
63
ret = -EINVAL;
64
}
65
goto out;
66
}
67
68
/* Careful about overflows. Len == 0 means "as much as possible" */
69
endbyte = offset + len;
70
if (!len || endbyte < len)
71
endbyte = -1;
72
else
73
endbyte--; /* inclusive */
74
75
bdi = mapping->backing_dev_info;
76
77
switch (advice) {
78
case POSIX_FADV_NORMAL:
79
file->f_ra.ra_pages = bdi->ra_pages;
80
spin_lock(&file->f_lock);
81
file->f_mode &= ~FMODE_RANDOM;
82
spin_unlock(&file->f_lock);
83
break;
84
case POSIX_FADV_RANDOM:
85
spin_lock(&file->f_lock);
86
file->f_mode |= FMODE_RANDOM;
87
spin_unlock(&file->f_lock);
88
break;
89
case POSIX_FADV_SEQUENTIAL:
90
file->f_ra.ra_pages = bdi->ra_pages * 2;
91
spin_lock(&file->f_lock);
92
file->f_mode &= ~FMODE_RANDOM;
93
spin_unlock(&file->f_lock);
94
break;
95
case POSIX_FADV_WILLNEED:
96
if (!mapping->a_ops->readpage) {
97
ret = -EINVAL;
98
break;
99
}
100
101
/* First and last PARTIAL page! */
102
start_index = offset >> PAGE_CACHE_SHIFT;
103
end_index = endbyte >> PAGE_CACHE_SHIFT;
104
105
/* Careful about overflow on the "+1" */
106
nrpages = end_index - start_index + 1;
107
if (!nrpages)
108
nrpages = ~0UL;
109
110
ret = force_page_cache_readahead(mapping, file,
111
start_index,
112
nrpages);
113
if (ret > 0)
114
ret = 0;
115
break;
116
case POSIX_FADV_NOREUSE:
117
break;
118
case POSIX_FADV_DONTNEED:
119
if (!bdi_write_congested(mapping->backing_dev_info))
120
filemap_flush(mapping);
121
122
/* First and last FULL page! */
123
start_index = (offset+(PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT;
124
end_index = (endbyte >> PAGE_CACHE_SHIFT);
125
126
if (end_index >= start_index)
127
invalidate_mapping_pages(mapping, start_index,
128
end_index);
129
break;
130
default:
131
ret = -EINVAL;
132
}
133
out:
134
fput(file);
135
return ret;
136
}
137
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
138
asmlinkage long SyS_fadvise64_64(long fd, loff_t offset, loff_t len, long advice)
139
{
140
return SYSC_fadvise64_64((int) fd, offset, len, (int) advice);
141
}
142
SYSCALL_ALIAS(sys_fadvise64_64, SyS_fadvise64_64);
143
#endif
144
145
#ifdef __ARCH_WANT_SYS_FADVISE64
146
147
SYSCALL_DEFINE(fadvise64)(int fd, loff_t offset, size_t len, int advice)
148
{
149
return sys_fadvise64_64(fd, offset, len, advice);
150
}
151
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
152
asmlinkage long SyS_fadvise64(long fd, loff_t offset, long len, long advice)
153
{
154
return SYSC_fadvise64((int) fd, offset, (size_t)len, (int)advice);
155
}
156
SYSCALL_ALIAS(sys_fadvise64, SyS_fadvise64);
157
#endif
158
159
#endif
160
161