1
2
3
4
5
6
7
8
9
10#include <linux/kernel.h>
11#include <linux/mm.h>
12#include <linux/module.h>
13#include <linux/pagemap.h>
14#include <linux/pagevec.h>
15#include <linux/task_io_accounting_ops.h>
16#include <linux/buffer_head.h>
17
18
19
20static int do_invalidatepage(struct page *page, unsigned long offset)
21{
22 int (*invalidatepage)(struct page *, unsigned long);
23 invalidatepage = page->mapping->a_ops->invalidatepage;
24 if (invalidatepage == NULL)
25 invalidatepage = block_invalidatepage;
26 return (*invalidatepage)(page, offset);
27}
28
29static inline void truncate_partial_page(struct page *page, unsigned partial)
30{
31 memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
32 if (PagePrivate(page))
33 do_invalidatepage(page, partial);
34}
35
36
37
38
39
40
41
42
43
44
45
46void
47truncate_complete_page(struct address_space *mapping, struct page *page)
48{
49 if (page->mapping != mapping)
50 return;
51
52 if (PagePrivate(page))
53 do_invalidatepage(page, 0);
54
55 if (test_clear_page_dirty(page))
56 task_io_account_cancelled_write(PAGE_CACHE_SIZE);
57 ClearPageUptodate(page);
58 ClearPageMappedToDisk(page);
59 remove_from_page_cache(page);
60 page_cache_release(page);
61}
62EXPORT_SYMBOL_GPL(truncate_complete_page);
63
64
65
66
67
68
69
70
71static int
72invalidate_complete_page(struct address_space *mapping, struct page *page)
73{
74 if (page->mapping != mapping)
75 return 0;
76
77 if (PagePrivate(page) && !try_to_release_page(page, 0))
78 return 0;
79
80 spin_lock_irq(&mapping->tree_lock);
81 if (PageDirty(page)) {
82 spin_unlock_irq(&mapping->tree_lock);
83 return 0;
84 }
85
86 BUG_ON(PagePrivate(page));
87 __remove_from_page_cache(page);
88 spin_unlock_irq(&mapping->tree_lock);
89 ClearPageUptodate(page);
90 page_cache_release(page);
91 return 1;
92}
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117void truncate_inode_pages(struct address_space *mapping, loff_t lstart)
118{
119 const pgoff_t start = (lstart + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
120 const unsigned partial = lstart & (PAGE_CACHE_SIZE - 1);
121 struct pagevec pvec;
122 pgoff_t next;
123 int i;
124
125 if (mapping->nrpages == 0)
126 return;
127
128 pagevec_init(&pvec, 0);
129 next = start;
130 while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
131 for (i = 0; i < pagevec_count(&pvec); i++) {
132 struct page *page = pvec.pages[i];
133 pgoff_t page_index = page->index;
134
135 if (page_index > next)
136 next = page_index;
137 next++;
138 if (TestSetPageLocked(page))
139 continue;
140 if (PageWriteback(page)) {
141 unlock_page(page);
142 continue;
143 }
144 truncate_complete_page(mapping, page);
145 unlock_page(page);
146 }
147 pagevec_release(&pvec);
148 cond_resched();
149 }
150
151 if (partial) {
152 struct page *page = find_lock_page(mapping, start - 1);
153 if (page) {
154 wait_on_page_writeback(page);
155 truncate_partial_page(page, partial);
156 unlock_page(page);
157 page_cache_release(page);
158 }
159 }
160
161 next = start;
162 for ( ; ; ) {
163 cond_resched();
164 if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
165 if (next == start)
166 break;
167 next = start;
168 continue;
169 }
170 for (i = 0; i < pagevec_count(&pvec); i++) {
171 struct page *page = pvec.pages[i];
172
173 lock_page(page);
174 wait_on_page_writeback(page);
175 if (page->index > next)
176 next = page->index;
177 next++;
178 truncate_complete_page(mapping, page);
179 unlock_page(page);
180 }
181 pagevec_release(&pvec);
182 }
183}
184
185EXPORT_SYMBOL(truncate_inode_pages);
186
187void invalidate_all_mapping_pages(struct address_space *mapping)
188{
189 struct pagevec pvec;
190 pgoff_t next = 0;
191 int i;
192
193 pagevec_init(&pvec, 0);
194 while (next <= ~0UL &&
195 pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
196 for (i = 0; i < pagevec_count(&pvec); i++) {
197 struct page *page = pvec.pages[i];
198
199 if (TestSetPageLocked(page)) {
200 next++;
201 continue;
202 }
203 if (page->index > next)
204 next = page->index;
205 next++;
206 if (!PageDirty(page) && !PageWriteback(page) &&
207 !page_mapped(page))
208 invalidate_complete_page(mapping, page);
209 unlock_page(page);
210 if (next > ~0UL)
211 break;
212 }
213 pagevec_release(&pvec);
214 }
215 return;
216}
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232unsigned long invalidate_mapping_pages(struct address_space *mapping,
233 pgoff_t start, pgoff_t end)
234{
235 struct pagevec pvec;
236 pgoff_t next = start;
237 unsigned long ret = 0;
238 int i;
239
240 pagevec_init(&pvec, 0);
241 while (next <= end &&
242 pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
243 for (i = 0; i < pagevec_count(&pvec); i++) {
244 struct page *page = pvec.pages[i];
245
246 if (TestSetPageLocked(page)) {
247 next++;
248 continue;
249 }
250 if (page->index > next)
251 next = page->index;
252 next++;
253 if (PageDirty(page) || PageWriteback(page))
254 goto unlock;
255 if (page_mapped(page))
256 goto unlock;
257 ret += invalidate_complete_page(mapping, page);
258unlock:
259 unlock_page(page);
260 if (next > end)
261 break;
262 }
263 pagevec_release(&pvec);
264 cond_resched();
265 }
266 return ret;
267}
268
269EXPORT_SYMBOL_GPL(invalidate_mapping_pages);
270
271unsigned long invalidate_inode_pages(struct address_space *mapping)
272{
273 return invalidate_mapping_pages(mapping, 0, ~0UL);
274}
275
276EXPORT_SYMBOL(invalidate_inode_pages);
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292void invalidate_inode_pages2(struct address_space *mapping)
293{
294 struct pagevec pvec;
295 pgoff_t next = 0;
296 int i;
297
298 pagevec_init(&pvec, 0);
299 while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
300 for (i = 0; i < pagevec_count(&pvec); i++) {
301 struct page *page = pvec.pages[i];
302
303 lock_page(page);
304 if (page->mapping == mapping) {
305 wait_on_page_writeback(page);
306 next = page->index + 1;
307 if (page_mapped(page)) {
308 clear_page_dirty(page);
309 ClearPageUptodate(page);
310 } else {
311 if (!invalidate_complete_page(mapping,
312 page)) {
313 clear_page_dirty(page);
314 ClearPageUptodate(page);
315 }
316 }
317 }
318 unlock_page(page);
319 }
320 pagevec_release(&pvec);
321 cond_resched();
322 }
323}
324
325EXPORT_SYMBOL_GPL(invalidate_inode_pages2);
326
327
328
329
330
331
332
333
334
335
336
337
338int invalidate_inode_pages3_range(struct address_space *mapping,
339 pgoff_t start, pgoff_t end)
340{
341 struct pagevec pvec;
342 pgoff_t next;
343 int i;
344 int ret = 0;
345 int wrapped = 0;
346
347 pagevec_init(&pvec, 0);
348 next = start;
349 while (next <= end && !wrapped &&
350 pagevec_lookup(&pvec, mapping, next,
351 min(end - next, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
352 for (i = 0; i < pagevec_count(&pvec); i++) {
353 struct page *page = pvec.pages[i];
354 pgoff_t page_index;
355
356 lock_page(page);
357 if (page->mapping != mapping) {
358 unlock_page(page);
359 continue;
360 }
361 page_index = page->index;
362 next = page_index + 1;
363 if (next == 0)
364 wrapped = 1;
365 if (page_index > end) {
366 unlock_page(page);
367 break;
368 }
369 wait_on_page_writeback(page);
370 while (page_mapped(page)) {
371 unmap_mapping_range(mapping,
372 (loff_t)page_index<<PAGE_CACHE_SHIFT,
373 PAGE_CACHE_SIZE, 0);
374 }
375 if (!invalidate_complete_page(mapping, page))
376 ret = -EIO;
377 else {
378
379
380
381
382
383
384 atomic_inc(&mapping->truncate_count);
385 }
386 unlock_page(page);
387 }
388 pagevec_release(&pvec);
389 cond_resched();
390 }
391 return ret;
392}
393EXPORT_SYMBOL_GPL(invalidate_inode_pages3_range);
394
395
396
397
398
399
400
401
402
403
404int invalidate_inode_pages3(struct address_space *mapping)
405{
406 return invalidate_inode_pages3_range(mapping, 0, -1);
407}
408EXPORT_SYMBOL_GPL(invalidate_inode_pages3);
409