Blame view

fs/gfs2/aops.c 29.6 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
7eabb77e6   Bob Peterson   [GFS2] Misc fixups
3
   * Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
4
5
6
   *
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
e9fc2aa09   Steven Whitehouse   [GFS2] Update cop...
7
   * of the GNU General Public License version 2.
b3b94faa5   David Teigland   [GFS2] The core o...
8
9
10
11
12
13
14
15
   */
  
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
  #include <linux/pagemap.h>
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
16
  #include <linux/pagevec.h>
9b124fbb8   Steven Whitehouse   [GFS2] Use mpage_...
17
  #include <linux/mpage.h>
d1665e414   Steven Whitehouse   [GFS2] Put back O...
18
  #include <linux/fs.h>
a8d638e30   Steven Whitehouse   [GFS2] Add writep...
19
  #include <linux/writeback.h>
7765ec26a   Steven Whitehouse   gfs2: convert to ...
20
  #include <linux/swap.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
21
  #include <linux/gfs2_ondisk.h>
47e83b509   Steven Whitehouse   [GFS2] Use correc...
22
  #include <linux/backing-dev.h>
b3b94faa5   David Teigland   [GFS2] The core o...
23
24
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
25
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
26
27
28
  #include "bmap.h"
  #include "glock.h"
  #include "inode.h"
b3b94faa5   David Teigland   [GFS2] The core o...
29
30
  #include "log.h"
  #include "meta_io.h"
b3b94faa5   David Teigland   [GFS2] The core o...
31
32
  #include "quota.h"
  #include "trans.h"
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
33
  #include "rgrp.h"
cd81a4bac   Robert Peterson   [GFS2] Addendum p...
34
  #include "super.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
35
  #include "util.h"
4340fe625   Steven Whitehouse   [GFS2] Add genera...
36
  #include "glops.h"
b3b94faa5   David Teigland   [GFS2] The core o...
37

ba7f72901   Steven Whitehouse   [GFS2] Remove pag...
38

3921120e7   Benjamin Marzinski   GFS2: fallocate s...
39
40
  void gfs2_page_add_databufs(struct gfs2_inode *ip, struct page *page,
  			    unsigned int from, unsigned int to)
ba7f72901   Steven Whitehouse   [GFS2] Remove pag...
41
42
43
44
45
46
47
48
49
50
51
  {
  	struct buffer_head *head = page_buffers(page);
  	unsigned int bsize = head->b_size;
  	struct buffer_head *bh;
  	unsigned int start, end;
  
  	for (bh = head, start = 0; bh != head || !start;
  	     bh = bh->b_this_page, start = end) {
  		end = start + bsize;
  		if (end <= from || start >= to)
  			continue;
ddf4b426a   Benjamin Marzinski   [GFS2] fix jdata ...
52
53
  		if (gfs2_is_jdata(ip))
  			set_buffer_uptodate(bh);
ba7f72901   Steven Whitehouse   [GFS2] Remove pag...
54
55
56
  		gfs2_trans_add_bh(ip->i_gl, bh, 0);
  	}
  }
b3b94faa5   David Teigland   [GFS2] The core o...
57
  /**
7a6bbacbb   Steven Whitehouse   [GFS2] Map multip...
58
   * gfs2_get_block_noalloc - Fills in a buffer head with details about a block
b3b94faa5   David Teigland   [GFS2] The core o...
59
60
61
62
63
64
65
   * @inode: The inode
   * @lblock: The block number to look up
   * @bh_result: The buffer head to return the result in
   * @create: Non-zero if we may add block to the file
   *
   * Returns: errno
   */
7a6bbacbb   Steven Whitehouse   [GFS2] Map multip...
66
67
  static int gfs2_get_block_noalloc(struct inode *inode, sector_t lblock,
  				  struct buffer_head *bh_result, int create)
b3b94faa5   David Teigland   [GFS2] The core o...
68
  {
b3b94faa5   David Teigland   [GFS2] The core o...
69
  	int error;
e9e1ef2b6   Bob Peterson   [GFS2] Remove fun...
70
  	error = gfs2_block_map(inode, lblock, bh_result, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
71
72
  	if (error)
  		return error;
de986e859   Wendy Cheng   [GFS2] Data corru...
73
  	if (!buffer_mapped(bh_result))
7a6bbacbb   Steven Whitehouse   [GFS2] Map multip...
74
75
  		return -EIO;
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
76
  }
7a6bbacbb   Steven Whitehouse   [GFS2] Map multip...
77
78
  static int gfs2_get_block_direct(struct inode *inode, sector_t lblock,
  				 struct buffer_head *bh_result, int create)
623d93555   Steven Whitehouse   [GFS2] Fix releas...
79
  {
e9e1ef2b6   Bob Peterson   [GFS2] Remove fun...
80
  	return gfs2_block_map(inode, lblock, bh_result, 0);
623d93555   Steven Whitehouse   [GFS2] Fix releas...
81
  }
7a6bbacbb   Steven Whitehouse   [GFS2] Map multip...
82

b3b94faa5   David Teigland   [GFS2] The core o...
83
  /**
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
84
85
86
   * gfs2_writepage_common - Common bits of writepage
   * @page: The page to be written
   * @wbc: The writeback control
b3b94faa5   David Teigland   [GFS2] The core o...
87
   *
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
88
   * Returns: 1 if writepage is ok, otherwise an error code or zero if no error.
b3b94faa5   David Teigland   [GFS2] The core o...
89
   */
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
90
91
  static int gfs2_writepage_common(struct page *page,
  				 struct writeback_control *wbc)
b3b94faa5   David Teigland   [GFS2] The core o...
92
  {
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
93
  	struct inode *inode = page->mapping->host;
f4387149e   Steven Whitehouse   [GFS2] Fix lack o...
94
95
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
96
97
98
  	loff_t i_size = i_size_read(inode);
  	pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
  	unsigned offset;
b3b94faa5   David Teigland   [GFS2] The core o...
99

9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
100
101
  	if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl)))
  		goto out;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
102
  	if (current->journal_info)
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
103
  		goto redirty;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
104
  	/* Is the page fully outside i_size? (truncate in progress) */
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
105
  	offset = i_size & (PAGE_CACHE_SIZE-1);
