Blame view

fs/gfs2/meta_io.c 12.5 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3a8a9a103   Steven Whitehouse   [GFS2] Update cop...
3
   * Copyright (C) 2004-2006 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
16
17
18
19
   */
  
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
  #include <linux/mm.h>
  #include <linux/pagemap.h>
  #include <linux/writeback.h>
  #include <linux/swap.h>
  #include <linux/delay.h>
2e565bb69   Steven Whitehouse   [GFS2] Mark metad...
20
  #include <linux/bio.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
21
  #include <linux/gfs2_ondisk.h>
7d308590a   Fabio Massimo Di Nitto   [GFS2] Export lm_...
22
  #include <linux/lm_interface.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
29
30
31
32
33
  #include "glock.h"
  #include "glops.h"
  #include "inode.h"
  #include "log.h"
  #include "lops.h"
  #include "meta_io.h"
  #include "rgrp.h"
  #include "trans.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
34
  #include "util.h"
4340fe625   Steven Whitehouse   [GFS2] Add genera...
35
  #include "ops_address.h"
b3b94faa5   David Teigland   [GFS2] The core o...
36

b3b94faa5   David Teigland   [GFS2] The core o...
37
38
39
  static int aspace_get_block(struct inode *inode, sector_t lblock,
  			    struct buffer_head *bh_result, int create)
  {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
40
  	gfs2_assert_warn(inode->i_sb->s_fs_info, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
41
42
43
44
45
46
47
48
  	return -EOPNOTSUPP;
  }
  
  static int gfs2_aspace_writepage(struct page *page,
  				 struct writeback_control *wbc)
  {
  	return block_write_full_page(page, aspace_get_block, wbc);
  }
66de045d9   Steven Whitehouse   [GFS2] Make our a...
49
  static const struct address_space_operations aspace_aops = {
b3b94faa5   David Teigland   [GFS2] The core o...
50
  	.writepage = gfs2_aspace_writepage,
4340fe625   Steven Whitehouse   [GFS2] Add genera...
51
  	.releasepage = gfs2_releasepage,
b3b94faa5   David Teigland   [GFS2] The core o...
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  };
  
  /**
   * gfs2_aspace_get - Create and initialize a struct inode structure
   * @sdp: the filesystem the aspace is in
   *
   * Right now a struct inode is just a struct inode.  Maybe Linux
   * will supply a more lightweight address space construct (that works)
   * in the future.
   *
   * Make sure pages/buffers in this aspace aren't in high memory.
   *
   * Returns: the aspace
   */
  
  struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp)
  {
  	struct inode *aspace;
  
  	aspace = new_inode(sdp->sd_vfs);
  	if (aspace) {
f3bba03fd   Steven Whitehouse   [GFS2] Fix deadlo...
73
  		mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS);
b3b94faa5   David Teigland   [GFS2] The core o...
74
75
  		aspace->i_mapping->a_ops = &aspace_aops;
  		aspace->i_size = ~0ULL;
bba9dfd83   Theodore Ts'o   [GFS2] inode_diet...
76
  		aspace->i_private = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
77
78
  		insert_inode_hash(aspace);
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
79
80
81
82
83
84
85
86
87
88
  	return aspace;
  }
  
  void gfs2_aspace_put(struct inode *aspace)
  {
  	remove_inode_hash(aspace);
  	iput(aspace);
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
   * gfs2_meta_inval - Invalidate all buffers associated with a glock
   * @gl: the glock
   *
   */
  
  void gfs2_meta_inval(struct gfs2_glock *gl)
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
  	struct inode *aspace = gl->gl_aspace;
  	struct address_space *mapping = gl->gl_aspace->i_mapping;
  
  	gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
  
  	atomic_inc(&aspace->i_writecount);
  	truncate_inode_pages(mapping, 0);
  	atomic_dec(&aspace->i_writecount);
  
  	gfs2_assert_withdraw(sdp, !mapping->nrpages);
  }
  
  /**
   * gfs2_meta_sync - Sync all buffers associated with a glock
   * @gl: The glock
b3b94faa5   David Teigland   [GFS2] The core o...
112
113
   *
   */
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
114
  void gfs2_meta_sync(struct gfs2_glock *gl)
