diff options
Diffstat (limited to 'fs/gfs2/meta_io.c')
-rw-r--r-- | fs/gfs2/meta_io.c | 81 |
1 files changed, 10 insertions, 71 deletions
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 4da423985e4f..01ef90253ed1 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -317,7 +317,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int | |||
317 | } | 317 | } |
318 | if (bd) { | 318 | if (bd) { |
319 | if (bd->bd_ail) { | 319 | if (bd->bd_ail) { |
320 | gfs2_remove_from_ail(NULL, bd); | 320 | gfs2_remove_from_ail(bd); |
321 | bh->b_private = NULL; | 321 | bh->b_private = NULL; |
322 | bd->bd_bh = NULL; | 322 | bd->bd_bh = NULL; |
323 | bd->bd_blkno = bh->b_blocknr; | 323 | bd->bd_blkno = bh->b_blocknr; |
@@ -358,32 +358,6 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
358 | } | 358 | } |
359 | 359 | ||
360 | /** | 360 | /** |
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 | |||
368 | void 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 | 361 | * gfs2_meta_indirect_buffer - Get a metadata buffer |
388 | * @ip: The GFS2 inode | 362 | * @ip: The GFS2 inode |
389 | * @height: The level of this buf in the metadata (indir addr) tree (if any) | 363 | * @height: The level of this buf in the metadata (indir addr) tree (if any) |
@@ -391,8 +365,6 @@ void gfs2_meta_cache_flush(struct gfs2_inode *ip) | |||
391 | * @new: Non-zero if we may create a new buffer | 365 | * @new: Non-zero if we may create a new buffer |
392 | * @bhp: the buffer is returned here | 366 | * @bhp: the buffer is returned here |
393 | * | 367 | * |
394 | * Try to use the gfs2_inode's MRU metadata tree cache. | ||
395 | * | ||
396 | * Returns: errno | 368 | * Returns: errno |
397 | */ | 369 | */ |
398 | 370 | ||
@@ -401,58 +373,25 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
401 | { | 373 | { |
402 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 374 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
403 | struct gfs2_glock *gl = ip->i_gl; | 375 | struct gfs2_glock *gl = ip->i_gl; |
404 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; | 376 | struct buffer_head *bh; |
405 | int in_cache = 0; | 377 | 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 | 378 | ||
424 | if (new) { | 379 | if (new) { |
425 | if (gfs2_assert_warn(sdp, height)) | 380 | BUG_ON(height == 0); |
426 | goto err; | 381 | bh = gfs2_meta_new(gl, num); |
427 | meta_prep_new(bh); | ||
428 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 382 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
429 | gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); | 383 | gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); |
430 | gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); | 384 | gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header)); |
431 | } else { | 385 | } else { |
432 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; | 386 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; |
433 | if (!buffer_uptodate(bh)) { | 387 | ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); |
434 | ll_rw_block(READ_META, 1, &bh); | 388 | if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { |
435 | if (gfs2_meta_wait(sdp, bh)) | 389 | brelse(bh); |
436 | goto err; | 390 | ret = -EIO; |
437 | } | 391 | } |
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 | } | 392 | } |
450 | |||
451 | *bhp = bh; | 393 | *bhp = bh; |
452 | return 0; | 394 | return ret; |
453 | err: | ||
454 | brelse(bh); | ||
455 | return -EIO; | ||
456 | } | 395 | } |
457 | 396 | ||
458 | /** | 397 | /** |