Contents of /alx-src/tags/kernel26-2.6.12-alx-r9/mm/fadvise.c
Parent Directory | Revision Log
Revision 630 -
(show annotations)
(download)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 2420 byte(s)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 2420 byte(s)
Tag kernel26-2.6.12-alx-r9
1 | /* |
2 | * mm/fadvise.c |
3 | * |
4 | * Copyright (C) 2002, Linus Torvalds |
5 | * |
6 | * 11Jan2003 akpm@digeo.com |
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/syscalls.h> |
19 | |
20 | #include <asm/unistd.h> |
21 | |
22 | /* |
23 | * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could |
24 | * deactivate the pages and clear PG_Referenced. |
25 | */ |
26 | asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) |
27 | { |
28 | struct file *file = fget(fd); |
29 | struct address_space *mapping; |
30 | struct backing_dev_info *bdi; |
31 | loff_t endbyte; |
32 | pgoff_t start_index; |
33 | pgoff_t end_index; |
34 | unsigned long nrpages; |
35 | int ret = 0; |
36 | |
37 | if (!file) |
38 | return -EBADF; |
39 | |
40 | mapping = file->f_mapping; |
41 | if (!mapping || len < 0) { |
42 | ret = -EINVAL; |
43 | goto out; |
44 | } |
45 | |
46 | /* Careful about overflows. Len == 0 means "as much as possible" */ |
47 | endbyte = offset + len; |
48 | if (!len || endbyte < len) |
49 | endbyte = -1; |
50 | |
51 | bdi = mapping->backing_dev_info; |
52 | |
53 | switch (advice) { |
54 | case POSIX_FADV_NORMAL: |
55 | file->f_ra.ra_pages = bdi->ra_pages; |
56 | break; |
57 | case POSIX_FADV_RANDOM: |
58 | file->f_ra.ra_pages = 0; |
59 | break; |
60 | case POSIX_FADV_SEQUENTIAL: |
61 | file->f_ra.ra_pages = bdi->ra_pages * 2; |
62 | break; |
63 | case POSIX_FADV_WILLNEED: |
64 | case POSIX_FADV_NOREUSE: |
65 | if (!mapping->a_ops->readpage) { |
66 | ret = -EINVAL; |
67 | break; |
68 | } |
69 | |
70 | /* First and last PARTIAL page! */ |
71 | start_index = offset >> PAGE_CACHE_SHIFT; |
72 | end_index = (endbyte-1) >> PAGE_CACHE_SHIFT; |
73 | |
74 | /* Careful about overflow on the "+1" */ |
75 | nrpages = end_index - start_index + 1; |
76 | if (!nrpages) |
77 | nrpages = ~0UL; |
78 | |
79 | ret = force_page_cache_readahead(mapping, file, |
80 | start_index, |
81 | max_sane_readahead(nrpages)); |
82 | if (ret > 0) |
83 | ret = 0; |
84 | break; |
85 | case POSIX_FADV_DONTNEED: |
86 | if (!bdi_write_congested(mapping->backing_dev_info)) |
87 | filemap_flush(mapping); |
88 | |
89 | /* First and last FULL page! */ |
90 | start_index = (offset + (PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT; |
91 | end_index = (endbyte >> PAGE_CACHE_SHIFT); |
92 | |
93 | if (end_index > start_index) |
94 | invalidate_mapping_pages(mapping, start_index, end_index-1); |
95 | break; |
96 | default: |
97 | ret = -EINVAL; |
98 | } |
99 | out: |
100 | fput(file); |
101 | return ret; |
102 | } |
103 | |
104 | #ifdef __ARCH_WANT_SYS_FADVISE64 |
105 | |
106 | asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) |
107 | { |
108 | return sys_fadvise64_64(fd, offset, len, advice); |
109 | } |
110 | |
111 | #endif |