b3b94faa5   David Teigland   [GFS2] The core o...
115
116
  {
  	struct address_space *mapping = gl->gl_aspace->i_mapping;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
117
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
118

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
119
120
  	filemap_fdatawrite(mapping);
  	error = filemap_fdatawait(mapping);
b3b94faa5   David Teigland   [GFS2] The core o...
121
122
123
124
125
126
127
  
  	if (error)
  		gfs2_io_error(gl->gl_sbd);
  }
  
  /**
   * getbuf - Get a buffer with a given address space
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
128
   * @gl: the glock
b3b94faa5   David Teigland   [GFS2] The core o...
129
130
131
132
133
   * @blkno: the block number (filesystem scope)
   * @create: 1 if the buffer should be created
   *
   * Returns: the buffer
   */
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
134
  static struct buffer_head *getbuf(struct gfs2_glock *gl, u64 blkno, int create)
b3b94faa5   David Teigland   [GFS2] The core o...
135
  {
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
136
137
  	struct address_space *mapping = gl->gl_aspace->i_mapping;
  	struct gfs2_sbd *sdp = gl->gl_sbd;
b3b94faa5   David Teigland   [GFS2] The core o...
138
139
140
141
142
143
144
145
146
147
148
149
  	struct page *page;
  	struct buffer_head *bh;
  	unsigned int shift;
  	unsigned long index;
  	unsigned int bufnum;
  
  	shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift;
  	index = blkno >> shift;             /* convert block to page */
  	bufnum = blkno - (index << shift);  /* block buf index within page */
  
  	if (create) {
  		for (;;) {
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
150
  			page = grab_cache_page(mapping, index);
b3b94faa5   David Teigland   [GFS2] The core o...
151
152
153
154
155
  			if (page)
  				break;
  			yield();
  		}
  	} else {
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
156
  		page = find_lock_page(mapping, index);
b3b94faa5   David Teigland   [GFS2] The core o...
157
158
159
160
161
162
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
191
192
193
194
195
196
197
  		if (!page)
  			return NULL;
  	}
  
  	if (!page_has_buffers(page))
  		create_empty_buffers(page, sdp->sd_sb.sb_bsize, 0);
  
  	/* Locate header for our buffer within our page */
  	for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page)
  		/* Do nothing */;
  	get_bh(bh);
  
  	if (!buffer_mapped(bh))
  		map_bh(bh, sdp->sd_vfs, blkno);
  
  	unlock_page(page);
  	mark_page_accessed(page);
  	page_cache_release(page);
  
  	return bh;
  }
  
  static void meta_prep_new(struct buffer_head *bh)
  {
  	struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data;
  
  	lock_buffer(bh);
  	clear_buffer_dirty(bh);
  	set_buffer_uptodate(bh);
  	unlock_buffer(bh);
  
  	mh->mh_magic = cpu_to_be32(GFS2_MAGIC);
  }
  
  /**
   * gfs2_meta_new - Get a block
   * @gl: The glock associated with this block
   * @blkno: The block number
   *
   * Returns: The buffer
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
198
  struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
b3b94faa5   David Teigland   [GFS2] The core o...
199
200
  {
  	struct buffer_head *bh;
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
201
  	bh = getbuf(gl, blkno, CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
202
203
204
205
206
207
208
209
  	meta_prep_new(bh);
  	return bh;
  }
  
  /**
   * gfs2_meta_read - Read a block from disk
   * @gl: The glock covering the block
   * @blkno: The block number
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
210
   * @flags: flags
b3b94faa5   David Teigland   [GFS2] The core o...
211
212
213
214
   * @bhp: the place where the buffer is returned (NULL on failure)
   *
   * Returns: errno
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
215
  int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
b3b94faa5   David Teigland   [GFS2] The core o...
216
217
  		   struct buffer_head **bhp)
  {
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
218
  	*bhp = getbuf(gl, blkno, CREATE);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
219
  	if (!buffer_uptodate(*bhp))
2e565bb69   Steven Whitehouse   [GFS2] Mark metad...
220
  		ll_rw_block(READ_META, 1, bhp);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
221
222
223
224
225
226
227
  	if (flags & DIO_WAIT) {
  		int error = gfs2_meta_wait(gl->gl_sbd, *bhp);
  		if (error) {
  			brelse(*bhp);
  			return error;
  		}
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
228

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
229
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
230
231
232
  }
  
  /**
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
233
   * gfs2_meta_wait - Reread a block from disk
b3b94faa5   David Teigland   [GFS2] The core o...
234
   * @sdp: the filesystem
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
235
   * @bh: The block to wait for
b3b94faa5   David Teigland   [GFS2] The core o...
236
237
238
   *
   * Returns: errno
   */
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
239
  int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
