diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2009-05-22 05:01:55 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2009-05-22 05:01:55 -0400 |
commit | b1e71b0622974953e46a284aa986504a90869a9b (patch) | |
tree | 0eb0f68c8b432b6332437e918ca2ab4e0c72d897 /fs/gfs2/aops.c | |
parent | 1ce97e564b628bee30b8dbb64e5e653a484308f6 (diff) |
GFS2: Clean up some file names
This patch renames the ops_*.c files which have no counterpart
without the ops_ prefix in order to shorten the name and make
it more readable. In addition, ops_address.h (which was very
small) is moved into inode.h and inode.h is cleaned up by
adding extern where required.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/aops.c')
-rw-r--r-- | fs/gfs2/aops.c | 1145 |
1 files changed, 1145 insertions, 0 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c new file mode 100644 index 000000000000..03ebb439ace0 --- /dev/null +++ b/fs/gfs2/aops.c | |||
@@ -0,0 +1,1145 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/sched.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/completion.h> | ||
14 | #include <linux/buffer_head.h> | ||
15 | #include <linux/pagemap.h> | ||
16 | #include <linux/pagevec.h> | ||
17 | #include <linux/mpage.h> | ||
18 | #include <linux/fs.h> | ||
19 | #include <linux/writeback.h> | ||
20 | #include <linux/swap.h> | ||
21 | #include <linux/gfs2_ondisk.h> | ||
22 | #include <linux/backing-dev.h> | ||
23 | |||
24 | #include "gfs2.h" | ||
25 | #include "incore.h" | ||
26 | #include "bmap.h" | ||
27 | #include "glock.h" | ||
28 | #include "inode.h" | ||
29 | #include "log.h" | ||
30 | #include "meta_io.h" | ||
31 | #include "quota.h" | ||
32 | #include "trans.h" | ||
33 | #include "rgrp.h" | ||
34 | #include "super.h" | ||
35 | #include "util.h" | ||
36 | #include "glops.h" | ||
37 | |||
38 | |||
39 | static void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page, | ||
40 | unsigned int from, unsigned int to) | ||
41 | { | ||
42 | struct buffer_head *head = page_buffers(page); | ||
43 | unsigned int bsize = head->b_size; | ||
44 | struct buffer_head *bh; | ||
45 | unsigned int start, end; | ||
46 | |||
47 | for (bh = head, start = 0; bh != head || !start; | ||
48 | bh = bh->b_this_page, start = end) { | ||
49 | end = start + bsize; | ||
50 | if (end <= from || start >= to) | ||
51 | continue; | ||
52 | if (gfs2_is_jdata(ip)) | ||
53 | set_buffer_uptodate(bh); | ||
54 | gfs2_trans_add_bh(ip->i_gl, bh, 0); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * gfs2_get_block_noalloc - Fills in a buffer head with details about a block | ||
60 | * @inode: The inode | ||
61 | * @lblock: The block number to look up | ||
62 | * @bh_result: The buffer head to return the result in | ||
63 | * @create: Non-zero if we may add block to the file | ||
64 | * | ||
65 | * Returns: errno | ||
66 | */ | ||
67 | |||
68 | static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock, | ||
69 | struct buffer_head *bh_result, int create) | ||
70 | { | ||
71 | int error; | ||
72 | |||
73 | error = gfs2_block_map(inode, lblock, bh_result, 0); | ||
74 | if (error) | ||
75 | return error; | ||
76 | if (!buffer_mapped(bh_result)) | ||
77 | return -EIO; | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int gfs2_get_block_direct(struct inode *inode, sector_t lblock, | ||
82 | struct buffer_head *bh_result, int create) | ||
83 | { | ||
84 | return gfs2_block_map(inode, lblock, bh_result, 0); | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * gfs2_writepage_common - Common bits of writepage | ||
89 | * @page: The page to be written | ||
90 | * @wbc: The writeback control | ||
91 | * | ||
92 | * Returns: 1 if writepage is ok, otherwise an error code or zero if no error. | ||
93 | */ | ||
94 | |||
95 | static int gfs2_writepage_common(struct page *page, | ||
96 | struct writeback_control *wbc) | ||
97 | { | ||
98 | struct inode *inode = page->mapping->host; | ||
99 | struct gfs2_inode *ip = GFS2_I(inode); | ||
100 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
101 | loff_t i_size = i_size_read(inode); | ||
102 | pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; | ||
103 | unsigned offset; | ||
104 | |||
105 | if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl))) | ||
106 | goto out; | ||
107 | if (current->journal_info) | ||
108 | goto redirty; | ||
109 | /* Is the page fully outside i_size? (truncate in progress) */ | ||
110 | offset = i_size & (PAGE_CACHE_SIZE-1); | ||
111 | if (page->index > end_index || (page->index == end_index && !offset)) { | ||
112 | page->mapping->a_ops->invalidatepage(page, 0); | ||
113 | goto out; | ||
114 | } | ||
115 | return 1; | ||
116 | redirty: | ||
117 | redirty_page_for_writepage(wbc, page); | ||
118 | out: | ||
119 | unlock_page(page); | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * gfs2_writeback_writepage - Write page for writeback mappings | ||
125 | * @page: The page | ||
126 | * @wbc: The writeback control | ||
127 | * | ||
128 | */ | ||
129 | |||
130 | static int gfs2_writeback_writepage(struct page *page, | ||
131 | struct writeback_control *wbc) | ||
132 | { | ||
133 | int ret; | ||
134 | |||
135 | ret = gfs2_writepage_common(page, wbc); | ||
136 | if (ret <= 0) | ||
137 | return ret; | ||
138 | |||
139 | ret = mpage_writepage(page, gfs2_get_block_noalloc, wbc); | ||
140 | if (ret == -EAGAIN) | ||
141 | ret = block_write_full_page(page, gfs2_get_block_noalloc, wbc); | ||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | /** | ||
146 | * gfs2_ordered_writepage - Write page for ordered data files | ||
147 | * @page: The page to write | ||
148 | * @wbc: The writeback control | ||
149 | * | ||
150 | */ | ||
151 | |||
152 | static int gfs2_ordered_writepage(struct page *page, | ||
153 | struct writeback_control *wbc) | ||
154 | { | ||
155 | struct inode *inode = page->mapping->host; | ||
156 | struct gfs2_inode *ip = GFS2_I(inode); | ||
157 | int ret; | ||
158 | |||
159 | ret = gfs2_writepage_common(page, wbc); | ||
160 | if (ret <= 0) | ||
161 | return ret; | ||
162 | |||
163 | if (!page_has_buffers(page)) { | ||
164 | create_empty_buffers(page, inode->i_sb->s_blocksize, | ||
165 | (1 << BH_Dirty)|(1 << BH_Uptodate)); | ||
166 | } | ||
167 | gfs2_page_add_databufs(ip, page, 0, inode->i_sb->s_blocksize-1); | ||
168 | return block_write_full_page(page, gfs2_get_block_noalloc, wbc); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * __gfs2_jdata_writepage - The core of jdata writepage | ||
173 | * @page: The page to write | ||
174 | * @wbc: The writeback control | ||
175 | * | ||
176 | * This is shared between writepage and writepages and implements the | ||
177 | * core of the writepage operation. If a transaction is required then | ||
178 | * PageChecked will have been set and the transaction will have | ||
179 | * already been started before this is called. | ||
180 | */ | ||
181 | |||
182 | static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc) | ||
183 | { | ||
184 | struct inode *inode = page->mapping->host; | ||
185 | struct gfs2_inode *ip = GFS2_I(inode); | ||
186 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
187 | |||
188 | if (PageChecked(page)) { | ||
189 | ClearPageChecked(page); | ||
190 | if (!page_has_buffers(page)) { | ||
191 | create_empty_buffers(page, inode->i_sb->s_blocksize, | ||
192 | (1 << BH_Dirty)|(1 << BH_Uptodate)); | ||
193 | } | ||
194 | gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1); | ||
195 | } | ||
196 | return block_write_full_page(page, gfs2_get_block_noalloc, wbc); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * gfs2_jdata_writepage - Write complete page | ||
201 | * @page: Page to write | ||
202 | * | ||
203 | * Returns: errno | ||
204 | * | ||
205 | */ | ||
206 | |||
207 | static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc) | ||
208 | { | ||
209 | struct inode *inode = page->mapping->host; | ||
210 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
211 | int ret; | ||
212 | int done_trans = 0; | ||
213 | |||
214 | if (PageChecked(page)) { | ||
215 | if (wbc->sync_mode != WB_SYNC_ALL) | ||
216 | goto out_ignore; | ||
217 | ret = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); | ||
218 | if (ret) | ||
219 | goto out_ignore; | ||
220 | done_trans = 1; | ||
221 | } | ||
222 | ret = gfs2_writepage_common(page, wbc); | ||
223 | if (ret > 0) | ||
224 | ret = __gfs2_jdata_writepage(page, wbc); | ||
225 | if (done_trans) | ||
226 | gfs2_trans_end(sdp); | ||
227 | return ret; | ||
228 | |||
229 | out_ignore: | ||
230 | redirty_page_for_writepage(wbc, page); | ||
231 | unlock_page(page); | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | /** | ||
236 | * gfs2_writeback_writepages - Write a bunch of dirty pages back to disk | ||
237 | * @mapping: The mapping to write | ||
238 | * @wbc: Write-back control | ||
239 | * | ||
240 | * For the data=writeback case we can already ignore buffer heads | ||
241 | * and write whole extents at once. This is a big reduction in the | ||
242 | * number of I/O requests we send and the bmap calls we make in this case. | ||
243 | */ | ||
244 | static int gfs2_writeback_writepages(struct address_space *mapping, | ||
245 | struct writeback_control *wbc) | ||
246 | { | ||
247 | return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc); | ||
248 | } | ||
249 | |||
250 | /** | ||
251 | * gfs2_write_jdata_pagevec - Write back a pagevec's worth of pages | ||
252 | * @mapping: The mapping | ||
253 | * @wbc: The writeback control | ||
254 | * @writepage: The writepage function to call for each page | ||
255 | * @pvec: The vector of pages | ||
256 | * @nr_pages: The number of pages to write | ||
257 | * | ||
258 | * Returns: non-zero if loop should terminate, zero otherwise | ||
259 | */ | ||
260 | |||
261 | static int gfs2_write_jdata_pagevec(struct address_space *mapping, | ||
262 | struct writeback_control *wbc, | ||
263 | struct pagevec *pvec, | ||
264 | int nr_pages, pgoff_t end) | ||
265 | { | ||
266 | struct inode *inode = mapping->host; | ||
267 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
268 | loff_t i_size = i_size_read(inode); | ||
269 | pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; | ||
270 | unsigned offset = i_size & (PAGE_CACHE_SIZE-1); | ||
271 | unsigned nrblocks = nr_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize); | ||
272 | struct backing_dev_info *bdi = mapping->backing_dev_info; | ||
273 | int i; | ||
274 | int ret; | ||
275 | |||
276 | ret = gfs2_trans_begin(sdp, nrblocks, nrblocks); | ||
277 | if (ret < 0) | ||
278 | return ret; | ||
279 | |||
280 | for(i = 0; i < nr_pages; i++) { | ||
281 | struct page *page = pvec->pages[i]; | ||
282 | |||
283 | lock_page(page); | ||
284 | |||
285 | if (unlikely(page->mapping != mapping)) { | ||
286 | unlock_page(page); | ||
287 | continue; | ||
288 | } | ||
289 | |||
290 | if (!wbc->range_cyclic && page->index > end) { | ||
291 | ret = 1; | ||
292 | unlock_page(page); | ||
293 | continue; | ||
294 | } | ||
295 | |||
296 | if (wbc->sync_mode != WB_SYNC_NONE) | ||
297 | wait_on_page_writeback(page); | ||
298 | |||
299 | if (PageWriteback(page) || | ||
300 | !clear_page_dirty_for_io(page)) { | ||
301 | unlock_page(page); | ||
302 | continue; | ||
303 | } | ||
304 | |||
305 | /* Is the page fully outside i_size? (truncate in progress) */ | ||
306 | if (page->index > end_index || (page->index == end_index && !offset)) { | ||
307 | page->mapping->a_ops->invalidatepage(page, 0); | ||
308 | unlock_page(page); | ||
309 | continue; | ||
310 | } | ||
311 | |||
312 | ret = __gfs2_jdata_writepage(page, wbc); | ||
313 | |||
314 | if (ret || (--(wbc->nr_to_write) <= 0)) | ||
315 | ret = 1; | ||
316 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | ||
317 | wbc->encountered_congestion = 1; | ||
318 | ret = 1; | ||
319 | } | ||
320 | |||
321 | } | ||
322 | gfs2_trans_end(sdp); | ||
323 | return ret; | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * gfs2_write_cache_jdata - Like write_cache_pages but different | ||
328 | * @mapping: The mapping to write | ||
329 | * @wbc: The writeback control | ||
330 | * @writepage: The writepage function to call | ||
331 | * @data: The data to pass to writepage | ||
332 | * | ||
333 | * The reason that we use our own function here is that we need to | ||
334 | * start transactions before we grab page locks. This allows us | ||
335 | * to get the ordering right. | ||
336 | */ | ||
337 | |||
338 | static int gfs2_write_cache_jdata(struct address_space *mapping, | ||
339 | struct writeback_control *wbc) | ||
340 | { | ||
341 | struct backing_dev_info *bdi = mapping->backing_dev_info; | ||
342 | int ret = 0; | ||
343 | int done = 0; | ||
344 | struct pagevec pvec; | ||
345 | int nr_pages; | ||
346 | pgoff_t index; | ||
347 | pgoff_t end; | ||
348 | int scanned = 0; | ||
349 | int range_whole = 0; | ||
350 | |||
351 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | ||
352 | wbc->encountered_congestion = 1; | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | pagevec_init(&pvec, 0); | ||
357 | if (wbc->range_cyclic) { | ||
358 | index = mapping->writeback_index; /* Start from prev offset */ | ||
359 | end = -1; | ||
360 | } else { | ||
361 | index = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
362 | end = wbc->range_end >> PAGE_CACHE_SHIFT; | ||
363 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) | ||
364 | range_whole = 1; | ||
365 | scanned = 1; | ||
366 | } | ||
367 | |||
368 | retry: | ||
369 | while (!done && (index <= end) && | ||
370 | (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, | ||
371 | PAGECACHE_TAG_DIRTY, | ||
372 | min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { | ||
373 | scanned = 1; | ||
374 | ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, end); | ||
375 | if (ret) | ||
376 | done = 1; | ||
377 | if (ret > 0) | ||
378 | ret = 0; | ||
379 | |||
380 | pagevec_release(&pvec); | ||
381 | cond_resched(); | ||
382 | } | ||
383 | |||
384 | if (!scanned && !done) { | ||
385 | /* | ||
386 | * We hit the last page and there is more work to be done: wrap | ||
387 | * back to the start of the file | ||
388 | */ | ||
389 | scanned = 1; | ||
390 | index = 0; | ||
391 | goto retry; | ||
392 | } | ||
393 | |||
394 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | ||
395 | mapping->writeback_index = index; | ||
396 | return ret; | ||
397 | } | ||
398 | |||
399 | |||
400 | /** | ||
401 | * gfs2_jdata_writepages - Write a bunch of dirty pages back to disk | ||
402 | * @mapping: The mapping to write | ||
403 | * @wbc: The writeback control | ||
404 | * | ||
405 | */ | ||
406 | |||
407 | static int gfs2_jdata_writepages(struct address_space *mapping, | ||
408 | struct writeback_control *wbc) | ||
409 | { | ||
410 | struct gfs2_inode *ip = GFS2_I(mapping->host); | ||
411 | struct gfs2_sbd *sdp = GFS2_SB(mapping->host); | ||
412 | int ret; | ||
413 | |||
414 | ret = gfs2_write_cache_jdata(mapping, wbc); | ||
415 | if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { | ||
416 | gfs2_log_flush(sdp, ip->i_gl); | ||
417 | ret = gfs2_write_cache_jdata(mapping, wbc); | ||
418 | } | ||
419 | return ret; | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * stuffed_readpage - Fill in a Linux page with stuffed file data | ||
424 | * @ip: the inode | ||
425 | * @page: the page | ||
426 | * | ||
427 | * Returns: errno | ||
428 | */ | ||
429 | |||
430 | static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | ||
431 | { | ||
432 | struct buffer_head *dibh; | ||
433 | void *kaddr; | ||
434 | int error; | ||
435 | |||
436 | /* | ||
437 | * Due to the order of unstuffing files and ->fault(), we can be | ||
438 | * asked for a zero page in the case of a stuffed file being extended, | ||
439 | * so we need to supply one here. It doesn't happen often. | ||
440 | */ | ||
441 | if (unlikely(page->index)) { | ||
442 | zero_user(page, 0, PAGE_CACHE_SIZE); | ||
443 | SetPageUptodate(page); | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
448 | if (error) | ||
449 | return error; | ||
450 | |||
451 | kaddr = kmap_atomic(page, KM_USER0); | ||
452 | memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), | ||
453 | ip->i_disksize); | ||
454 | memset(kaddr + ip->i_disksize, 0, PAGE_CACHE_SIZE - ip->i_disksize); | ||
455 | kunmap_atomic(kaddr, KM_USER0); | ||
456 | flush_dcache_page(page); | ||
457 | brelse(dibh); | ||
458 | SetPageUptodate(page); | ||
459 | |||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | |||
464 | /** | ||
465 | * __gfs2_readpage - readpage | ||
466 | * @file: The file to read a page for | ||
467 | * @page: The page to read | ||
468 | * | ||
469 | * This is the core of gfs2's readpage. Its used by the internal file | ||
470 | * reading code as in that case we already hold the glock. Also its | ||
471 | * called by gfs2_readpage() once the required lock has been granted. | ||
472 | * | ||
473 | */ | ||
474 | |||
475 | static int __gfs2_readpage(void *file, struct page *page) | ||
476 | { | ||
477 | struct gfs2_inode *ip = GFS2_I(page->mapping->host); | ||
478 | struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); | ||
479 | int error; | ||
480 | |||
481 | if (gfs2_is_stuffed(ip)) { | ||
482 | error = stuffed_readpage(ip, page); | ||
483 | unlock_page(page); | ||
484 | } else { | ||
485 | error = mpage_readpage(page, gfs2_block_map); | ||
486 | } | ||
487 | |||
488 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
489 | return -EIO; | ||
490 | |||
491 | return error; | ||
492 | } | ||
493 | |||
494 | /** | ||
495 | * gfs2_readpage - read a page of a file | ||
496 | * @file: The file to read | ||
497 | * @page: The page of the file | ||
498 | * | ||
499 | * This deals with the locking required. We have to unlock and | ||
500 | * relock the page in order to get the locking in the right | ||
501 | * order. | ||
502 | */ | ||
503 | |||
504 | static int gfs2_readpage(struct file *file, struct page *page) | ||
505 | { | ||
506 | struct address_space *mapping = page->mapping; | ||
507 | struct gfs2_inode *ip = GFS2_I(mapping->host); | ||
508 | struct gfs2_holder gh; | ||
509 | int error; | ||
510 | |||
511 | unlock_page(page); | ||
512 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | ||
513 | error = gfs2_glock_nq(&gh); | ||
514 | if (unlikely(error)) | ||
515 | goto out; | ||
516 | error = AOP_TRUNCATED_PAGE; | ||
517 | lock_page(page); | ||
518 | if (page->mapping == mapping && !PageUptodate(page)) | ||
519 | error = __gfs2_readpage(file, page); | ||
520 | else | ||
521 | unlock_page(page); | ||
522 | gfs2_glock_dq(&gh); | ||
523 | out: | ||
524 | gfs2_holder_uninit(&gh); | ||
525 | if (error && error != AOP_TRUNCATED_PAGE) | ||
526 | lock_page(page); | ||
527 | return error; | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | * gfs2_internal_read - read an internal file | ||
532 | * @ip: The gfs2 inode | ||
533 | * @ra_state: The readahead state (or NULL for no readahead) | ||
534 | * @buf: The buffer to fill | ||
535 | * @pos: The file position | ||
536 | * @size: The amount to read | ||
537 | * | ||
538 | */ | ||
539 | |||
540 | int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, | ||
541 | char *buf, loff_t *pos, unsigned size) | ||
542 | { | ||
543 | struct address_space *mapping = ip->i_inode.i_mapping; | ||
544 | unsigned long index = *pos / PAGE_CACHE_SIZE; | ||
545 | unsigned offset = *pos & (PAGE_CACHE_SIZE - 1); | ||
546 | unsigned copied = 0; | ||
547 | unsigned amt; | ||
548 | struct page *page; | ||
549 | void *p; | ||
550 | |||
551 | do { | ||
552 | amt = size - copied; | ||
553 | if (offset + size > PAGE_CACHE_SIZE) | ||
554 | amt = PAGE_CACHE_SIZE - offset; | ||
555 | page = read_cache_page(mapping, index, __gfs2_readpage, NULL); | ||
556 | if (IS_ERR(page)) | ||
557 | return PTR_ERR(page); | ||
558 | p = kmap_atomic(page, KM_USER0); | ||
559 | memcpy(buf + copied, p + offset, amt); | ||
560 | kunmap_atomic(p, KM_USER0); | ||
561 | mark_page_accessed(page); | ||
562 | page_cache_release(page); | ||
563 | copied += amt; | ||
564 | index++; | ||
565 | offset = 0; | ||
566 | } while(copied < size); | ||
567 | (*pos) += size; | ||
568 | return size; | ||
569 | } | ||
570 | |||
571 | /** | ||
572 | * gfs2_readpages - Read a bunch of pages at once | ||
573 | * | ||
574 | * Some notes: | ||
575 | * 1. This is only for readahead, so we can simply ignore any things | ||
576 | * which are slightly inconvenient (such as locking conflicts between | ||
577 | * the page lock and the glock) and return having done no I/O. Its | ||
578 | * obviously not something we'd want to do on too regular a basis. | ||
579 | * Any I/O we ignore at this time will be done via readpage later. | ||
580 | * 2. We don't handle stuffed files here we let readpage do the honours. | ||
581 | * 3. mpage_readpages() does most of the heavy lifting in the common case. | ||
582 | * 4. gfs2_block_map() is relied upon to set BH_Boundary in the right places. | ||
583 | */ | ||
584 | |||
585 | static int gfs2_readpages(struct file *file, struct address_space *mapping, | ||
586 | struct list_head *pages, unsigned nr_pages) | ||
587 | { | ||
588 | struct inode *inode = mapping->host; | ||
589 | struct gfs2_inode *ip = GFS2_I(inode); | ||
590 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
591 | struct gfs2_holder gh; | ||
592 | int ret; | ||
593 | |||
594 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | ||
595 | ret = gfs2_glock_nq(&gh); | ||
596 | if (unlikely(ret)) | ||
597 | goto out_uninit; | ||
598 | if (!gfs2_is_stuffed(ip)) | ||
599 | ret = mpage_readpages(mapping, pages, nr_pages, gfs2_block_map); | ||
600 | gfs2_glock_dq(&gh); | ||
601 | out_uninit: | ||
602 | gfs2_holder_uninit(&gh); | ||
603 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
604 | ret = -EIO; | ||
605 | return ret; | ||
606 | } | ||
607 | |||
608 | /** | ||
609 | * gfs2_write_begin - Begin to write to a file | ||
610 | * @file: The file to write to | ||
611 | * @mapping: The mapping in which to write | ||
612 | * @pos: The file offset at which to start writing | ||
613 | * @len: Length of the write | ||
614 | * @flags: Various flags | ||
615 | * @pagep: Pointer to return the page | ||
616 | * @fsdata: Pointer to return fs data (unused by GFS2) | ||
617 | * | ||
618 | * Returns: errno | ||
619 | */ | ||
620 | |||
621 | static int gfs2_write_begin(struct file *file, struct address_space *mapping, | ||
622 | loff_t pos, unsigned len, unsigned flags, | ||
623 | struct page **pagep, void **fsdata) | ||
624 | { | ||
625 | struct gfs2_inode *ip = GFS2_I(mapping->host); | ||
626 | struct gfs2_sbd *sdp = GFS2_SB(mapping->host); | ||
627 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | ||
628 | int alloc_required; | ||
629 | int error = 0; | ||
630 | struct gfs2_alloc *al; | ||
631 | pgoff_t index = pos >> PAGE_CACHE_SHIFT; | ||
632 | unsigned from = pos & (PAGE_CACHE_SIZE - 1); | ||
633 | unsigned to = from + len; | ||
634 | struct page *page; | ||
635 | |||
636 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); | ||
637 | error = gfs2_glock_nq(&ip->i_gh); | ||
638 | if (unlikely(error)) | ||
639 | goto out_uninit; | ||
640 | |||
641 | error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); | ||
642 | if (error) | ||
643 | goto out_unlock; | ||
644 | |||
645 | if (alloc_required || gfs2_is_jdata(ip)) | ||
646 | gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); | ||
647 | |||
648 | if (alloc_required) { | ||
649 | al = gfs2_alloc_get(ip); | ||
650 | if (!al) { | ||
651 | error = -ENOMEM; | ||
652 | goto out_unlock; | ||
653 | } | ||
654 | |||
655 | error = gfs2_quota_lock_check(ip); | ||
656 | if (error) | ||
657 | goto out_alloc_put; | ||
658 | |||
659 | al->al_requested = data_blocks + ind_blocks; | ||
660 | error = gfs2_inplace_reserve(ip); | ||
661 | if (error) | ||
662 | goto out_qunlock; | ||
663 | } | ||
664 | |||
665 | rblocks = RES_DINODE + ind_blocks; | ||
666 | if (gfs2_is_jdata(ip)) | ||
667 | rblocks += data_blocks ? data_blocks : 1; | ||
668 | if (ind_blocks || data_blocks) | ||
669 | rblocks += RES_STATFS + RES_QUOTA; | ||
670 | |||
671 | error = gfs2_trans_begin(sdp, rblocks, | ||
672 | PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize); | ||
673 | if (error) | ||
674 | goto out_trans_fail; | ||
675 | |||
676 | error = -ENOMEM; | ||
677 | flags |= AOP_FLAG_NOFS; | ||
678 | page = grab_cache_page_write_begin(mapping, index, flags); | ||
679 | *pagep = page; | ||
680 | if (unlikely(!page)) | ||
681 | goto out_endtrans; | ||
682 | |||
683 | if (gfs2_is_stuffed(ip)) { | ||
684 | error = 0; | ||
685 | if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { | ||
686 | error = gfs2_unstuff_dinode(ip, page); | ||
687 | if (error == 0) | ||
688 | goto prepare_write; | ||
689 | } else if (!PageUptodate(page)) { | ||
690 | error = stuffed_readpage(ip, page); | ||
691 | } | ||
692 | goto out; | ||
693 | } | ||
694 | |||
695 | prepare_write: | ||
696 | error = block_prepare_write(page, from, to, gfs2_block_map); | ||
697 | out: | ||
698 | if (error == 0) | ||
699 | return 0; | ||
700 | |||
701 | page_cache_release(page); | ||
702 | if (pos + len > ip->i_inode.i_size) | ||
703 | vmtruncate(&ip->i_inode, ip->i_inode.i_size); | ||
704 | out_endtrans: | ||
705 | gfs2_trans_end(sdp); | ||
706 | out_trans_fail: | ||
707 | if (alloc_required) { | ||
708 | gfs2_inplace_release(ip); | ||
709 | out_qunlock: | ||
710 | gfs2_quota_unlock(ip); | ||
711 | out_alloc_put: | ||
712 | gfs2_alloc_put(ip); | ||
713 | } | ||
714 | out_unlock: | ||
715 | gfs2_glock_dq(&ip->i_gh); | ||
716 | out_uninit: | ||
717 | gfs2_holder_uninit(&ip->i_gh); | ||
718 | return error; | ||
719 | } | ||
720 | |||
721 | /** | ||
722 | * adjust_fs_space - Adjusts the free space available due to gfs2_grow | ||
723 | * @inode: the rindex inode | ||
724 | */ | ||
725 | static void adjust_fs_space(struct inode *inode) | ||
726 | { | ||
727 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | ||
728 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
729 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
730 | u64 fs_total, new_free; | ||
731 | |||
732 | /* Total up the file system space, according to the latest rindex. */ | ||
733 | fs_total = gfs2_ri_total(sdp); | ||
734 | |||
735 | spin_lock(&sdp->sd_statfs_spin); | ||
736 | if (fs_total > (m_sc->sc_total + l_sc->sc_total)) | ||
737 | new_free = fs_total - (m_sc->sc_total + l_sc->sc_total); | ||
738 | else | ||
739 | new_free = 0; | ||
740 | spin_unlock(&sdp->sd_statfs_spin); | ||
741 | fs_warn(sdp, "File system extended by %llu blocks.\n", | ||
742 | (unsigned long long)new_free); | ||
743 | gfs2_statfs_change(sdp, new_free, new_free, 0); | ||
744 | } | ||
745 | |||
746 | /** | ||
747 | * gfs2_stuffed_write_end - Write end for stuffed files | ||
748 | * @inode: The inode | ||
749 | * @dibh: The buffer_head containing the on-disk inode | ||
750 | * @pos: The file position | ||
751 | * @len: The length of the write | ||
752 | * @copied: How much was actually copied by the VFS | ||
753 | * @page: The page | ||
754 | * | ||
755 | * This copies the data from the page into the inode block after | ||
756 | * the inode data structure itself. | ||
757 | * | ||
758 | * Returns: errno | ||
759 | */ | ||
760 | static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, | ||
761 | loff_t pos, unsigned len, unsigned copied, | ||
762 | struct page *page) | ||
763 | { | ||
764 | struct gfs2_inode *ip = GFS2_I(inode); | ||
765 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
766 | u64 to = pos + copied; | ||
767 | void *kaddr; | ||
768 | unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode); | ||
769 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; | ||
770 | |||
771 | BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode))); | ||
772 | kaddr = kmap_atomic(page, KM_USER0); | ||
773 | memcpy(buf + pos, kaddr + pos, copied); | ||
774 | memset(kaddr + pos + copied, 0, len - copied); | ||
775 | flush_dcache_page(page); | ||
776 | kunmap_atomic(kaddr, KM_USER0); | ||
777 | |||
778 | if (!PageUptodate(page)) | ||
779 | SetPageUptodate(page); | ||
780 | unlock_page(page); | ||
781 | page_cache_release(page); | ||
782 | |||
783 | if (copied) { | ||
784 | if (inode->i_size < to) { | ||
785 | i_size_write(inode, to); | ||
786 | ip->i_disksize = inode->i_size; | ||
787 | } | ||
788 | gfs2_dinode_out(ip, di); | ||
789 | mark_inode_dirty(inode); | ||
790 | } | ||
791 | |||
792 | if (inode == sdp->sd_rindex) | ||
793 | adjust_fs_space(inode); | ||
794 | |||
795 | brelse(dibh); | ||
796 | gfs2_trans_end(sdp); | ||
797 | gfs2_glock_dq(&ip->i_gh); | ||
798 | gfs2_holder_uninit(&ip->i_gh); | ||
799 | return copied; | ||
800 | } | ||
801 | |||
802 | /** | ||
803 | * gfs2_write_end | ||
804 | * @file: The file to write to | ||
805 | * @mapping: The address space to write to | ||
806 | * @pos: The file position | ||
807 | * @len: The length of the data | ||
808 | * @copied: | ||
809 | * @page: The page that has been written | ||
810 | * @fsdata: The fsdata (unused in GFS2) | ||
811 | * | ||
812 | * The main write_end function for GFS2. We have a separate one for | ||
813 | * stuffed files as they are slightly different, otherwise we just | ||
814 | * put our locking around the VFS provided functions. | ||
815 | * | ||
816 | * Returns: errno | ||
817 | */ | ||
818 | |||
819 | static int gfs2_write_end(struct file *file, struct address_space *mapping, | ||
820 | loff_t pos, unsigned len, unsigned copied, | ||
821 | struct page *page, void *fsdata) | ||
822 | { | ||
823 | struct inode *inode = page->mapping->host; | ||
824 | struct gfs2_inode *ip = GFS2_I(inode); | ||
825 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
826 | struct buffer_head *dibh; | ||
827 | struct gfs2_alloc *al = ip->i_alloc; | ||
828 | unsigned int from = pos & (PAGE_CACHE_SIZE - 1); | ||
829 | unsigned int to = from + len; | ||
830 | int ret; | ||
831 | |||
832 | BUG_ON(gfs2_glock_is_locked_by_me(ip->i_gl) == NULL); | ||
833 | |||
834 | ret = gfs2_meta_inode_buffer(ip, &dibh); | ||
835 | if (unlikely(ret)) { | ||
836 | unlock_page(page); | ||
837 | page_cache_release(page); | ||
838 | goto failed; | ||
839 | } | ||
840 | |||
841 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
842 | |||
843 | if (gfs2_is_stuffed(ip)) | ||
844 | return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page); | ||
845 | |||
846 | if (!gfs2_is_writeback(ip)) | ||
847 | gfs2_page_add_databufs(ip, page, from, to); | ||
848 | |||
849 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | ||
850 | if (ret > 0) { | ||
851 | if (inode->i_size > ip->i_disksize) | ||
852 | ip->i_disksize = inode->i_size; | ||
853 | gfs2_dinode_out(ip, dibh->b_data); | ||
854 | mark_inode_dirty(inode); | ||
855 | } | ||
856 | |||
857 | if (inode == sdp->sd_rindex) | ||
858 | adjust_fs_space(inode); | ||
859 | |||
860 | brelse(dibh); | ||
861 | gfs2_trans_end(sdp); | ||
862 | failed: | ||
863 | if (al) { | ||
864 | gfs2_inplace_release(ip); | ||
865 | gfs2_quota_unlock(ip); | ||
866 | gfs2_alloc_put(ip); | ||
867 | } | ||
868 | gfs2_glock_dq(&ip->i_gh); | ||
869 | gfs2_holder_uninit(&ip->i_gh); | ||
870 | return ret; | ||
871 | } | ||
872 | |||
873 | /** | ||
874 | * gfs2_set_page_dirty - Page dirtying function | ||
875 | * @page: The page to dirty | ||
876 | * | ||
877 | * Returns: 1 if it dirtyed the page, or 0 otherwise | ||
878 | */ | ||
879 | |||
880 | static int gfs2_set_page_dirty(struct page *page) | ||
881 | { | ||
882 | SetPageChecked(page); | ||
883 | return __set_page_dirty_buffers(page); | ||
884 | } | ||
885 | |||
886 | /** | ||
887 | * gfs2_bmap - Block map function | ||
888 | * @mapping: Address space info | ||
889 | * @lblock: The block to map | ||
890 | * | ||
891 | * Returns: The disk address for the block or 0 on hole or error | ||
892 | */ | ||
893 | |||
894 | static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock) | ||
895 | { | ||
896 | struct gfs2_inode *ip = GFS2_I(mapping->host); | ||
897 | struct gfs2_holder i_gh; | ||
898 | sector_t dblock = 0; | ||
899 | int error; | ||
900 | |||
901 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | ||
902 | if (error) | ||
903 | return 0; | ||
904 | |||
905 | if (!gfs2_is_stuffed(ip)) | ||
906 | dblock = generic_block_bmap(mapping, lblock, gfs2_block_map); | ||
907 | |||
908 | gfs2_glock_dq_uninit(&i_gh); | ||
909 | |||
910 | return dblock; | ||
911 | } | ||
912 | |||
913 | static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh) | ||
914 | { | ||
915 | struct gfs2_bufdata *bd; | ||
916 | |||
917 | lock_buffer(bh); | ||
918 | gfs2_log_lock(sdp); | ||
919 | clear_buffer_dirty(bh); | ||
920 | bd = bh->b_private; | ||
921 | if (bd) { | ||
922 | if (!list_empty(&bd->bd_le.le_list) && !buffer_pinned(bh)) | ||
923 | list_del_init(&bd->bd_le.le_list); | ||
924 | else | ||
925 | gfs2_remove_from_journal(bh, current->journal_info, 0); | ||
926 | } | ||
927 | bh->b_bdev = NULL; | ||
928 | clear_buffer_mapped(bh); | ||
929 | clear_buffer_req(bh); | ||
930 | clear_buffer_new(bh); | ||
931 | gfs2_log_unlock(sdp); | ||
932 | unlock_buffer(bh); | ||
933 | } | ||
934 | |||
935 | static void gfs2_invalidatepage(struct page *page, unsigned long offset) | ||
936 | { | ||
937 | struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); | ||
938 | struct buffer_head *bh, *head; | ||
939 | unsigned long pos = 0; | ||
940 | |||
941 | BUG_ON(!PageLocked(page)); | ||
942 | if (offset == 0) | ||
943 | ClearPageChecked(page); | ||
944 | if (!page_has_buffers(page)) | ||
945 | goto out; | ||
946 | |||
947 | bh = head = page_buffers(page); | ||
948 | do { | ||
949 | if (offset <= pos) | ||
950 | gfs2_discard(sdp, bh); | ||
951 | pos += bh->b_size; | ||
952 | bh = bh->b_this_page; | ||
953 | } while (bh != head); | ||
954 | out: | ||
955 | if (offset == 0) | ||
956 | try_to_release_page(page, 0); | ||
957 | } | ||
958 | |||
959 | /** | ||
960 | * gfs2_ok_for_dio - check that dio is valid on this file | ||
961 | * @ip: The inode | ||
962 | * @rw: READ or WRITE | ||
963 | * @offset: The offset at which we are reading or writing | ||
964 | * | ||
965 | * Returns: 0 (to ignore the i/o request and thus fall back to buffered i/o) | ||
966 | * 1 (to accept the i/o request) | ||
967 | */ | ||
968 | static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset) | ||
969 | { | ||
970 | /* | ||
971 | * Should we return an error here? I can't see that O_DIRECT for | ||
972 | * a stuffed file makes any sense. For now we'll silently fall | ||
973 | * back to buffered I/O | ||
974 | */ | ||
975 | if (gfs2_is_stuffed(ip)) | ||
976 | return 0; | ||
977 | |||
978 | if (offset >= i_size_read(&ip->i_inode)) | ||
979 | return 0; | ||
980 | return 1; | ||
981 | } | ||
982 | |||
983 | |||
984 | |||
985 | static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | ||
986 | const struct iovec *iov, loff_t offset, | ||
987 | unsigned long nr_segs) | ||
988 | { | ||
989 | struct file *file = iocb->ki_filp; | ||
990 | struct inode *inode = file->f_mapping->host; | ||
991 | struct gfs2_inode *ip = GFS2_I(inode); | ||
992 | struct gfs2_holder gh; | ||
993 | int rv; | ||
994 | |||
995 | /* | ||
996 | * Deferred lock, even if its a write, since we do no allocation | ||
997 | * on this path. All we need change is atime, and this lock mode | ||
998 | * ensures that other nodes have flushed their buffered read caches | ||
999 | * (i.e. their page cache entries for this inode). We do not, | ||
1000 | * unfortunately have the option of only flushing a range like | ||
1001 | * the VFS does. | ||
1002 | */ | ||
1003 | gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, &gh); | ||
1004 | rv = gfs2_glock_nq(&gh); | ||
1005 | if (rv) | ||
1006 | return rv; | ||
1007 | rv = gfs2_ok_for_dio(ip, rw, offset); | ||
1008 | if (rv != 1) | ||
1009 | goto out; /* dio not valid, fall back to buffered i/o */ | ||
1010 | |||
1011 | rv = blockdev_direct_IO_no_locking(rw, iocb, inode, inode->i_sb->s_bdev, | ||
1012 | iov, offset, nr_segs, | ||
1013 | gfs2_get_block_direct, NULL); | ||
1014 | out: | ||
1015 | gfs2_glock_dq_m(1, &gh); | ||
1016 | gfs2_holder_uninit(&gh); | ||
1017 | return rv; | ||
1018 | } | ||
1019 | |||
1020 | /** | ||
1021 | * gfs2_releasepage - free the metadata associated with a page | ||
1022 | * @page: the page that's being released | ||
1023 | * @gfp_mask: passed from Linux VFS, ignored by us | ||
1024 | * | ||
1025 | * Call try_to_free_buffers() if the buffers in this page can be | ||
1026 | * released. | ||
1027 | * | ||
1028 | * Returns: 0 | ||
1029 | */ | ||
1030 | |||
1031 | int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | ||
1032 | { | ||
1033 | struct inode *aspace = page->mapping->host; | ||
1034 | struct gfs2_sbd *sdp = aspace->i_sb->s_fs_info; | ||
1035 | struct buffer_head *bh, *head; | ||
1036 | struct gfs2_bufdata *bd; | ||
1037 | |||
1038 | if (!page_has_buffers(page)) | ||
1039 | return 0; | ||
1040 | |||
1041 | gfs2_log_lock(sdp); | ||
1042 | head = bh = page_buffers(page); | ||
1043 | do { | ||
1044 | if (atomic_read(&bh->b_count)) | ||
1045 | goto cannot_release; | ||
1046 | bd = bh->b_private; | ||
1047 | if (bd && bd->bd_ail) | ||
1048 | goto cannot_release; | ||
1049 | gfs2_assert_warn(sdp, !buffer_pinned(bh)); | ||
1050 | gfs2_assert_warn(sdp, !buffer_dirty(bh)); | ||
1051 | bh = bh->b_this_page; | ||
1052 | } while(bh != head); | ||
1053 | gfs2_log_unlock(sdp); | ||
1054 | |||
1055 | head = bh = page_buffers(page); | ||
1056 | do { | ||
1057 | gfs2_log_lock(sdp); | ||
1058 | bd = bh->b_private; | ||
1059 | if (bd) { | ||
1060 | gfs2_assert_warn(sdp, bd->bd_bh == bh); | ||
1061 | gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr)); | ||
1062 | if (!list_empty(&bd->bd_le.le_list)) { | ||
1063 | if (!buffer_pinned(bh)) | ||
1064 | list_del_init(&bd->bd_le.le_list); | ||
1065 | else | ||
1066 | bd = NULL; | ||
1067 | } | ||
1068 | if (bd) | ||
1069 | bd->bd_bh = NULL; | ||
1070 | bh->b_private = NULL; | ||
1071 | } | ||
1072 | gfs2_log_unlock(sdp); | ||
1073 | if (bd) | ||
1074 | kmem_cache_free(gfs2_bufdata_cachep, bd); | ||
1075 | |||
1076 | bh = bh->b_this_page; | ||
1077 | } while (bh != head); | ||
1078 | |||
1079 | return try_to_free_buffers(page); | ||
1080 | cannot_release: | ||
1081 | gfs2_log_unlock(sdp); | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static const struct address_space_operations gfs2_writeback_aops = { | ||
1086 | .writepage = gfs2_writeback_writepage, | ||
1087 | .writepages = gfs2_writeback_writepages, | ||
1088 | .readpage = gfs2_readpage, | ||
1089 | .readpages = gfs2_readpages, | ||
1090 | .sync_page = block_sync_page, | ||
1091 | .write_begin = gfs2_write_begin, | ||
1092 | .write_end = gfs2_write_end, | ||
1093 | .bmap = gfs2_bmap, | ||
1094 | .invalidatepage = gfs2_invalidatepage, | ||
1095 | .releasepage = gfs2_releasepage, | ||
1096 | .direct_IO = gfs2_direct_IO, | ||
1097 | .migratepage = buffer_migrate_page, | ||
1098 | .is_partially_uptodate = block_is_partially_uptodate, | ||
1099 | }; | ||
1100 | |||
1101 | static const struct address_space_operations gfs2_ordered_aops = { | ||
1102 | .writepage = gfs2_ordered_writepage, | ||
1103 | .readpage = gfs2_readpage, | ||
1104 | .readpages = gfs2_readpages, | ||
1105 | .sync_page = block_sync_page, | ||
1106 | .write_begin = gfs2_write_begin, | ||
1107 | .write_end = gfs2_write_end, | ||
1108 | .set_page_dirty = gfs2_set_page_dirty, | ||
1109 | .bmap = gfs2_bmap, | ||
1110 | .invalidatepage = gfs2_invalidatepage, | ||
1111 | .releasepage = gfs2_releasepage, | ||
1112 | .direct_IO = gfs2_direct_IO, | ||
1113 | .migratepage = buffer_migrate_page, | ||
1114 | .is_partially_uptodate = block_is_partially_uptodate, | ||
1115 | }; | ||
1116 | |||
1117 | static const struct address_space_operations gfs2_jdata_aops = { | ||
1118 | .writepage = gfs2_jdata_writepage, | ||
1119 | .writepages = gfs2_jdata_writepages, | ||
1120 | .readpage = gfs2_readpage, | ||
1121 | .readpages = gfs2_readpages, | ||
1122 | .sync_page = block_sync_page, | ||
1123 | .write_begin = gfs2_write_begin, | ||
1124 | .write_end = gfs2_write_end, | ||
1125 | .set_page_dirty = gfs2_set_page_dirty, | ||
1126 | .bmap = gfs2_bmap, | ||
1127 | .invalidatepage = gfs2_invalidatepage, | ||
1128 | .releasepage = gfs2_releasepage, | ||
1129 | .is_partially_uptodate = block_is_partially_uptodate, | ||
1130 | }; | ||
1131 | |||
1132 | void gfs2_set_aops(struct inode *inode) | ||
1133 | { | ||
1134 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1135 | |||
1136 | if (gfs2_is_writeback(ip)) | ||
1137 | inode->i_mapping->a_ops = &gfs2_writeback_aops; | ||
1138 | else if (gfs2_is_ordered(ip)) | ||
1139 | inode->i_mapping->a_ops = &gfs2_ordered_aops; | ||
1140 | else if (gfs2_is_jdata(ip)) | ||
1141 | inode->i_mapping->a_ops = &gfs2_jdata_aops; | ||
1142 | else | ||
1143 | BUG(); | ||
1144 | } | ||
1145 | |||