Blame view

fs/gfs2/meta_io.c 10.2 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
091806edd   Bob Peterson   [GFS2] filesystem...
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
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>
b3b94faa5   David Teigland   [GFS2] The core o...
22
23
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
24
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
25
26
27
28
29
30
31
32
  #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...
33
  #include "util.h"
627c10b7e   Steven Whitehouse   GFS2: Improve tra...
34
  #include "trace_gfs2.h"
b3b94faa5   David Teigland   [GFS2] The core o...
35

4a0f9a321   Steven Whitehouse   GFS2: Optimise wr...
36
  static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wbc)
b3b94faa5   David Teigland   [GFS2] The core o...
37
  {
4a0f9a321   Steven Whitehouse   GFS2: Optimise wr...
38
39
  	struct buffer_head *bh, *head;
  	int nr_underway = 0;
65299a3b7   Christoph Hellwig   block: separate p...
40
  	int write_op = REQ_META | REQ_PRIO |
721a9602e   Jens Axboe   block: kill off R...
41
  		(wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
b3b94faa5   David Teigland   [GFS2] The core o...
42

4a0f9a321   Steven Whitehouse   GFS2: Optimise wr...
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  	BUG_ON(!PageLocked(page));
  	BUG_ON(!page_has_buffers(page));
  
  	head = page_buffers(page);
  	bh = head;
  
  	do {
  		if (!buffer_mapped(bh))
  			continue;
  		/*
  		 * If it's a fully non-blocking write attempt and we cannot
  		 * lock the buffer then redirty the page.  Note that this can
  		 * potentially cause a busy-wait loop from pdflush and kswapd
  		 * activity, but those code paths have their own higher-level
  		 * throttling.
  		 */
1b430beee   Wu Fengguang   writeback: remove...
59
  		if (wbc->sync_mode != WB_SYNC_NONE) {
4a0f9a321   Steven Whitehouse   GFS2: Optimise wr...
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  			lock_buffer(bh);
  		} else if (!trylock_buffer(bh)) {
  			redirty_page_for_writepage(wbc, page);
  			continue;
  		}
  		if (test_clear_buffer_dirty(bh)) {
  			mark_buffer_async_write(bh);
  		} else {
  			unlock_buffer(bh);
  		}
  	} while ((bh = bh->b_this_page) != head);
  
  	/*
  	 * The page and its buffers are protected by PageWriteback(), so we can
  	 * drop the bh refcounts early.
  	 */
  	BUG_ON(PageWriteback(page));
  	set_page_writeback(page);
  
  	do {
  		struct buffer_head *next = bh->b_this_page;
  		if (buffer_async_write(bh)) {
  			submit_bh(write_op, bh);
  			nr_underway++;
  		}
  		bh = next;
  	} while (bh != head);
  	unlock_page(page);
4a0f9a321   Steven Whitehouse   GFS2: Optimise wr...
88
89
  	if (nr_underway == 0)
  		end_page_writeback(page);
eaefbf968   Bob Peterson   GFS2: Eliminate u...
90
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
91
  }
009d85183   Steven Whitehouse   GFS2: Metadata ad...
92
  const struct address_space_operations gfs2_meta_aops = {
b3b94faa5   David Teigland   [GFS2] The core o...
93
  	.writepage = gfs2_aspace_writepage,
4340fe625   Steven Whitehouse   [GFS2] Add genera...
94
  	.releasepage = gfs2_releasepage,
b3b94faa5   David Teigland   [GFS2] The core o...
95
96
97
  };
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
98
99
   * gfs2_meta_sync - Sync all buffers associated with a glock
   * @gl: The glock
b3b94faa5   David Teigland   [GFS2] The core o...
100
101
   *
   */
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
102
  void gfs2_meta_sync(struct gfs2_glock *gl)
b3b94faa5   David Teigland   [GFS2] The core o...
103
  {
009d85183   Steven Whitehouse   GFS2: Metadata ad...
104
  	struct address_space *mapping = gfs2_glock2aspace(gl);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
105
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
106

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
107
108
  	filemap_fdatawrite(mapping);
  	error = filemap_fdatawait(mapping);
b3b94faa5   David Teigland   [GFS2] The core o...
109
110
111
112
113
114
  
  	if (error)
  		gfs2_io_error(gl->gl_sbd);
  }
  
  /**
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
115
   * gfs2_getbuf - Get a buffer with a given address space
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
116
   * @gl: the glock
b3b94faa5   David Teigland   [GFS2] The core o...
117
118
119
120
121
   * @blkno: the block number (filesystem scope)
   * @create: 1 if the buffer should be created
   *
   * Returns: the buffer
   */
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
122
  struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, int create)
