Blame view
mm/fadvise.c
3.55 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 |
/* * mm/fadvise.c * * Copyright (C) 2002, Linus Torvalds * |
e1f8e8744 Remove Andrew Mor... |
6 |
* 11Jan2003 Andrew Morton |
1da177e4c Linux-2.6.12-rc2 |
7 8 9 10 11 12 13 14 15 16 17 |
* Initial version. */ #include <linux/kernel.h> #include <linux/file.h> #include <linux/fs.h> #include <linux/mm.h> #include <linux/pagemap.h> #include <linux/backing-dev.h> #include <linux/pagevec.h> #include <linux/fadvise.h> |
ebcf28e1c [PATCH] fadvise()... |
18 |
#include <linux/writeback.h> |
1da177e4c Linux-2.6.12-rc2 |
19 |
#include <linux/syscalls.h> |
67d46b296 mm/fadvise.c: dra... |
20 |
#include <linux/swap.h> |
1da177e4c Linux-2.6.12-rc2 |
21 22 23 24 25 26 27 |
#include <asm/unistd.h> /* * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could * deactivate the pages and clear PG_Referenced. */ |
4a0fd5bf0 teach SYSCALL_DEF... |
28 |
SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice) |
1da177e4c Linux-2.6.12-rc2 |
29 |
{ |
2903ff019 switch simple cas... |
30 |
struct fd f = fdget(fd); |
1da177e4c Linux-2.6.12-rc2 |
31 32 |
struct address_space *mapping; struct backing_dev_info *bdi; |
ebcf28e1c [PATCH] fadvise()... |
33 |
loff_t endbyte; /* inclusive */ |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 |
pgoff_t start_index; pgoff_t end_index; unsigned long nrpages; int ret = 0; |
2903ff019 switch simple cas... |
38 |
if (!f.file) |
1da177e4c Linux-2.6.12-rc2 |
39 |
return -EBADF; |
496ad9aa8 new helper: file_... |
40 |
if (S_ISFIFO(file_inode(f.file)->i_mode)) { |
87ba81dba [PATCH] fadvise: ... |
41 42 43 |
ret = -ESPIPE; goto out; } |
2903ff019 switch simple cas... |
44 |
mapping = f.file->f_mapping; |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 48 |
if (!mapping || len < 0) { ret = -EINVAL; goto out; } |
70688e4dd xip: support non-... |
49 |
if (mapping->a_ops->get_xip_mem) { |
b5beb1caf check ADVICE of f... |
50 51 52 53 54 55 56 57 58 59 60 61 |
switch (advice) { case POSIX_FADV_NORMAL: case POSIX_FADV_RANDOM: case POSIX_FADV_SEQUENTIAL: case POSIX_FADV_WILLNEED: case POSIX_FADV_NOREUSE: case POSIX_FADV_DONTNEED: /* no bad return value, but ignore advice */ break; default: ret = -EINVAL; } |
fe77ba6f4 [PATCH] xip: madv... |
62 |
goto out; |
b5beb1caf check ADVICE of f... |
63 |
} |
fe77ba6f4 [PATCH] xip: madv... |
64 |
|
1da177e4c Linux-2.6.12-rc2 |
65 66 67 68 |
/* Careful about overflows. Len == 0 means "as much as possible" */ endbyte = offset + len; if (!len || endbyte < len) endbyte = -1; |
ebcf28e1c [PATCH] fadvise()... |
69 70 |
else endbyte--; /* inclusive */ |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 74 75 |
bdi = mapping->backing_dev_info; switch (advice) { case POSIX_FADV_NORMAL: |
2903ff019 switch simple cas... |
76 77 78 79 |
f.file->f_ra.ra_pages = bdi->ra_pages; spin_lock(&f.file->f_lock); f.file->f_mode &= ~FMODE_RANDOM; spin_unlock(&f.file->f_lock); |
1da177e4c Linux-2.6.12-rc2 |
80 81 |
break; case POSIX_FADV_RANDOM: |
2903ff019 switch simple cas... |
82 83 84 |
spin_lock(&f.file->f_lock); f.file->f_mode |= FMODE_RANDOM; spin_unlock(&f.file->f_lock); |
1da177e4c Linux-2.6.12-rc2 |
85 86 |
break; case POSIX_FADV_SEQUENTIAL: |
2903ff019 switch simple cas... |
87 88 89 90 |
f.file->f_ra.ra_pages = bdi->ra_pages * 2; spin_lock(&f.file->f_lock); f.file->f_mode &= ~FMODE_RANDOM; spin_unlock(&f.file->f_lock); |
1da177e4c Linux-2.6.12-rc2 |
91 92 |
break; case POSIX_FADV_WILLNEED: |
1da177e4c Linux-2.6.12-rc2 |
93 94 |
/* First and last PARTIAL page! */ start_index = offset >> PAGE_CACHE_SHIFT; |
ebcf28e1c [PATCH] fadvise()... |
95 |
end_index = endbyte >> PAGE_CACHE_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
96 97 98 99 100 |
/* Careful about overflow on the "+1" */ nrpages = end_index - start_index + 1; if (!nrpages) nrpages = ~0UL; |
3d3727cdb mm, fadvise: don'... |
101 102 103 104 105 |
/* * Ignore return value because fadvise() shall return * success even if filesystem can't retrieve a hint, */ |
2903ff019 switch simple cas... |
106 |
force_page_cache_readahead(mapping, f.file, start_index, |
3d3727cdb mm, fadvise: don'... |
107 |
nrpages); |
1da177e4c Linux-2.6.12-rc2 |
108 |
break; |
60c371bc7 [PATCH] fadvise()... |
109 110 |
case POSIX_FADV_NOREUSE: break; |
1da177e4c Linux-2.6.12-rc2 |
111 112 |
case POSIX_FADV_DONTNEED: if (!bdi_write_congested(mapping->backing_dev_info)) |
ad8a1b558 fadvise: only ini... |
113 114 |
__filemap_fdatawrite_range(mapping, offset, endbyte, WB_SYNC_NONE); |
1da177e4c Linux-2.6.12-rc2 |
115 116 |
/* First and last FULL page! */ |
ebcf28e1c [PATCH] fadvise()... |
117 |
start_index = (offset+(PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
118 |
end_index = (endbyte >> PAGE_CACHE_SHIFT); |
67d46b296 mm/fadvise.c: dra... |
119 120 121 122 123 124 125 126 127 128 129 130 131 |
if (end_index >= start_index) { unsigned long count = invalidate_mapping_pages(mapping, start_index, end_index); /* * If fewer pages were invalidated than expected then * it is possible that some of the pages were on * a per-cpu pagevec for a remote CPU. Drain all * pagevecs and try again. */ if (count < (end_index - start_index + 1)) { lru_add_drain_all(); invalidate_mapping_pages(mapping, start_index, |
ebcf28e1c [PATCH] fadvise()... |
132 |
end_index); |
67d46b296 mm/fadvise.c: dra... |
133 134 |
} } |
ebcf28e1c [PATCH] fadvise()... |
135 |
break; |
1da177e4c Linux-2.6.12-rc2 |
136 137 138 139 |
default: ret = -EINVAL; } out: |
2903ff019 switch simple cas... |
140 |
fdput(f); |
1da177e4c Linux-2.6.12-rc2 |
141 142 143 144 |
return ret; } #ifdef __ARCH_WANT_SYS_FADVISE64 |
4a0fd5bf0 teach SYSCALL_DEF... |
145 |
SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice) |
1da177e4c Linux-2.6.12-rc2 |
146 147 148 149 150 |
{ return sys_fadvise64_64(fd, offset, len, advice); } #endif |