aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-10-15 11:29:05 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2008-01-25 03:07:16 -0500
commitf91a0d3e24e4b0198be5fae20d45a35c40d1efce (patch)
treecda8095f9befd25cbfaf5f63a4c8ca26870d45ca /fs
parent3cc3f710ce0effe397b830826a1a081fa81f11c7 (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')
-rw-r--r--fs/gfs2/glops.c21
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/inode.c13
-rw-r--r--fs/gfs2/log.c6
-rw-r--r--fs/gfs2/log.h2
-rw-r--r--fs/gfs2/main.c1
-rw-r--r--fs/gfs2/meta_io.c81
-rw-r--r--fs/gfs2/meta_io.h1
-rw-r--r--fs/gfs2/ops_address.c1
-rw-r--r--fs/gfs2/super.c1
10 files changed, 19 insertions, 110 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 110f03d66f4b..ba124230393b 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -56,7 +56,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
56 bd = list_entry(head->next, struct gfs2_bufdata, 56 bd = list_entry(head->next, struct gfs2_bufdata,
57 bd_ail_gl_list); 57 bd_ail_gl_list);
58 bh = bd->bd_bh; 58 bh = bd->bd_bh;
59 gfs2_remove_from_ail(NULL, bd); 59 gfs2_remove_from_ail(bd);
60 bd->bd_bh = NULL; 60 bd->bd_bh = NULL;
61 bh->b_private = NULL; 61 bh->b_private = NULL;
62 bd->bd_blkno = bh->b_blocknr; 62 bd->bd_blkno = bh->b_blocknr;
@@ -287,23 +287,6 @@ static int inode_go_lock(struct gfs2_holder *gh)
287} 287}
288 288
289/** 289/**
290 * inode_go_unlock - operation done before an inode lock is unlocked by a
291 * process
292 * @gl: the glock
293 * @flags:
294 *
295 */
296
297static void inode_go_unlock(struct gfs2_holder *gh)
298{
299 struct gfs2_glock *gl = gh->gh_gl;
300 struct gfs2_inode *ip = gl->gl_object;
301
302 if (ip)
303 gfs2_meta_cache_flush(ip);
304}
305
306/**
307 * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock 290 * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock
308 * @gl: the glock 291 * @gl: the glock
309 * 292 *
@@ -377,7 +360,6 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl)
377 360
378 if (gl->gl_state != LM_ST_UNLOCKED && 361 if (gl->gl_state != LM_ST_UNLOCKED &&
379 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { 362 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
380 gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode));
381 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); 363 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
382 364
383 error = gfs2_find_jhead(sdp->sd_jdesc, &head); 365 error = gfs2_find_jhead(sdp->sd_jdesc, &head);
@@ -437,7 +419,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
437 .go_inval = inode_go_inval, 419 .go_inval = inode_go_inval,
438 .go_demote_ok = inode_go_demote_ok, 420 .go_demote_ok = inode_go_demote_ok,
439 .go_lock = inode_go_lock, 421 .go_lock = inode_go_lock,
440 .go_unlock = inode_go_unlock,
441 .go_type = LM_TYPE_INODE, 422 .go_type = LM_TYPE_INODE,
442 .go_min_hold_time = HZ / 10, 423 .go_min_hold_time = HZ / 10,
443}; 424};
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 55c72f01cf31..5662ff9f86e1 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -275,8 +275,6 @@ struct gfs2_inode {
275 spinlock_t i_spin; 275 spinlock_t i_spin;
276 struct rw_semaphore i_rw_mutex; 276 struct rw_semaphore i_rw_mutex;
277 unsigned long i_last_pfault; 277 unsigned long i_last_pfault;
278
279 struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT];
280}; 278};
281 279
282/* 280/*
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index ad0fe373dca5..af493fc6c8ce 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -293,11 +293,6 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
293 return 0; 293 return 0;
294} 294}
295 295
296static void gfs2_inode_bh(struct gfs2_inode *ip, struct buffer_head *bh)
297{
298 ip->i_cache[0] = bh;
299}
300
301/** 296/**
302 * gfs2_inode_refresh - Refresh the incore copy of the dinode 297 * gfs2_inode_refresh - Refresh the incore copy of the dinode
303 * @ip: The GFS2 inode 298 * @ip: The GFS2 inode
@@ -965,7 +960,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
965 struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; 960 struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 };
966 int error; 961 int error;
967 u64 generation; 962 u64 generation;
968 struct buffer_head *bh=NULL; 963 struct buffer_head *bh = NULL;
969 964
970 if (!name->len || name->len > GFS2_FNAMESIZE) 965 if (!name->len || name->len > GFS2_FNAMESIZE)
971 return ERR_PTR(-ENAMETOOLONG); 966 return ERR_PTR(-ENAMETOOLONG);
@@ -1002,8 +997,6 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
1002 if (IS_ERR(inode)) 997 if (IS_ERR(inode))
1003 goto fail_gunlock2; 998 goto fail_gunlock2;
1004 999
1005 gfs2_inode_bh(GFS2_I(inode), bh);
1006
1007 error = gfs2_inode_refresh(GFS2_I(inode)); 1000 error = gfs2_inode_refresh(GFS2_I(inode));
1008 if (error) 1001 if (error)
1009 goto fail_gunlock2; 1002 goto fail_gunlock2;
@@ -1020,6 +1013,8 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
1020 if (error) 1013 if (error)
1021 goto fail_gunlock2; 1014 goto fail_gunlock2;
1022 1015
1016 if (bh)
1017 brelse(bh);
1023 if (!inode) 1018 if (!inode)
1024 return ERR_PTR(-ENOMEM); 1019 return ERR_PTR(-ENOMEM);
1025 return inode; 1020 return inode;
@@ -1031,6 +1026,8 @@ fail_gunlock2:
1031fail_gunlock: 1026fail_gunlock:
1032 gfs2_glock_dq(ghs); 1027 gfs2_glock_dq(ghs);
1033fail: 1028fail:
1029 if (bh)
1030 brelse(bh);
1034 return ERR_PTR(error); 1031 return ERR_PTR(error);
1035} 1032}
1036 1033
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 7df702473252..70b404d2774b 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -68,14 +68,12 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
68 * 68 *
69 */ 69 */
70 70
71void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd) 71void gfs2_remove_from_ail(struct gfs2_bufdata *bd)
72{ 72{
73 bd->bd_ail = NULL; 73 bd->bd_ail = NULL;
74 list_del_init(&bd->bd_ail_st_list); 74 list_del_init(&bd->bd_ail_st_list);
75 list_del_init(&bd->bd_ail_gl_list); 75 list_del_init(&bd->bd_ail_gl_list);
76 atomic_dec(&bd->bd_gl->gl_ail_count); 76 atomic_dec(&bd->bd_gl->gl_ail_count);
77 if (mapping)
78 gfs2_meta_cache_flush(GFS2_I(mapping->host));
79 brelse(bd->bd_bh); 77 brelse(bd->bd_bh);
80} 78}
81 79
@@ -248,7 +246,7 @@ static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
248 bd = list_entry(head->prev, struct gfs2_bufdata, 246 bd = list_entry(head->prev, struct gfs2_bufdata,
249 bd_ail_st_list); 247 bd_ail_st_list);
250 gfs2_assert(sdp, bd->bd_ail == ai); 248 gfs2_assert(sdp, bd->bd_ail == ai);
251 gfs2_remove_from_ail(bd->bd_bh->b_page->mapping, bd); 249 gfs2_remove_from_ail(bd);
252 } 250 }
253} 251}
254 252
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index dae282400627..24e7161486e2 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -59,7 +59,7 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
59 struct buffer_head *real); 59 struct buffer_head *real);
60void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); 60void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
61void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); 61void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
62void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd); 62void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
63 63
64void gfs2_log_shutdown(struct gfs2_sbd *sdp); 64void gfs2_log_shutdown(struct gfs2_sbd *sdp);
65void gfs2_meta_syncfs(struct gfs2_sbd *sdp); 65void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 7ecfe0d3a491..653fd5a6203a 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -31,7 +31,6 @@ static void gfs2_init_inode_once(struct kmem_cache *cachep, void *foo)
31 inode_init_once(&ip->i_inode); 31 inode_init_once(&ip->i_inode);
32 spin_lock_init(&ip->i_spin); 32 spin_lock_init(&ip->i_spin);
33 init_rwsem(&ip->i_rw_mutex); 33 init_rwsem(&ip->i_rw_mutex);
34 memset(ip->i_cache, 0, sizeof(ip->i_cache));
35} 34}
36 35
37static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo) 36static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo)
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
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 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;
453err:
454 brelse(bh);
455 return -EIO;
456} 395}
457 396
458/** 397/**
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h
index b7048222ebb4..73e3b1c76fe1 100644
--- a/fs/gfs2/meta_io.h
+++ b/fs/gfs2/meta_io.h
@@ -56,7 +56,6 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr,
56 56
57void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen); 57void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen);
58 58
59void gfs2_meta_cache_flush(struct gfs2_inode *ip);
60int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, 59int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
61 int new, struct buffer_head **bhp); 60 int new, struct buffer_head **bhp);
62 61
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 1696e5d9d112..4c4ef7f59909 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -154,7 +154,6 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
154 error = block_write_full_page(page, gfs2_get_block_noalloc, wbc); 154 error = block_write_full_page(page, gfs2_get_block_noalloc, wbc);
155 if (done_trans) 155 if (done_trans)
156 gfs2_trans_end(sdp); 156 gfs2_trans_end(sdp);
157 gfs2_meta_cache_flush(ip);
158 return error; 157 return error;
159 158
160out_ignore: 159out_ignore:
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index dd3e737f528e..5183dfb9342a 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -543,7 +543,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
543 if (error) 543 if (error)
544 return error; 544 return error;
545 545
546 gfs2_meta_cache_flush(ip);
547 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); 546 j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
548 547
549 error = gfs2_find_jhead(sdp->sd_jdesc, &head); 548 error = gfs2_find_jhead(sdp->sd_jdesc, &head);