b3b94faa5   David Teigland   [GFS2] The core o...
240
241
242
  {
  	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
  		return -EIO;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
243
  	wait_on_buffer(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
244

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
245
246
247
248
249
  	if (!buffer_uptodate(bh)) {
  		struct gfs2_trans *tr = current->journal_info;
  		if (tr && tr->tr_touched)
  			gfs2_io_error_bh(sdp, bh);
  		return -EIO;
b3b94faa5   David Teigland   [GFS2] The core o...
250
  	}
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
251
252
  	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
  		return -EIO;
b3b94faa5   David Teigland   [GFS2] The core o...
253
254
255
256
257
  
  	return 0;
  }
  
  /**
586dfdaaf   Steven Whitehouse   [GFS2] Make the n...
258
   * gfs2_attach_bufdata - attach a struct gfs2_bufdata structure to a buffer
b3b94faa5   David Teigland   [GFS2] The core o...
259
260
   * @gl: the glock the buffer belongs to
   * @bh: The buffer to be attached to
586dfdaaf   Steven Whitehouse   [GFS2] Make the n...
261
   * @meta: Flag to indicate whether its metadata or not
b3b94faa5   David Teigland   [GFS2] The core o...
262
   */
568f4c965   Steven Whitehouse   [GFS2] 80 Column ...
263
264
  void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
  			 int meta)
b3b94faa5   David Teigland   [GFS2] The core o...
265
266
  {
  	struct gfs2_bufdata *bd;
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
267
268
  	if (meta)
  		lock_page(bh->b_page);
b3b94faa5   David Teigland   [GFS2] The core o...
269

5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
270
  	if (bh->b_private) {
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
271
272
  		if (meta)
  			unlock_page(bh->b_page);
b3b94faa5   David Teigland   [GFS2] The core o...
273
274
  		return;
  	}
c37622296   Robert P. J. Day   [PATCH] Transform...
275
  	bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL),
b3b94faa5   David Teigland   [GFS2] The core o...
276
277
278
279
  	bd->bd_bh = bh;
  	bd->bd_gl = gl;
  
  	INIT_LIST_HEAD(&bd->bd_list_tr);
82ffa5163   Steven Whitehouse   [GFS2] More style...
280
  	if (meta)
586dfdaaf   Steven Whitehouse   [GFS2] Make the n...
281
  		lops_init_le(&bd->bd_le, &gfs2_buf_lops);
82ffa5163   Steven Whitehouse   [GFS2] More style...
282
  	else
586dfdaaf   Steven Whitehouse   [GFS2] Make the n...
283
  		lops_init_le(&bd->bd_le, &gfs2_databuf_lops);
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
284
  	bh->b_private = bd;