b3b94faa5   David Teigland   [GFS2] The core o...
123
  {
009d85183   Steven Whitehouse   GFS2: Metadata ad...
124
  	struct address_space *mapping = gfs2_glock2aspace(gl);
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
125
  	struct gfs2_sbd *sdp = gl->gl_sbd;
b3b94faa5   David Teigland   [GFS2] The core o...
126
127
128
129
130
131
132
133
134
135
136
137
  	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...
138
  			page = grab_cache_page(mapping, index);
b3b94faa5   David Teigland   [GFS2] The core o...
139
140
141
142
143
  			if (page)
  				break;
  			yield();
  		}
  	} else {
cb4c03131   Steven Whitehouse   [GFS2] Reduce num...
144
  		page = find_lock_page(mapping, index);
b3b94faa5   David Teigland   [GFS2] The core o...
145
146
147
148
149
150
151
152
153
154
155
156
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
  		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...
186
  struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
b3b94faa5   David Teigland   [GFS2] The core o...
187
188
  {
  	struct buffer_head *bh;
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
189
  	bh = gfs2_getbuf(gl, blkno, CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
190
191
192
193
194
195
196
197
  	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...
198
   * @flags: flags
b3b94faa5   David Teigland   [GFS2] The core o...
199
200
201
202
   * @bhp: the place where the buffer is returned (NULL on failure)
   *
   * Returns: errno
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
203
  int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
b3b94faa5   David Teigland   [GFS2] The core o...
204
205
  		   struct buffer_head **bhp)
  {
c969f58ca   Steven Whitehouse   GFS2: Update the ...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  	struct gfs2_sbd *sdp = gl->gl_sbd;
  	struct buffer_head *bh;
  
  	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
  		return -EIO;
  
  	*bhp = bh = gfs2_getbuf(gl, blkno, CREATE);
  
  	lock_buffer(bh);
  	if (buffer_uptodate(bh)) {
  		unlock_buffer(bh);
  		return 0;
  	}
  	bh->b_end_io = end_buffer_read_sync;
  	get_bh(bh);
65299a3b7   Christoph Hellwig   block: separate p...
221
  	submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh);
c969f58ca   Steven Whitehouse   GFS2: Update the ...
222
223
224
225
226
227
228
229
230
231
  	if (!(flags & DIO_WAIT))
  		return 0;
  
  	wait_on_buffer(bh);
  	if (unlikely(!buffer_uptodate(bh))) {
  		struct gfs2_trans *tr = current->journal_info;
  		if (tr && tr->tr_touched)
  			gfs2_io_error_bh(sdp, bh);
  		brelse(bh);
  		return -EIO;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
232
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
233

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

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

5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
275
  	if (bh->b_private) {
18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
276
277
  		if (meta)
  			unlock_page(bh->b_page);
b3b94faa5   David Teigland   [GFS2] The core o...
278
279
  		return;
  	}
3e5cd0877   Bob Peterson   [GFS2] Fix typo
280
  	bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL);
b3b94faa5   David Teigland   [GFS2] The core o...
281
282
283
284
  	bd->bd_bh = bh;
  	bd->bd_gl = gl;
  
  	INIT_LIST_HEAD(&bd->bd_list_tr);
82ffa5163   Steven Whitehouse   [GFS2] More style...
285
  	if (meta)
586dfdaaf   Steven Whitehouse   [GFS2] Make the n...
286
  		lops_init_le(&bd->bd_le, &gfs2_buf_lops);
82ffa5163   Steven Whitehouse   [GFS2] More style...
287
  	else
586dfdaaf   Steven Whitehouse   [GFS2] Make the n...
288
  		lops_init_le(&bd->bd_le, &gfs2_databuf_lops);
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
289
  	bh->b_private = bd;
b3b94faa5   David Teigland   [GFS2] The core o...
290

18ec7d5c3   Steven Whitehouse   [GFS2] Make journ...
291
292
  	if (meta)
  		unlock_page(bh->b_page);
b3b94faa5   David Teigland   [GFS2] The core o...
293
  }
16615be18   Steven Whitehouse   [GFS2] Clean up j...
294
295
  void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int meta)
  {
009d85183   Steven Whitehouse   GFS2: Metadata ad...
296
297
  	struct address_space *mapping = bh->b_page->mapping;
  	struct gfs2_sbd *sdp = gfs2_mapping2sbd(mapping);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
298
  	struct gfs2_bufdata *bd = bh->b_private;
009d85183   Steven Whitehouse   GFS2: Metadata ad...
299

16615be18   Steven Whitehouse   [GFS2] Clean up j...
300
  	if (test_clear_buffer_pinned(bh)) {
627c10b7e   Steven Whitehouse   GFS2: Improve tra...
301
  		trace_gfs2_pin(bd, 0);
5e687eac1   Benjamin Marzinski   GFS2: Various gfs...
302
  		atomic_dec(&sdp->sd_log_pinned);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
303
304
305
306
307
308
309
310
311
312
313
314
315
316
  		list_del_init(&bd->bd_le.le_list);
  		if (meta) {
  			gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
  			sdp->sd_log_num_buf--;
  			tr->tr_num_buf_rm++;
  		} else {
  			gfs2_assert_warn(sdp, sdp->sd_log_num_databuf);
  			sdp->sd_log_num_databuf--;
  			tr->tr_num_databuf_rm++;
  		}
  		tr->tr_touched = 1;
  		brelse(bh);
  	}
  	if (bd) {
c618e87a5   Steven Whitehouse   GFS2: Update to A...
317
  		spin_lock(&sdp->sd_ail_lock);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
318
  		if (bd->bd_ail) {
f91a0d3e2   Steven Whitehouse   [GFS2] Remove use...
319
  			gfs2_remove_from_ail(bd);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
320
321
322
323
324
  			bh->b_private = NULL;
  			bd->bd_bh = NULL;
  			bd->bd_blkno = bh->b_blocknr;
  			gfs2_trans_add_revoke(sdp, bd);
  		}
c618e87a5   Steven Whitehouse   GFS2: Update to A...
325
  		spin_unlock(&sdp->sd_ail_lock);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
326
327
328
329
  	}
  	clear_buffer_dirty(bh);
  	clear_buffer_uptodate(bh);
  }