d2d7b8a2a   Steven Whitehouse   [GFS2] Fix bug in...
106
  	if (page->index > end_index || (page->index == end_index && !offset)) {
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
107
  		page->mapping->a_ops->invalidatepage(page, 0);
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
108
  		goto out;
b3b94faa5   David Teigland   [GFS2] The core o...
109
  	}
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  	return 1;
  redirty:
  	redirty_page_for_writepage(wbc, page);
  out:
  	unlock_page(page);
  	return 0;
  }
  
  /**
   * gfs2_writeback_writepage - Write page for writeback mappings
   * @page: The page
   * @wbc: The writeback control
   *
   */
  
  static int gfs2_writeback_writepage(struct page *page,
  				    struct writeback_control *wbc)
  {
  	int ret;
  
  	ret = gfs2_writepage_common(page, wbc);
  	if (ret <= 0)
  		return ret;
30116ff6c   Steven Whitehouse   GFS2: Use nobh_wr...
133
  	return nobh_writepage(page, gfs2_get_block_noalloc, wbc);
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  }
  
  /**
   * gfs2_ordered_writepage - Write page for ordered data files
   * @page: The page to write
   * @wbc: The writeback control
   *
   */
  
  static int gfs2_ordered_writepage(struct page *page,
  				  struct writeback_control *wbc)
  {
  	struct inode *inode = page->mapping->host;
  	struct gfs2_inode *ip = GFS2_I(inode);
  	int ret;
  
  	ret = gfs2_writepage_common(page, wbc);
  	if (ret <= 0)
  		return ret;
  
  	if (!page_has_buffers(page)) {
  		create_empty_buffers(page, inode->i_sb->s_blocksize,
  				     (1 << BH_Dirty)|(1 << BH_Uptodate));
  	}
  	gfs2_page_add_databufs(ip, page, 0, inode->i_sb->s_blocksize-1);
  	return block_write_full_page(page, gfs2_get_block_noalloc, wbc);
  }
  
  /**
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
   * __gfs2_jdata_writepage - The core of jdata writepage
   * @page: The page to write
   * @wbc: The writeback control
   *
   * This is shared between writepage and writepages and implements the
   * core of the writepage operation. If a transaction is required then
   * PageChecked will have been set and the transaction will have
   * already been started before this is called.
   */
  
  static int __gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc)
  {
  	struct inode *inode = page->mapping->host;
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
  
  	if (PageChecked(page)) {
  		ClearPageChecked(page);
  		if (!page_has_buffers(page)) {
  			create_empty_buffers(page, inode->i_sb->s_blocksize,
  					     (1 << BH_Dirty)|(1 << BH_Uptodate));
  		}
  		gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1);
  	}
  	return block_write_full_page(page, gfs2_get_block_noalloc, wbc);
  }
  
  /**
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
191
192
193
194
195
196
197
198
199
200
   * gfs2_jdata_writepage - Write complete page
   * @page: Page to write
   *
   * Returns: errno
   *
   */
  
  static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc)
  {
  	struct inode *inode = page->mapping->host;
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
201
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
1bb7322fd   Steven Whitehouse   GFS2: Fix up jdat...
202
  	int ret;
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
203
  	int done_trans = 0;
bf36a7131   Steven Whitehouse   [GFS2] Add gfs2_i...
204
  	if (PageChecked(page)) {
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
205
206
  		if (wbc->sync_mode != WB_SYNC_ALL)
  			goto out_ignore;
1bb7322fd   Steven Whitehouse   GFS2: Fix up jdat...
207
208
  		ret = gfs2_trans_begin(sdp, RES_DINODE + 1, 0);
  		if (ret)
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
209
  			goto out_ignore;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
210
211
  		done_trans = 1;
  	}
1bb7322fd   Steven Whitehouse   GFS2: Fix up jdat...
212
213
214
  	ret = gfs2_writepage_common(page, wbc);
  	if (ret > 0)
  		ret = __gfs2_jdata_writepage(page, wbc);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
215
216
  	if (done_trans)
  		gfs2_trans_end(sdp);
1bb7322fd   Steven Whitehouse   GFS2: Fix up jdat...
217
  	return ret;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
218
219
220
221
222
  
  out_ignore:
  	redirty_page_for_writepage(wbc, page);
  	unlock_page(page);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
223
224
225
  }
  
  /**
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
226
   * gfs2_writeback_writepages - Write a bunch of dirty pages back to disk
a8d638e30   Steven Whitehouse   [GFS2] Add writep...
227
228
229
   * @mapping: The mapping to write
   * @wbc: Write-back control
   *
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
230
   * For the data=writeback case we can already ignore buffer heads
a8d638e30   Steven Whitehouse   [GFS2] Add writep...
231
232
233
   * and write whole extents at once. This is a big reduction in the
   * number of I/O requests we send and the bmap calls we make in this case.
   */
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
234
235
  static int gfs2_writeback_writepages(struct address_space *mapping,
  				     struct writeback_control *wbc)
a8d638e30   Steven Whitehouse   [GFS2] Add writep...
236
  {
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
237
  	return mpage_writepages(mapping, wbc, gfs2_get_block_noalloc);
a8d638e30   Steven Whitehouse   [GFS2] Add writep...
238
239
240
  }
  
  /**
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
   * gfs2_write_jdata_pagevec - Write back a pagevec's worth of pages
   * @mapping: The mapping
   * @wbc: The writeback control
   * @writepage: The writepage function to call for each page
   * @pvec: The vector of pages
   * @nr_pages: The number of pages to write
   *
   * Returns: non-zero if loop should terminate, zero otherwise
   */
  
  static int gfs2_write_jdata_pagevec(struct address_space *mapping,
  				    struct writeback_control *wbc,
  				    struct pagevec *pvec,
  				    int nr_pages, pgoff_t end)
  {
  	struct inode *inode = mapping->host;
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
  	loff_t i_size = i_size_read(inode);
  	pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
  	unsigned offset = i_size & (PAGE_CACHE_SIZE-1);
  	unsigned nrblocks = nr_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize);
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
262
263
  	int i;
  	int ret;