b3b94faa5   David Teigland   [GFS2] The core o...
285

18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
286
287
  	if (meta)
  		unlock_page(bh->b_page);
b3b94faa5   David Teigland   [GFS2] The core o...
288
289
290
  }
  
  /**
a98ab2204   Steven Whitehouse   [GFS2] Rename gfs...
291
   * gfs2_pin - Pin a buffer in memory
b3b94faa5   David Teigland   [GFS2] The core o...
292
293
294
295
   * @sdp: the filesystem the buffer belongs to
   * @bh: The buffer to be pinned
   *
   */
a98ab2204   Steven Whitehouse   [GFS2] Rename gfs...
296
  void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh)
b3b94faa5   David Teigland   [GFS2] The core o...
297
  {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
298
  	struct gfs2_bufdata *bd = bh->b_private;
b3b94faa5   David Teigland   [GFS2] The core o...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  
  	gfs2_assert_withdraw(sdp, test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags));
  
  	if (test_set_buffer_pinned(bh))
  		gfs2_assert_withdraw(sdp, 0);
  
  	wait_on_buffer(bh);
  
  	/* If this buffer is in the AIL and it has already been written
  	   to in-place disk block, remove it from the AIL. */
  
  	gfs2_log_lock(sdp);
  	if (bd->bd_ail && !buffer_in_io(bh))
  		list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list);
  	gfs2_log_unlock(sdp);
  
  	clear_buffer_dirty(bh);
  	wait_on_buffer(bh);
  
  	if (!buffer_uptodate(bh))
  		gfs2_io_error_bh(sdp, bh);
  
  	get_bh(bh);
  }
  
  /**
a98ab2204   Steven Whitehouse   [GFS2] Rename gfs...
325
   * gfs2_unpin - Unpin a buffer
b3b94faa5   David Teigland   [GFS2] The core o...
326
327
328
329
330
   * @sdp: the filesystem the buffer belongs to
   * @bh: The buffer to unpin
   * @ai:
   *
   */
a98ab2204   Steven Whitehouse   [GFS2] Rename gfs...
331
332
  void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
  	        struct gfs2_ail *ai)
