aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/meta_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/meta_io.c')
-rw-r--r--fs/gfs2/meta_io.c97
1 files changed, 19 insertions, 78 deletions
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 4da423985e4f..85aea27b4a86 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -50,6 +50,7 @@ static int gfs2_aspace_writepage(struct page *page,
50static const struct address_space_operations aspace_aops = { 50static const struct address_space_operations aspace_aops = {
51 .writepage = gfs2_aspace_writepage, 51 .writepage = gfs2_aspace_writepage,
52 .releasepage = gfs2_releasepage, 52 .releasepage = gfs2_releasepage,
53 .sync_page = block_sync_page,
53}; 54};
54 55
55/** 56/**
@@ -221,13 +222,14 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
221 struct buffer_head **bhp) 222 struct buffer_head **bhp)
222{ 223{
223 *bhp = getbuf(gl, blkno, CREATE); 224 *bhp = getbuf(gl, blkno, CREATE);
224 if (!buffer_uptodate(*bhp)) 225 if (!buffer_uptodate(*bhp)) {
225 ll_rw_block(READ_META, 1, bhp); 226 ll_rw_block(READ_META, 1, bhp);
226 if (flags & DIO_WAIT) { 227 if (flags & DIO_WAIT) {
227 int error = gfs2_meta_wait(gl->gl_sbd, *bhp); 228 int error = gfs2_meta_wait(gl->gl_sbd, *bhp);
228 if (error) { 229 if (error) {
229 brelse(*bhp); 230 brelse(*bhp);
230 return error; 231 return error;
232 }
231 } 233 }
232 } 234 }
233 235
@@ -282,7 +284,7 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh,
282 return; 284 return;
283 } 285 }
284 286
285 bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL), 287 bd = kmem_cache_zalloc(gfs2_bufdata_cachep, GFP_NOFS | __GFP_NOFAIL);
286 bd->bd_bh = bh; 288 bd->bd_bh = bh;
287 bd->bd_gl = gl; 289 bd->bd_gl = gl;
288 290
@@ -317,7 +319,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int
317 } 319 }
318 if (bd) { 320 if (bd) {
319 if (bd->bd_ail) { 321 if (bd->bd_ail) {
320 gfs2_remove_from_ail(NULL, bd); 322 gfs2_remove_from_ail(bd);
321 bh->b_private = NULL; 323 bh->b_private = NULL;
322 bd->bd_bh = NULL; 324 bd->bd_bh = NULL;
323 bd->bd_blkno = bh->b_blocknr; 325 bd->bd_blkno = bh->b_blocknr;
@@ -358,32 +360,6 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
358} 360}
359 361
360/** 362/**
361 * gfs2_meta_cache_flush - get rid of any references on buffers for this inode
362 * @ip: The GFS2 inode
363 *
364 * This releases buffers that are in the most-recently-used array of
365 * blocks used for indirect block addressing for this inode.
366 */
367
368void gfs2_meta_cache_flush(struct gfs2_inode *ip)
369{
370 struct buffer_head **bh_slot;
371 unsigned int x;
372
373 spin_lock(&ip->i_spin);
374
375 for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) {
376 bh_slot = &ip->i_cache[x];
377 if (*bh_slot) {
378 brelse(*bh_slot);
379 *bh_slot = NULL;
380 }
381 }
382
383 spin_unlock(&ip->i_spin);
384}
385
386/**
387 * gfs2_meta_indirect_buffer - Get a metadata buffer 363 * gfs2_meta_indirect_buffer - Get a metadata buffer
388 * @ip: The GFS2 inode 364 * @ip: The GFS2 inode
389 * @height: The level of this buf in the metadata (indir addr) tree (if any) 365 * @height: The level of this buf in the metadata (indir addr) tree (if any)
@@ -391,8 +367,6 @@ void gfs2_meta_cache_flush(struct gfs2_inode *ip)
391 * @new: Non-zero if we may create a new buffer 367 * @new: Non-zero if we may create a new buffer
392 * @bhp: the buffer is returned here 368 * @bhp: the buffer is returned here
393 * 369 *
394 * Try to use the gfs2_inode's MRU metadata tree cache.
395 *
396 * Returns: errno 370 * Returns: errno
397 */ 371 */
398 372
@@ -401,58 +375,25 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
401{ 375{
402 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 376 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
403 struct gfs2_glock *gl = ip->i_gl; 377 struct gfs2_glock *gl = ip->i_gl;
404 struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; 378 struct buffer_head *bh;
405 int in_cache = 0; 379 int ret = 0;
406
407 BUG_ON(!gl);
408 BUG_ON(!sdp);
409
410 spin_lock(&ip->i_spin);
411 if (*bh_slot && (*bh_slot)->b_blocknr == num) {
412 bh = *bh_slot;
413 get_bh(bh);
414 in_cache = 1;
415 }
416 spin_unlock(&ip->i_spin);
417
418 if (!bh)
419 bh = getbuf(gl, num, CREATE);
420
421 if (!bh)
422 return -ENOBUFS;
423 380
424 if (new) { 381 if (new) {
425 if (gfs2_assert_warn(sdp, height)) 382 BUG_ON(height == 0);
426 goto err; 383 bh = gfs2_meta_new(gl, num);
427 meta_prep_new(bh);
428 gfs2_trans_add_bh(ip->i_gl, bh, 1); 384 gfs2_trans_add_bh(ip->i_gl, bh, 1);
429 gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); 385 gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
430 gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); 386 gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
431 } else { 387 } else {
432 u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; 388 u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
433 if (!buffer_uptodate(bh)) { 389 ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh);
434 ll_rw_block(READ_META, 1, &bh); 390 if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) {
435 if (gfs2_meta_wait(sdp, bh)) 391 brelse(bh);
436 goto err; 392 ret = -EIO;
437 } 393 }
438 if (gfs2_metatype_check(sdp, bh, mtype))
439 goto err;
440 }
441
442 if (!in_cache) {
443 spin_lock(&ip->i_spin);
444 if (*bh_slot)
445 brelse(*bh_slot);
446 *bh_slot = bh;
447 get_bh(bh);
448 spin_unlock(&ip->i_spin);
449 } 394 }
450
451 *bhp = bh; 395 *bhp = bh;
452 return 0; 396 return ret;
453err:
454 brelse(bh);
455 return -EIO;
456} 397}
457 398
458/** 399/**