diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-10-15 11:29:05 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2008-01-25 03:07:16 -0500 |
commit | f91a0d3e24e4b0198be5fae20d45a35c40d1efce (patch) | |
tree | cda8095f9befd25cbfaf5f63a4c8ca26870d45ca /fs/gfs2/meta_io.c | |
parent | 3cc3f710ce0effe397b830826a1a081fa81f11c7 (diff) |
[GFS2] Remove useless i_cache from inodes
The i_cache was designed to keep references to the indirect blocks
used during block mapping so that they didn't have to be looked
up continually. The idea failed because there are too many places
where the i_cache needs to be freed, and this has in the past been
the cause of many bugs.
In addition there was no performance benefit being gained since the
disk blocks in question were cached anyway. So this patch removes
it in order to simplify the code to prepare for other changes which
would otherwise have had to add further support for this feature.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
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 | /** |