20b95bf2c   Abhijith Das   [GFS2] gfs2_adjus...
264
  	ret = gfs2_trans_begin(sdp, nrblocks, nrblocks);
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  	if (ret < 0)
  		return ret;
  
  	for(i = 0; i < nr_pages; i++) {
  		struct page *page = pvec->pages[i];
  
  		lock_page(page);
  
  		if (unlikely(page->mapping != mapping)) {
  			unlock_page(page);
  			continue;
  		}
  
  		if (!wbc->range_cyclic && page->index > end) {
  			ret = 1;
  			unlock_page(page);
  			continue;
  		}
  
  		if (wbc->sync_mode != WB_SYNC_NONE)
  			wait_on_page_writeback(page);
  
  		if (PageWriteback(page) ||
  		    !clear_page_dirty_for_io(page)) {
  			unlock_page(page);
  			continue;
  		}
  
  		/* Is the page fully outside i_size? (truncate in progress) */
  		if (page->index > end_index || (page->index == end_index && !offset)) {
  			page->mapping->a_ops->invalidatepage(page, 0);
  			unlock_page(page);
  			continue;
  		}
  
  		ret = __gfs2_jdata_writepage(page, wbc);
  
  		if (ret || (--(wbc->nr_to_write) <= 0))
  			ret = 1;
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  	}
  	gfs2_trans_end(sdp);
  	return ret;
  }
  
  /**
   * gfs2_write_cache_jdata - Like write_cache_pages but different
   * @mapping: The mapping to write
   * @wbc: The writeback control
   * @writepage: The writepage function to call
   * @data: The data to pass to writepage
   *
   * The reason that we use our own function here is that we need to
   * start transactions before we grab page locks. This allows us
   * to get the ordering right.
   */
  
  static int gfs2_write_cache_jdata(struct address_space *mapping,
  				  struct writeback_control *wbc)
  {
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
324
325
326
327
328
329
330
331
  	int ret = 0;
  	int done = 0;
  	struct pagevec pvec;
  	int nr_pages;
  	pgoff_t index;
  	pgoff_t end;
  	int scanned = 0;
  	int range_whole = 0;
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
  	pagevec_init(&pvec, 0);
  	if (wbc->range_cyclic) {
  		index = mapping->writeback_index; /* Start from prev offset */
  		end = -1;
  	} else {
  		index = wbc->range_start >> PAGE_CACHE_SHIFT;
  		end = wbc->range_end >> PAGE_CACHE_SHIFT;
  		if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
  			range_whole = 1;
  		scanned = 1;
  	}
  
  retry:
  	 while (!done && (index <= end) &&
  		(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
  					       PAGECACHE_TAG_DIRTY,
  					       min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
  		scanned = 1;
  		ret = gfs2_write_jdata_pagevec(mapping, wbc, &pvec, nr_pages, end);
  		if (ret)
  			done = 1;
  		if (ret > 0)
  			ret = 0;
  
  		pagevec_release(&pvec);
  		cond_resched();
  	}
  
  	if (!scanned && !done) {
  		/*
  		 * We hit the last page and there is more work to be done: wrap
  		 * back to the start of the file
  		 */
  		scanned = 1;
  		index = 0;
  		goto retry;
  	}
  
  	if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
  		mapping->writeback_index = index;
  	return ret;
  }
  
  
  /**
   * gfs2_jdata_writepages - Write a bunch of dirty pages back to disk
   * @mapping: The mapping to write
   * @wbc: The writeback control
   * 
   */
  
  static int gfs2_jdata_writepages(struct address_space *mapping,
  				 struct writeback_control *wbc)
  {
  	struct gfs2_inode *ip = GFS2_I(mapping->host);
  	struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
  	int ret;
  
  	ret = gfs2_write_cache_jdata(mapping, wbc);
  	if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) {
  		gfs2_log_flush(sdp, ip->i_gl);
  		ret = gfs2_write_cache_jdata(mapping, wbc);
  	}
  	return ret;
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
399
400
401
402
403
404
405
406
407
408
   * stuffed_readpage - Fill in a Linux page with stuffed file data
   * @ip: the inode
   * @page: the page
   *
   * Returns: errno
   */
  
  static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
  {
  	struct buffer_head *dibh;
602c89d2e   Steven Whitehouse   GFS2: Clean up st...
409
  	u64 dsize = i_size_read(&ip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
410
411
  	void *kaddr;
  	int error;
bf126aee6   Steven Whitehouse   [GFS2] Patch to f...
412
  	/*
3c18ddd16   Nick Piggin   mm: remove nopage
413
  	 * Due to the order of unstuffing files and ->fault(), we can be
bf126aee6   Steven Whitehouse   [GFS2] Patch to f...
414
415
416
417
  	 * asked for a zero page in the case of a stuffed file being extended,
  	 * so we need to supply one here. It doesn't happen often.
  	 */
  	if (unlikely(page->index)) {
eebd2aa35   Christoph Lameter   Pagecache zeroing...
418
  		zero_user(page, 0, PAGE_CACHE_SIZE);
0a7ab79c5   Abhijith Das   GFS2: change gfs2...
419
  		SetPageUptodate(page);
bf126aee6   Steven Whitehouse   [GFS2] Patch to f...
420
421
  		return 0;
  	}
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
422

b3b94faa5   David Teigland   [GFS2] The core o...
423
424
425
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (error)
  		return error;
5c4e9e036   Steven Whitehouse   [GFS2] Fix a case...
426
  	kaddr = kmap_atomic(page, KM_USER0);
602c89d2e   Steven Whitehouse   GFS2: Clean up st...
427
428
429
430
  	if (dsize > (dibh->b_size - sizeof(struct gfs2_dinode)))
  		dsize = (dibh->b_size - sizeof(struct gfs2_dinode));
  	memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
  	memset(kaddr + dsize, 0, PAGE_CACHE_SIZE - dsize);
c312c4fdc   Russell Cattelan   [GFS2] Pass the c...
431
  	kunmap_atomic(kaddr, KM_USER0);
bf126aee6   Steven Whitehouse   [GFS2] Patch to f...
432
  	flush_dcache_page(page);
b3b94faa5   David Teigland   [GFS2] The core o...
433
  	brelse(dibh);
b3b94faa5   David Teigland   [GFS2] The core o...
434
435
436
437
  	SetPageUptodate(page);
  
  	return 0;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
438
439
  
  /**
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
440
441
   * __gfs2_readpage - readpage
   * @file: The file to read a page for
b3b94faa5   David Teigland   [GFS2] The core o...
442
443
   * @page: The page to read
   *
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
444
445
446
447
   * This is the core of gfs2's readpage. Its used by the internal file
   * reading code as in that case we already hold the glock. Also its
   * called by gfs2_readpage() once the required lock has been granted.
   *
b3b94faa5   David Teigland   [GFS2] The core o...
448
   */
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
449
  static int __gfs2_readpage(void *file, struct page *page)
b3b94faa5   David Teigland   [GFS2] The core o...
450
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
451
452
  	struct gfs2_inode *ip = GFS2_I(page->mapping->host);
  	struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
b3b94faa5   David Teigland   [GFS2] The core o...
453
  	int error;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
454
  	if (gfs2_is_stuffed(ip)) {
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
455
456
  		error = stuffed_readpage(ip, page);
  		unlock_page(page);
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
457
  	} else {
e9e1ef2b6   Bob Peterson   [GFS2] Remove fun...
458
  		error = mpage_readpage(page, gfs2_block_map);
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
459
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
460
461
  
  	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
462
  		return -EIO;
b3b94faa5   David Teigland   [GFS2] The core o...
463

51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
464
465
466
467
468
469
470
471
  	return error;
  }
  
  /**
   * gfs2_readpage - read a page of a file
   * @file: The file to read
   * @page: The page of the file
   *
01b7c7ae8   Steven Whitehouse   [GFS2] Revise rea...
472
473
474
   * This deals with the locking required. We have to unlock and
   * relock the page in order to get the locking in the right
   * order.
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
475
476
477
478
   */
  
  static int gfs2_readpage(struct file *file, struct page *page)
  {
01b7c7ae8   Steven Whitehouse   [GFS2] Revise rea...
479
480
  	struct address_space *mapping = page->mapping;
  	struct gfs2_inode *ip = GFS2_I(mapping->host);
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
481
  	struct gfs2_holder gh;
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
482
  	int error;
01b7c7ae8   Steven Whitehouse   [GFS2] Revise rea...
483
  	unlock_page(page);
719ee3446   Steven Whitehouse   GFS2: high time t...
484
485
  	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
  	error = gfs2_glock_nq(&gh);
01b7c7ae8   Steven Whitehouse   [GFS2] Revise rea...
486
  	if (unlikely(error))
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
487
  		goto out;
01b7c7ae8   Steven Whitehouse   [GFS2] Revise rea...
488
489
490
491
492
493
  	error = AOP_TRUNCATED_PAGE;
  	lock_page(page);
  	if (page->mapping == mapping && !PageUptodate(page))
  		error = __gfs2_readpage(file, page);
  	else
  		unlock_page(page);
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
494
  	gfs2_glock_dq(&gh);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
495
  out:
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
496
  	gfs2_holder_uninit(&gh);
01b7c7ae8   Steven Whitehouse   [GFS2] Revise rea...
497
498
  	if (error && error != AOP_TRUNCATED_PAGE)
  		lock_page(page);
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
  	return error;
  }
  
  /**
   * gfs2_internal_read - read an internal file
   * @ip: The gfs2 inode
   * @ra_state: The readahead state (or NULL for no readahead)
   * @buf: The buffer to fill
   * @pos: The file position
   * @size: The amount to read
   *
   */
  
  int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state,
                         char *buf, loff_t *pos, unsigned size)
  {
  	struct address_space *mapping = ip->i_inode.i_mapping;
  	unsigned long index = *pos / PAGE_CACHE_SIZE;
  	unsigned offset = *pos & (PAGE_CACHE_SIZE - 1);
  	unsigned copied = 0;
  	unsigned amt;
  	struct page *page;
  	void *p;
  
  	do {
  		amt = size - copied;
  		if (offset + size > PAGE_CACHE_SIZE)
  			amt = PAGE_CACHE_SIZE - offset;
  		page = read_cache_page(mapping, index, __gfs2_readpage, NULL);
  		if (IS_ERR(page))
  			return PTR_ERR(page);
  		p = kmap_atomic(page, KM_USER0);
  		memcpy(buf + copied, p + offset, amt);
  		kunmap_atomic(p, KM_USER0);
  		mark_page_accessed(page);
  		page_cache_release(page);
  		copied += amt;
  		index++;
  		offset = 0;
  	} while(copied < size);
  	(*pos) += size;
  	return size;
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
541
  }
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
542
543
544
545
546
547
548
549
550
  /**
   * gfs2_readpages - Read a bunch of pages at once
   *
   * Some notes:
   * 1. This is only for readahead, so we can simply ignore any things
   *    which are slightly inconvenient (such as locking conflicts between
   *    the page lock and the glock) and return having done no I/O. Its
   *    obviously not something we'd want to do on too regular a basis.
   *    Any I/O we ignore at this time will be done via readpage later.
e1d5b18ae   Steven Whitehouse   [GFS2] Fail over ...
551
   * 2. We don't handle stuffed files here we let readpage do the honours.
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
552
   * 3. mpage_readpages() does most of the heavy lifting in the common case.
e9e1ef2b6   Bob Peterson   [GFS2] Remove fun...
553
   * 4. gfs2_block_map() is relied upon to set BH_Boundary in the right places.
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
554
   */
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
555

fd88de569   Steven Whitehouse   [GFS2] Readpages ...
556
557
558
559
  static int gfs2_readpages(struct file *file, struct address_space *mapping,
  			  struct list_head *pages, unsigned nr_pages)
  {
  	struct inode *inode = mapping->host;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
560
561
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
562
  	struct gfs2_holder gh;
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
563
  	int ret;
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
564

719ee3446   Steven Whitehouse   GFS2: high time t...
565
566
  	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
  	ret = gfs2_glock_nq(&gh);
51ff87bdd   Steven Whitehouse   [GFS2] Clean up i...
567
  	if (unlikely(ret))
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
568
  		goto out_uninit;
e1d5b18ae   Steven Whitehouse   [GFS2] Fail over ...
569
  	if (!gfs2_is_stuffed(ip))
e9e1ef2b6   Bob Peterson   [GFS2] Remove fun...
570
  		ret = mpage_readpages(mapping, pages, nr_pages, gfs2_block_map);
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
571
572
573
  	gfs2_glock_dq(&gh);
  out_uninit:
  	gfs2_holder_uninit(&gh);
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
574
575
576
  	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
  		ret = -EIO;
  	return ret;
b3b94faa5   David Teigland   [GFS2] The core o...
577
578
579
  }
  
  /**
7765ec26a   Steven Whitehouse   gfs2: convert to ...
580
   * gfs2_write_begin - Begin to write to a file
b3b94faa5   David Teigland   [GFS2] The core o...
581
   * @file: The file to write to
7765ec26a   Steven Whitehouse   gfs2: convert to ...
582
583
584
585
586
587
   * @mapping: The mapping in which to write
   * @pos: The file offset at which to start writing
   * @len: Length of the write
   * @flags: Various flags
   * @pagep: Pointer to return the page
   * @fsdata: Pointer to return fs data (unused by GFS2)
b3b94faa5   David Teigland   [GFS2] The core o...
588
589
590
   *
   * Returns: errno
   */
7765ec26a   Steven Whitehouse   gfs2: convert to ...
591
592
593
  static int gfs2_write_begin(struct file *file, struct address_space *mapping,
  			    loff_t pos, unsigned len, unsigned flags,
  			    struct page **pagep, void **fsdata)
b3b94faa5   David Teigland   [GFS2] The core o...
594
  {
7765ec26a   Steven Whitehouse   gfs2: convert to ...
595
596
  	struct gfs2_inode *ip = GFS2_I(mapping->host);
  	struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
597
  	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
7ed122e42   Steven Whitehouse   GFS2: Streamline ...
598
  	unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
599
  	int alloc_required;
b3b94faa5   David Teigland   [GFS2] The core o...
600
  	int error = 0;
564e12b11   Bob Peterson   GFS2: decouple qu...
601
  	struct gfs2_qadata *qa = NULL;
7765ec26a   Steven Whitehouse   gfs2: convert to ...
602
603
  	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
  	unsigned from = pos & (PAGE_CACHE_SIZE - 1);
7765ec26a   Steven Whitehouse   gfs2: convert to ...
604
  	struct page *page;
52ae7b793   Russell Cattelan   [GFS2] Fix a size...
605

719ee3446   Steven Whitehouse   GFS2: high time t...
606
607
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
  	error = gfs2_glock_nq(&ip->i_gh);
7765ec26a   Steven Whitehouse   gfs2: convert to ...
608
  	if (unlikely(error))
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
609
  		goto out_uninit;
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
610
611
612
613
614
615
616
617
  	if (&ip->i_inode == sdp->sd_rindex) {
  		error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE,
  					   GL_NOCACHE, &m_ip->i_gh);
  		if (unlikely(error)) {
  			gfs2_glock_dq(&ip->i_gh);
  			goto out_uninit;
  		}
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
618

461cb419f   Bob Peterson   GFS2: Simplify gf...
619
  	alloc_required = gfs2_write_alloc_required(ip, pos, len);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
620

7ed122e42   Steven Whitehouse   GFS2: Streamline ...
621
622
  	if (alloc_required || gfs2_is_jdata(ip))
  		gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
623
  	if (alloc_required) {
564e12b11   Bob Peterson   GFS2: decouple qu...
624
625
  		qa = gfs2_qadata_get(ip);
  		if (!qa) {
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
626
627
628
  			error = -ENOMEM;
  			goto out_unlock;
  		}
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
629

d82661d96   Steven Whitehouse   [GFS2] Streamline...
630
  		error = gfs2_quota_lock_check(ip);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
631
632
  		if (error)
  			goto out_alloc_put;
564e12b11   Bob Peterson   GFS2: decouple qu...
633
  		error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
634
635
636
637
638
639
640
641
642
  		if (error)
  			goto out_qunlock;
  	}
  
  	rblocks = RES_DINODE + ind_blocks;
  	if (gfs2_is_jdata(ip))
  		rblocks += data_blocks ? data_blocks : 1;
  	if (ind_blocks || data_blocks)
  		rblocks += RES_STATFS + RES_QUOTA;
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
643
644
  	if (&ip->i_inode == sdp->sd_rindex)
  		rblocks += 2 * RES_STATFS;
bf97b6734   Benjamin Marzinski   GFS2: reserve mor...
645
  	if (alloc_required)
54335b1fc   Steven Whitehouse   GFS2: Cache the m...
646
  		rblocks += gfs2_rg_blocks(ip);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
647

16615be18   Steven Whitehouse   [GFS2] Clean up j...
648
649
  	error = gfs2_trans_begin(sdp, rblocks,
  				 PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
650
  	if (error)
a867bb28c   Steven Whitehouse   [GFS2] Fix incorr...
651
  		goto out_trans_fail;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
652

c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
653
  	error = -ENOMEM;
e4fefbac6   Steven Whitehouse   GFS2: Set GFP_NOF...
654
  	flags |= AOP_FLAG_NOFS;
54566b2c1   Nick Piggin   fs: symlink write...
655
  	page = grab_cache_page_write_begin(mapping, index, flags);
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
656
657
658
  	*pagep = page;
  	if (unlikely(!page))
  		goto out_endtrans;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
659
  	if (gfs2_is_stuffed(ip)) {
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
660
  		error = 0;
7765ec26a   Steven Whitehouse   gfs2: convert to ...
661
  		if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
f25ef0c1b   Steven Whitehouse   [GFS2] Tidy gfs2_...
662
  			error = gfs2_unstuff_dinode(ip, page);
5c4e9e036   Steven Whitehouse   [GFS2] Fix a case...
663
664
  			if (error == 0)
  				goto prepare_write;
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
665
  		} else if (!PageUptodate(page)) {
b3b94faa5   David Teigland   [GFS2] The core o...
666
  			error = stuffed_readpage(ip, page);
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
667
  		}
5c4e9e036   Steven Whitehouse   [GFS2] Fix a case...
668
  		goto out;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
669
  	}
5c4e9e036   Steven Whitehouse   [GFS2] Fix a case...
670
  prepare_write:
ebdec241d   Christoph Hellwig   fs: kill block_pr...
671
  	error = __block_write_begin(page, from, len, gfs2_block_map);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
672
  out:
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
673
674
  	if (error == 0)
  		return 0;
6c474f7bc   Maxim   GFS2: Adding miss...
675
  	unlock_page(page);
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
676
  	page_cache_release(page);
15c6fd978   npiggin@suse.de   kill spurious ref...
677

ff8f33c8b   Steven Whitehouse   GFS2: New truncat...
678
  	gfs2_trans_end(sdp);
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
679
  	if (pos + len > ip->i_inode.i_size)
ff8f33c8b   Steven Whitehouse   GFS2: New truncat...
680
681
  		gfs2_trim_blocks(&ip->i_inode);
  	goto out_trans_fail;
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
682
683
  out_endtrans:
  	gfs2_trans_end(sdp);
a867bb28c   Steven Whitehouse   [GFS2] Fix incorr...
684
  out_trans_fail:
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
685
686
  	if (alloc_required) {
  		gfs2_inplace_release(ip);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
687
  out_qunlock:
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
688
  		gfs2_quota_unlock(ip);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
689
  out_alloc_put:
564e12b11   Bob Peterson   GFS2: decouple qu...
690
  		gfs2_qadata_put(ip);
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
691
  	}
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
692
  out_unlock:
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
693
694
695
696
  	if (&ip->i_inode == sdp->sd_rindex) {
  		gfs2_glock_dq(&m_ip->i_gh);
  		gfs2_holder_uninit(&m_ip->i_gh);
  	}
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
697
  	gfs2_glock_dq(&ip->i_gh);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
698
  out_uninit:
c41d4f09f   Steven Whitehouse   [GFS2] Don't hold...
699
  	gfs2_holder_uninit(&ip->i_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
700
701
702
703
  	return error;
  }
  
  /**
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
704
705
706
707
708
709
   * adjust_fs_space - Adjusts the free space available due to gfs2_grow
   * @inode: the rindex inode
   */
  static void adjust_fs_space(struct inode *inode)
  {
  	struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
710
711
  	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
  	struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
712
713
  	struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
  	struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
714
  	struct buffer_head *m_bh, *l_bh;
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
715
716
717
718
  	u64 fs_total, new_free;
  
  	/* Total up the file system space, according to the latest rindex. */
  	fs_total = gfs2_ri_total(sdp);
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
719
720
  	if (gfs2_meta_inode_buffer(m_ip, &m_bh) != 0)
  		return;
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
721
722
  
  	spin_lock(&sdp->sd_statfs_spin);
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
723
724
  	gfs2_statfs_change_in(m_sc, m_bh->b_data +
  			      sizeof(struct gfs2_dinode));
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
725
726
727
728
729
  	if (fs_total > (m_sc->sc_total + l_sc->sc_total))
  		new_free = fs_total - (m_sc->sc_total + l_sc->sc_total);
  	else
  		new_free = 0;
  	spin_unlock(&sdp->sd_statfs_spin);
6c53267f0   Robert Peterson   [GFS2] Kernel cha...
730
731
732
  	fs_warn(sdp, "File system extended by %llu blocks.
  ",
  		(unsigned long long)new_free);
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
733
  	gfs2_statfs_change(sdp, new_free, new_free, 0);
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
734
735
736
737
738
739
740
  
  	if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0)
  		goto out;
  	update_statfs(sdp, m_bh, l_bh);
  	brelse(l_bh);
  out:
  	brelse(m_bh);
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
741
742
743
  }
  
  /**
7765ec26a   Steven Whitehouse   gfs2: convert to ...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
   * gfs2_stuffed_write_end - Write end for stuffed files
   * @inode: The inode
   * @dibh: The buffer_head containing the on-disk inode
   * @pos: The file position
   * @len: The length of the write
   * @copied: How much was actually copied by the VFS
   * @page: The page
   *
   * This copies the data from the page into the inode block after
   * the inode data structure itself.
   *
   * Returns: errno
   */
  static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
  				  loff_t pos, unsigned len, unsigned copied,
  				  struct page *page)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
763
  	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
7765ec26a   Steven Whitehouse   gfs2: convert to ...
764
765
766
  	u64 to = pos + copied;
  	void *kaddr;
  	unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode);