b3b94faa5   David Teigland   [GFS2] The core o...
333
  {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
334
  	struct gfs2_bufdata *bd = bh->b_private;
b3b94faa5   David Teigland   [GFS2] The core o...
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
  
  	gfs2_assert_withdraw(sdp, buffer_uptodate(bh));
  
  	if (!buffer_pinned(bh))
  		gfs2_assert_withdraw(sdp, 0);
  
  	mark_buffer_dirty(bh);
  	clear_buffer_pinned(bh);
  
  	gfs2_log_lock(sdp);
  	if (bd->bd_ail) {
  		list_del(&bd->bd_ail_st_list);
  		brelse(bh);
  	} else {
  		struct gfs2_glock *gl = bd->bd_gl;
  		list_add(&bd->bd_ail_gl_list, &gl->gl_ail_list);
  		atomic_inc(&gl->gl_ail_count);
  	}
  	bd->bd_ail = ai;
  	list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list);
  	gfs2_log_unlock(sdp);
  }
  
  /**
   * gfs2_meta_wipe - make inode's buffers so they aren't dirty/pinned anymore
   * @ip: the inode who owns the buffers
   * @bstart: the first buffer in the run
   * @blen: the number of buffers in the run
   *
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
365
  void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
b3b94faa5   David Teigland   [GFS2] The core o...
366
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
367
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
368
369
370
  	struct buffer_head *bh;
  
  	while (blen) {
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
371
  		bh = getbuf(ip->i_gl, bstart, NO_CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
372
  		if (bh) {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
373
  			struct gfs2_bufdata *bd = bh->b_private;
b3b94faa5   David Teigland   [GFS2] The core o...
374
375
  
  			if (test_clear_buffer_pinned(bh)) {
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
376
  				struct gfs2_trans *tr = current->journal_info;
2332c4435   Robert Peterson   [GFS2] assertion ...
377
378
  				struct gfs2_inode *bh_ip =
  					GFS2_I(bh->b_page->mapping->host);
b3b94faa5   David Teigland   [GFS2] The core o...
379
380
381
382
383
  				gfs2_log_lock(sdp);
  				list_del_init(&bd->bd_le.le_list);
  				gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
  				sdp->sd_log_num_buf--;
  				gfs2_log_unlock(sdp);
2332c4435   Robert Peterson   [GFS2] assertion ...
384
385
386
387
  				if (bh_ip->i_inode.i_private != NULL)
  					tr->tr_num_databuf_rm++;
  				else
  					tr->tr_num_buf_rm++;
b3b94faa5   David Teigland   [GFS2] The core o...
388
389
390
391
392
  				brelse(bh);
  			}
  			if (bd) {
  				gfs2_log_lock(sdp);
  				if (bd->bd_ail) {
cd915493f   Steven Whitehouse   [GFS2] Change all...
393
  					u64 blkno = bh->b_blocknr;
b3b94faa5   David Teigland   [GFS2] The core o...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
  					bd->bd_ail = NULL;
  					list_del(&bd->bd_ail_st_list);
  					list_del(&bd->bd_ail_gl_list);
  					atomic_dec(&bd->bd_gl->gl_ail_count);
  					brelse(bh);
  					gfs2_log_unlock(sdp);
  					gfs2_trans_add_revoke(sdp, blkno);
  				} else
  					gfs2_log_unlock(sdp);
  			}
  
  			lock_buffer(bh);
  			clear_buffer_dirty(bh);
  			clear_buffer_uptodate(bh);
  			unlock_buffer(bh);
  
  			brelse(bh);
  		}
  
  		bstart++;
  		blen--;
  	}
  }
  
  /**
   * gfs2_meta_cache_flush - get rid of any references on buffers for this inode
   * @ip: The GFS2 inode
   *
   * This releases buffers that are in the most-recently-used array of
   * blocks used for indirect block addressing for this inode.
   */
  
  void gfs2_meta_cache_flush(struct gfs2_inode *ip)
  {
  	struct buffer_head **bh_slot;
  	unsigned int x;
  
  	spin_lock(&ip->i_spin);
  
  	for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) {
  		bh_slot = &ip->i_cache[x];
  		if (!*bh_slot)
  			break;
  		brelse(*bh_slot);
  		*bh_slot = NULL;
  	}
  
  	spin_unlock(&ip->i_spin);
  }
  
  /**
   * gfs2_meta_indirect_buffer - Get a metadata buffer
   * @ip: The GFS2 inode
   * @height: The level of this buf in the metadata (indir addr) tree (if any)
   * @num: The block number (device relative) of the buffer
   * @new: Non-zero if we may create a new buffer
   * @bhp: the buffer is returned here
   *
   * Try to use the gfs2_inode's MRU metadata tree cache.
   *
   * Returns: errno
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
456
  int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
b3b94faa5   David Teigland   [GFS2] The core o...
457
458
  			      int new, struct buffer_head **bhp)
  {
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
459
460
461
462
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
  	struct gfs2_glock *gl = ip->i_gl;
  	struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height;
  	int in_cache = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
463

b004157ab   Steven Whitehouse   [GFS2] Fix journa...
464
465
  	BUG_ON(!gl);
  	BUG_ON(!sdp);
b3b94faa5   David Teigland   [GFS2] The core o...
466
  	spin_lock(&ip->i_spin);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
467
468
469
470
  	if (*bh_slot && (*bh_slot)->b_blocknr == num) {
  		bh = *bh_slot;
  		get_bh(bh);
  		in_cache = 1;
b3b94faa5   David Teigland   [GFS2] The core o...
471
472
  	}
  	spin_unlock(&ip->i_spin);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
473
  	if (!bh)
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
474
  		bh = getbuf(gl, num, CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
475

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
476
477
  	if (!bh)
  		return -ENOBUFS;
b3b94faa5   David Teigland   [GFS2] The core o...
478
479
  
  	if (new) {
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
480
481
482
  		if (gfs2_assert_warn(sdp, height))
  			goto err;
  		meta_prep_new(bh);
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
483
  		gfs2_trans_add_bh(ip->i_gl, bh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
484
485
  		gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
  		gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
486
487
488
  	} else {
  		u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
  		if (!buffer_uptodate(bh)) {
2e565bb69   Steven Whitehouse   [GFS2] Mark metad...
489
  			ll_rw_block(READ_META, 1, &bh);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
490
491
492
493
494
495
  			if (gfs2_meta_wait(sdp, bh))
  				goto err;
  		}
  		if (gfs2_metatype_check(sdp, bh, mtype))
  			goto err;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
496

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
497
498
499
500
501
502
503
  	if (!in_cache) {
  		spin_lock(&ip->i_spin);
  		if (*bh_slot)
  			brelse(*bh_slot);
  		*bh_slot = bh;
  		get_bh(bh);
  		spin_unlock(&ip->i_spin);
b3b94faa5   David Teigland   [GFS2] The core o...
504
505
506
  	}
  
  	*bhp = bh;
b3b94faa5   David Teigland   [GFS2] The core o...
507
  	return 0;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
508
509
510
  err:
  	brelse(bh);
  	return -EIO;
b3b94faa5   David Teigland   [GFS2] The core o...
511
512
513
514
515
516
517
518
  }
  
  /**
   * gfs2_meta_ra - start readahead on an extent of a file
   * @gl: the glock the blocks belong to
   * @dblock: the starting disk block
   * @extlen: the number of blocks in the extent
   *
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
519
   * returns: the first buffer in the extent
b3b94faa5   David Teigland   [GFS2] The core o...
520
   */
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
521
  struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