b3b94faa5   David Teigland   [GFS2] The core o...
330
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
331
332
333
334
335
336
   * 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...
337
  void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
b3b94faa5   David Teigland   [GFS2] The core o...
338
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
339
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
340
341
342
  	struct buffer_head *bh;
  
  	while (blen) {
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
343
  		bh = gfs2_getbuf(ip->i_gl, bstart, NO_CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
344
  		if (bh) {
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
345
346
  			lock_buffer(bh);
  			gfs2_log_lock(sdp);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
347
  			gfs2_remove_from_journal(bh, current->journal_info, 1);
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
348
  			gfs2_log_unlock(sdp);
b3b94faa5   David Teigland   [GFS2] The core o...
349
  			unlock_buffer(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
350
351
352
353
354
355
356
357
358
  			brelse(bh);
  		}
  
  		bstart++;
  		blen--;
  	}
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
359
360
361
362
363
364
365
   * 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
   *
b3b94faa5   David Teigland   [GFS2] The core o...
366
367
   * Returns: errno
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
368
  int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
b3b94faa5   David Teigland   [GFS2] The core o...
369
370
  			      int new, struct buffer_head **bhp)
  {
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
371
372
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
  	struct gfs2_glock *gl = ip->i_gl;
f91a0d3e2   Steven Whitehouse   [GFS2] Remove use...
373
374
  	struct buffer_head *bh;
  	int ret = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
375
376
  
  	if (new) {
f91a0d3e2   Steven Whitehouse   [GFS2] Remove use...
377
378
  		BUG_ON(height == 0);
  		bh = gfs2_meta_new(gl, num);
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
379
  		gfs2_trans_add_bh(ip->i_gl, bh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
380
381
  		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...
382
383
  	} else {
  		u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
f91a0d3e2   Steven Whitehouse   [GFS2] Remove use...
384
385
386
387
  		ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh);
  		if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) {
  			brelse(bh);
  			ret = -EIO;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
388
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
389
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
390
  	*bhp = bh;
f91a0d3e2   Steven Whitehouse   [GFS2] Remove use...
391
  	return ret;
b3b94faa5   David Teigland   [GFS2] The core o...
392
393
394
395
396
397
398
399
  }
  
  /**
   * 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...
400
   * returns: the first buffer in the extent
b3b94faa5   David Teigland   [GFS2] The core o...
401
   */
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
402
  struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen)
b3b94faa5   David Teigland   [GFS2] The core o...
403
404
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
b3b94faa5   David Teigland   [GFS2] The core o...
405
  	struct buffer_head *first_bh, *bh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
406
  	u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >>
568f4c965   Steven Whitehouse   [GFS2] 80 Column ...
407
  			  sdp->sd_sb.sb_bsize_shift;
b3b94faa5   David Teigland   [GFS2] The core o...
408

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
409
410
411
412
  	BUG_ON(!extlen);
  
  	if (max_ra < 1)
  		max_ra = 1;
b3b94faa5   David Teigland   [GFS2] The core o...
413
414
  	if (extlen > max_ra)
  		extlen = max_ra;
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
415
  	first_bh = gfs2_getbuf(gl, dblock, CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
416
417
418
  
  	if (buffer_uptodate(first_bh))
  		goto out;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
419
  	if (!buffer_locked(first_bh))
20ed0535d   Steven Whitehouse   GFS2: Fix up REQ ...
420
  		ll_rw_block(READ_SYNC | REQ_META, 1, &first_bh);
b3b94faa5   David Teigland   [GFS2] The core o...
421
422
423
424
425
  
  	dblock++;
  	extlen--;
  
  	while (extlen) {
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
426
  		bh = gfs2_getbuf(gl, dblock, CREATE);
b3b94faa5   David Teigland   [GFS2] The core o...
427

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
428
  		if (!buffer_uptodate(bh) && !buffer_locked(bh))
20ed0535d   Steven Whitehouse   GFS2: Fix up REQ ...
429
  			ll_rw_block(READA | REQ_META, 1, &bh);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
430
  		brelse(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
431
432
  		dblock++;
  		extlen--;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
433
434
  		if (!buffer_locked(first_bh) && buffer_uptodate(first_bh))
  			goto out;
b3b94faa5   David Teigland   [GFS2] The core o...
435
  	}
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
436
  	wait_on_buffer(first_bh);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
437
  out:
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
438
  	return first_bh;
b3b94faa5   David Teigland   [GFS2] The core o...
439
  }