7765ec26a   Steven Whitehouse   gfs2: convert to ...
767
768
769
770
771
772
773
774
775
776
777
778
  
  	BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode)));
  	kaddr = kmap_atomic(page, KM_USER0);
  	memcpy(buf + pos, kaddr + pos, copied);
  	memset(kaddr + pos + copied, 0, len - copied);
  	flush_dcache_page(page);
  	kunmap_atomic(kaddr, KM_USER0);
  
  	if (!PageUptodate(page))
  		SetPageUptodate(page);
  	unlock_page(page);
  	page_cache_release(page);
7537d81aa   Abhijith Das   GFS2: Fix timesta...
779
  	if (copied) {
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
780
  		if (inode->i_size < to)
7537d81aa   Abhijith Das   GFS2: Fix timesta...
781
  			i_size_write(inode, to);
7765ec26a   Steven Whitehouse   gfs2: convert to ...
782
783
  		mark_inode_dirty(inode);
  	}
9ae3c6de6   Benjamin Marzinski   GFS2: drop rindex...
784
  	if (inode == sdp->sd_rindex) {
7765ec26a   Steven Whitehouse   gfs2: convert to ...
785
  		adjust_fs_space(inode);
9ae3c6de6   Benjamin Marzinski   GFS2: drop rindex...
786
787
  		ip->i_gh.gh_flags |= GL_NOCACHE;
  	}