b3b94faa5   David Teigland   [GFS2] The core o...
522
523
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
b3b94faa5   David Teigland   [GFS2] The core o...
524
  	struct buffer_head *first_bh, *bh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
525
  	u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >>
568f4c965   Steven Whitehouse   [GFS2] 80 Column ...
526
  			  sdp->sd_sb.sb_bsize_shift;
b3b94faa5   David Teigland   [GFS2] The core o...
527

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
528
529
530
531
  	BUG_ON(!extlen);
  
  	if (max_ra < 1)
  		max_ra = 1;
b3b94faa5   David Teigland   [GFS2] The core o...
532
533
  	if (extlen > max_ra)
  		extlen = max_ra;
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
534
  	first_bh = getbuf(gl, dblock, CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
535
536
537
  
  	if (buffer_uptodate(first_bh))
  		goto out;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
538
  	if (!buffer_locked(first_bh))
2e565bb69   Steven Whitehouse   [GFS2] Mark metad...
539
  		ll_rw_block(READ_META, 1, &first_bh);
b3b94faa5   David Teigland   [GFS2] The core o...
540
541
542
543
544
  
  	dblock++;
  	extlen--;
  
  	while (extlen) {
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
545
  		bh = getbuf(gl, dblock, CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
546

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
547
548
549
  		if (!buffer_uptodate(bh) && !buffer_locked(bh))
  			ll_rw_block(READA, 1, &bh);
  		brelse(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
550
551
  		dblock++;
  		extlen--;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
552
553
  		if (!buffer_locked(first_bh) && buffer_uptodate(first_bh))
  			goto out;
b3b94faa5   David Teigland   [GFS2] The core o...
554
  	}
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
555
  	wait_on_buffer(first_bh);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
556
  out:
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
557
  	return first_bh;
b3b94faa5   David Teigland   [GFS2] The core o...
558
  }