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