7765ec26a   Steven Whitehouse   gfs2: convert to ...
788
789
790
  
  	brelse(dibh);
  	gfs2_trans_end(sdp);
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
791
792
793
794
  	if (inode == sdp->sd_rindex) {
  		gfs2_glock_dq(&m_ip->i_gh);
  		gfs2_holder_uninit(&m_ip->i_gh);
  	}
7765ec26a   Steven Whitehouse   gfs2: convert to ...
795
796
797
798
799
800
801
  	gfs2_glock_dq(&ip->i_gh);
  	gfs2_holder_uninit(&ip->i_gh);
  	return copied;
  }
  
  /**
   * gfs2_write_end
b3b94faa5   David Teigland   [GFS2] The core o...
802
   * @file: The file to write to
7765ec26a   Steven Whitehouse   gfs2: convert to ...
803
804
805
806
807
808
809
810
811
812
   * @mapping: The address space to write to
   * @pos: The file position
   * @len: The length of the data
   * @copied:
   * @page: The page that has been written
   * @fsdata: The fsdata (unused in GFS2)
   *
   * The main write_end function for GFS2. We have a separate one for
   * stuffed files as they are slightly different, otherwise we just
   * put our locking around the VFS provided functions.
b3b94faa5   David Teigland   [GFS2] The core o...
813
814
815
   *
   * Returns: errno
   */
7765ec26a   Steven Whitehouse   gfs2: convert to ...
816
817
818
  static int gfs2_write_end(struct file *file, struct address_space *mapping,
  			  loff_t pos, unsigned len, unsigned copied,
  			  struct page *page, void *fsdata)
b3b94faa5   David Teigland   [GFS2] The core o...
819
820
  {
  	struct inode *inode = page->mapping->host;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
821
822
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
823
  	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
824
  	struct buffer_head *dibh;
564e12b11   Bob Peterson   GFS2: decouple qu...
825
  	struct gfs2_qadata *qa = ip->i_qadata;
7765ec26a   Steven Whitehouse   gfs2: convert to ...
826
827
828
  	unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
  	unsigned int to = from + len;
  	int ret;
b3b94faa5   David Teigland   [GFS2] The core o...
829

7afd88d91   Steven Whitehouse   [GFS2] Fix a page...
830
  	BUG_ON(gfs2_glock_is_locked_by_me(ip->i_gl) == NULL);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
831

7765ec26a   Steven Whitehouse   gfs2: convert to ...
832
833
834
835
836
837
  	ret = gfs2_meta_inode_buffer(ip, &dibh);
  	if (unlikely(ret)) {
  		unlock_page(page);
  		page_cache_release(page);
  		goto failed;
  	}
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
838
839
  
  	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
840

7765ec26a   Steven Whitehouse   gfs2: convert to ...
841
842
  	if (gfs2_is_stuffed(ip))
  		return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page);
b3b94faa5   David Teigland   [GFS2] The core o...
843

bf36a7131   Steven Whitehouse   [GFS2] Add gfs2_i...
844
  	if (!gfs2_is_writeback(ip))
7765ec26a   Steven Whitehouse   gfs2: convert to ...
845
  		gfs2_page_add_databufs(ip, page, from, to);
b3b94faa5   David Teigland   [GFS2] The core o...
846

7765ec26a   Steven Whitehouse   gfs2: convert to ...
847
  	ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
48516ced2   Steven Whitehouse   [GFS2] Remove une...
848

9ae3c6de6   Benjamin Marzinski   GFS2: drop rindex...
849
  	if (inode == sdp->sd_rindex) {
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
850
  		adjust_fs_space(inode);
9ae3c6de6   Benjamin Marzinski   GFS2: drop rindex...
851
852
  		ip->i_gh.gh_flags |= GL_NOCACHE;
  	}
7ae8fa845   Robert Peterson   [GFS2] kernel cha...
853

18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
854
  	brelse(dibh);
7765ec26a   Steven Whitehouse   gfs2: convert to ...
855
  failed:
deab72d37   Bob Peterson   GFS2: write_end e...
856
  	gfs2_trans_end(sdp);
564e12b11   Bob Peterson   GFS2: decouple qu...
857
  	if (ip->i_res)
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
858
  		gfs2_inplace_release(ip);
564e12b11   Bob Peterson   GFS2: decouple qu...
859
  	if (qa) {
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
860
  		gfs2_quota_unlock(ip);
564e12b11   Bob Peterson   GFS2: decouple qu...
861
  		gfs2_qadata_put(ip);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
862
  	}
1946f70ab   Benjamin Marzinski   GFS2: keep statfs...
863
864
865
866
  	if (inode == sdp->sd_rindex) {
  		gfs2_glock_dq(&m_ip->i_gh);
  		gfs2_holder_uninit(&m_ip->i_gh);
  	}
7765ec26a   Steven Whitehouse   gfs2: convert to ...
867
  	gfs2_glock_dq(&ip->i_gh);
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
868
  	gfs2_holder_uninit(&ip->i_gh);
7765ec26a   Steven Whitehouse   gfs2: convert to ...
869
  	return ret;
b3b94faa5   David Teigland   [GFS2] The core o...
870
871
872
  }
  
  /**
8fb68595d   Robert Peterson   [GFS2] Journaled ...
873
874
875
876
877
878
879
880
   * gfs2_set_page_dirty - Page dirtying function
   * @page: The page to dirty
   *
   * Returns: 1 if it dirtyed the page, or 0 otherwise
   */
   
  static int gfs2_set_page_dirty(struct page *page)
  {
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
881
  	SetPageChecked(page);
8fb68595d   Robert Peterson   [GFS2] Journaled ...
882
883
884
885
  	return __set_page_dirty_buffers(page);
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
886
887
888
889
890
891
892
893
894
   * gfs2_bmap - Block map function
   * @mapping: Address space info
   * @lblock: The block to map
   *
   * Returns: The disk address for the block or 0 on hole or error
   */
  
  static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
895
  	struct gfs2_inode *ip = GFS2_I(mapping->host);
b3b94faa5   David Teigland   [GFS2] The core o...
896
897
898
  	struct gfs2_holder i_gh;
  	sector_t dblock = 0;
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
899
900
901
902
903
  	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
  	if (error)
  		return 0;
  
  	if (!gfs2_is_stuffed(ip))
e9e1ef2b6   Bob Peterson   [GFS2] Remove fun...
904
  		dblock = generic_block_bmap(mapping, lblock, gfs2_block_map);
b3b94faa5   David Teigland   [GFS2] The core o...
905
906
907
908
909
  
  	gfs2_glock_dq_uninit(&i_gh);
  
  	return dblock;
  }
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
910
911
912
913
914
915
916
917
918
  static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh)
  {
  	struct gfs2_bufdata *bd;
  
  	lock_buffer(bh);
  	gfs2_log_lock(sdp);
  	clear_buffer_dirty(bh);
  	bd = bh->b_private;
  	if (bd) {
16615be18   Steven Whitehouse   [GFS2] Clean up j...
919
920
921
922
  		if (!list_empty(&bd->bd_le.le_list) && !buffer_pinned(bh))
  			list_del_init(&bd->bd_le.le_list);
  		else
  			gfs2_remove_from_journal(bh, current->journal_info, 0);
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
923
924
925
926
927
928
929
930
  	}
  	bh->b_bdev = NULL;
  	clear_buffer_mapped(bh);
  	clear_buffer_req(bh);
  	clear_buffer_new(bh);
  	gfs2_log_unlock(sdp);
  	unlock_buffer(bh);
  }
8628de058   Steven Whitehouse   [GFS2] Update GFS...
931
  static void gfs2_invalidatepage(struct page *page, unsigned long offset)
b3b94faa5   David Teigland   [GFS2] The core o...
932
  {
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
933
934
935
  	struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
  	struct buffer_head *bh, *head;
  	unsigned long pos = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
936
  	BUG_ON(!PageLocked(page));
8fb68595d   Robert Peterson   [GFS2] Journaled ...
937
938
  	if (offset == 0)
  		ClearPageChecked(page);
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
939
940
  	if (!page_has_buffers(page))
  		goto out;
b3b94faa5   David Teigland   [GFS2] The core o...
941

d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
942
943
944
945
946
947
948
949
950
951
  	bh = head = page_buffers(page);
  	do {
  		if (offset <= pos)
  			gfs2_discard(sdp, bh);
  		pos += bh->b_size;
  		bh = bh->b_this_page;
  	} while (bh != head);
  out:
  	if (offset == 0)
  		try_to_release_page(page, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
952
  }
c7b338343   Steven Whitehouse   [GFS2] Fix DIO de...
953
954
955
956
957
958
959
960
961
962
963
964
965
  /**
   * gfs2_ok_for_dio - check that dio is valid on this file
   * @ip: The inode
   * @rw: READ or WRITE
   * @offset: The offset at which we are reading or writing
   *
   * Returns: 0 (to ignore the i/o request and thus fall back to buffered i/o)
   *          1 (to accept the i/o request)
   */
  static int gfs2_ok_for_dio(struct gfs2_inode *ip, int rw, loff_t offset)
  {
  	/*
  	 * Should we return an error here? I can't see that O_DIRECT for
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
966
967
  	 * a stuffed file makes any sense. For now we'll silently fall
  	 * back to buffered I/O
c7b338343   Steven Whitehouse   [GFS2] Fix DIO de...
968
  	 */
c7b338343   Steven Whitehouse   [GFS2] Fix DIO de...
969
970
  	if (gfs2_is_stuffed(ip))
  		return 0;
acb57a365   Bob Peterson   GFS2: Direct IO w...
971
  	if (offset >= i_size_read(&ip->i_inode))
c7b338343   Steven Whitehouse   [GFS2] Fix DIO de...
972
973
974
  		return 0;
  	return 1;
  }
a9e5f4d07   Steven Whitehouse   [GFS2] Alter dire...
975
976
977
  static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
  			      const struct iovec *iov, loff_t offset,
  			      unsigned long nr_segs)
d1665e414   Steven Whitehouse   [GFS2] Put back O...
978
979
980
  {
  	struct file *file = iocb->ki_filp;
  	struct inode *inode = file->f_mapping->host;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
981
  	struct gfs2_inode *ip = GFS2_I(inode);
d1665e414   Steven Whitehouse   [GFS2] Put back O...
982
983
984
985
  	struct gfs2_holder gh;
  	int rv;
  
  	/*
c7b338343   Steven Whitehouse   [GFS2] Fix DIO de...
986
987
988
989
990
991
  	 * Deferred lock, even if its a write, since we do no allocation
  	 * on this path. All we need change is atime, and this lock mode
  	 * ensures that other nodes have flushed their buffered read caches
  	 * (i.e. their page cache entries for this inode). We do not,
  	 * unfortunately have the option of only flushing a range like
  	 * the VFS does.
d1665e414   Steven Whitehouse   [GFS2] Put back O...
992
  	 */
719ee3446   Steven Whitehouse   GFS2: high time t...
993
994
  	gfs2_holder_init(ip->i_gl, LM_ST_DEFERRED, 0, &gh);
  	rv = gfs2_glock_nq(&gh);
d1665e414   Steven Whitehouse   [GFS2] Put back O...
995
  	if (rv)
c7b338343   Steven Whitehouse   [GFS2] Fix DIO de...
996
997
998
999
  		return rv;
  	rv = gfs2_ok_for_dio(ip, rw, offset);
  	if (rv != 1)
  		goto out; /* dio not valid, fall back to buffered i/o */
eafdc7d19   Christoph Hellwig   sort out blockdev...
1000
1001
1002
  	rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
  				  offset, nr_segs, gfs2_get_block_direct,
  				  NULL, NULL, 0);
d1665e414   Steven Whitehouse   [GFS2] Put back O...
1003
1004
1005
  out:
  	gfs2_glock_dq_m(1, &gh);
  	gfs2_holder_uninit(&gh);
d1665e414   Steven Whitehouse   [GFS2] Put back O...
1006
1007
1008
1009
  	return rv;
  }
  
  /**
623d93555   Steven Whitehouse   [GFS2] Fix releas...
1010
   * gfs2_releasepage - free the metadata associated with a page
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
   * @page: the page that's being released
   * @gfp_mask: passed from Linux VFS, ignored by us
   *
   * Call try_to_free_buffers() if the buffers in this page can be
   * released.
   *
   * Returns: 0
   */
  
  int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
  {
009d85183   Steven Whitehouse   GFS2: Metadata ad...
1022
1023
  	struct address_space *mapping = page->mapping;
  	struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping);
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1024
1025
  	struct buffer_head *bh, *head;
  	struct gfs2_bufdata *bd;
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1026
1027
  
  	if (!page_has_buffers(page))
891ba6d4a   Steven Whitehouse   [GFS2] Don't try ...
1028
  		return 0;
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1029

bb3b0e3df   Steven Whitehouse   [GFS2] Clean up i...
1030
  	gfs2_log_lock(sdp);
380f7c65a   Steven Whitehouse   GFS2: Resolve ino...
1031
  	spin_lock(&sdp->sd_ail_lock);
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1032
1033
  	head = bh = page_buffers(page);
  	do {
bb3b0e3df   Steven Whitehouse   [GFS2] Clean up i...
1034
1035
1036
1037
1038
  		if (atomic_read(&bh->b_count))
  			goto cannot_release;
  		bd = bh->b_private;
  		if (bd && bd->bd_ail)
  			goto cannot_release;
8f065d365   Steven Whitehouse   GFS2: Improve bug...
1039
1040
  		if (buffer_pinned(bh) || buffer_dirty(bh))
  			goto not_possible;
bb3b0e3df   Steven Whitehouse   [GFS2] Clean up i...
1041
1042
  		bh = bh->b_this_page;
  	} while(bh != head);
380f7c65a   Steven Whitehouse   GFS2: Resolve ino...
1043
  	spin_unlock(&sdp->sd_ail_lock);
bb3b0e3df   Steven Whitehouse   [GFS2] Clean up i...
1044
  	gfs2_log_unlock(sdp);
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1045

bb3b0e3df   Steven Whitehouse   [GFS2] Clean up i...
1046
1047
  	head = bh = page_buffers(page);
  	do {
623d93555   Steven Whitehouse   [GFS2] Fix releas...
1048
  		gfs2_log_lock(sdp);
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1049
1050
1051
1052
  		bd = bh->b_private;
  		if (bd) {
  			gfs2_assert_warn(sdp, bd->bd_bh == bh);
  			gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr));
d7b616e25   Steven Whitehouse   [GFS2] Clean up o...
1053
1054
1055
1056
1057
1058
1059
1060
  			if (!list_empty(&bd->bd_le.le_list)) {
  				if (!buffer_pinned(bh))
  					list_del_init(&bd->bd_le.le_list);
  				else
  					bd = NULL;
  			}
  			if (bd)
  				bd->bd_bh = NULL;
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1061
1062
  			bh->b_private = NULL;
  		}
623d93555   Steven Whitehouse   [GFS2] Fix releas...
1063
1064
1065
  		gfs2_log_unlock(sdp);
  		if (bd)
  			kmem_cache_free(gfs2_bufdata_cachep, bd);
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1066
1067
  
  		bh = bh->b_this_page;
166afccd7   Steven Whitehouse   [GFS2] Tidy up er...
1068
  	} while (bh != head);
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1069

4340fe625   Steven Whitehouse   [GFS2] Add genera...
1070
  	return try_to_free_buffers(page);
8f065d365   Steven Whitehouse   GFS2: Improve bug...
1071
1072
1073
1074
  
  not_possible: /* Should never happen */
  	WARN_ON(buffer_dirty(bh));
  	WARN_ON(buffer_pinned(bh));
bb3b0e3df   Steven Whitehouse   [GFS2] Clean up i...
1075
  cannot_release:
380f7c65a   Steven Whitehouse   GFS2: Resolve ino...
1076
  	spin_unlock(&sdp->sd_ail_lock);
bb3b0e3df   Steven Whitehouse   [GFS2] Clean up i...
1077
1078
  	gfs2_log_unlock(sdp);
  	return 0;
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1079
  }
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1080
  static const struct address_space_operations gfs2_writeback_aops = {
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
1081
  	.writepage = gfs2_writeback_writepage,
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1082
1083
1084
  	.writepages = gfs2_writeback_writepages,
  	.readpage = gfs2_readpage,
  	.readpages = gfs2_readpages,
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1085
1086
1087
1088
1089
1090
  	.write_begin = gfs2_write_begin,
  	.write_end = gfs2_write_end,
  	.bmap = gfs2_bmap,
  	.invalidatepage = gfs2_invalidatepage,
  	.releasepage = gfs2_releasepage,
  	.direct_IO = gfs2_direct_IO,
e5d9dc278   Steven Whitehouse   [GFS2] Allow page...
1091
  	.migratepage = buffer_migrate_page,
229615def   Hisashi Hifumi   GFS2: Pagecache u...
1092
  	.is_partially_uptodate = block_is_partially_uptodate,
aa261f549   Andi Kleen   HWPOISON: Enable ...
1093
  	.error_remove_page = generic_error_remove_page,
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1094
1095
1096
  };
  
  static const struct address_space_operations gfs2_ordered_aops = {
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
1097
  	.writepage = gfs2_ordered_writepage,
b3b94faa5   David Teigland   [GFS2] The core o...
1098
  	.readpage = gfs2_readpage,
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
1099
  	.readpages = gfs2_readpages,
7765ec26a   Steven Whitehouse   gfs2: convert to ...
1100
1101
  	.write_begin = gfs2_write_begin,
  	.write_end = gfs2_write_end,
8fb68595d   Robert Peterson   [GFS2] Journaled ...
1102
  	.set_page_dirty = gfs2_set_page_dirty,
b3b94faa5   David Teigland   [GFS2] The core o...
1103
1104
  	.bmap = gfs2_bmap,
  	.invalidatepage = gfs2_invalidatepage,
4340fe625   Steven Whitehouse   [GFS2] Add genera...
1105
  	.releasepage = gfs2_releasepage,
b3b94faa5   David Teigland   [GFS2] The core o...
1106
  	.direct_IO = gfs2_direct_IO,
e5d9dc278   Steven Whitehouse   [GFS2] Allow page...
1107
  	.migratepage = buffer_migrate_page,
229615def   Hisashi Hifumi   GFS2: Pagecache u...
1108
  	.is_partially_uptodate = block_is_partially_uptodate,
aa261f549   Andi Kleen   HWPOISON: Enable ...
1109
  	.error_remove_page = generic_error_remove_page,
b3b94faa5   David Teigland   [GFS2] The core o...
1110
  };
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1111
  static const struct address_space_operations gfs2_jdata_aops = {
9ff8ec32e   Steven Whitehouse   [GFS2] Split gfs2...
1112
  	.writepage = gfs2_jdata_writepage,
b8e7cbb65   Steven Whitehouse   [GFS2] Add writep...
1113
  	.writepages = gfs2_jdata_writepages,
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1114
1115
  	.readpage = gfs2_readpage,
  	.readpages = gfs2_readpages,
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1116
1117
1118
1119
1120
1121
  	.write_begin = gfs2_write_begin,
  	.write_end = gfs2_write_end,
  	.set_page_dirty = gfs2_set_page_dirty,
  	.bmap = gfs2_bmap,
  	.invalidatepage = gfs2_invalidatepage,
  	.releasepage = gfs2_releasepage,
229615def   Hisashi Hifumi   GFS2: Pagecache u...
1122
  	.is_partially_uptodate = block_is_partially_uptodate,
aa261f549   Andi Kleen   HWPOISON: Enable ...
1123
  	.error_remove_page = generic_error_remove_page,
5561093e2   Steven Whitehouse   [GFS2] Introduce ...
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
  };
  
  void gfs2_set_aops(struct inode *inode)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
  
  	if (gfs2_is_writeback(ip))
  		inode->i_mapping->a_ops = &gfs2_writeback_aops;
  	else if (gfs2_is_ordered(ip))
  		inode->i_mapping->a_ops = &gfs2_ordered_aops;
  	else if (gfs2_is_jdata(ip))
  		inode->i_mapping->a_ops = &gfs2_jdata_aops;
  	else
  		BUG();
  }