[GFS2] Remove useless i_cache from inodes
authorSteven Whitehouse <swhiteho@redhat.com>
Mon, 15 Oct 2007 15:29:05 +0000 (16:29 +0100)
committerSteven Whitehouse <swhiteho@redhat.com>
Fri, 25 Jan 2008 08:07:16 +0000 (08:07 +0000)
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>
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/log.c
fs/gfs2/log.h
fs/gfs2/main.c
fs/gfs2/meta_io.c
fs/gfs2/meta_io.h
fs/gfs2/ops_address.c
fs/gfs2/super.c

index 110f03d66f4bd0ee1e2da2a089e213bd7ba706c5..ba124230393b670ca9397cdc79feb4184b07cffd 100644 (file)
@@ -56,7 +56,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
                bd = list_entry(head->next, struct gfs2_bufdata,
                                bd_ail_gl_list);
                bh = bd->bd_bh;
-               gfs2_remove_from_ail(NULL, bd);
+               gfs2_remove_from_ail(bd);
                bd->bd_bh = NULL;
                bh->b_private = NULL;
                bd->bd_blkno = bh->b_blocknr;
@@ -286,23 +286,6 @@ static int inode_go_lock(struct gfs2_holder *gh)
        return error;
 }
 
-/**
- * inode_go_unlock - operation done before an inode lock is unlocked by a
- *                  process
- * @gl: the glock
- * @flags:
- *
- */
-
-static void inode_go_unlock(struct gfs2_holder *gh)
-{
-       struct gfs2_glock *gl = gh->gh_gl;
-       struct gfs2_inode *ip = gl->gl_object;
-
-       if (ip)
-               gfs2_meta_cache_flush(ip);
-}
-
 /**
  * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock
  * @gl: the glock
@@ -377,7 +360,6 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl)
 
        if (gl->gl_state != LM_ST_UNLOCKED &&
            test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
-               gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode));
                j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
 
                error = gfs2_find_jhead(sdp->sd_jdesc, &head);
@@ -437,7 +419,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
        .go_inval = inode_go_inval,
        .go_demote_ok = inode_go_demote_ok,
        .go_lock = inode_go_lock,
-       .go_unlock = inode_go_unlock,
        .go_type = LM_TYPE_INODE,
        .go_min_hold_time = HZ / 10,
 };
index 55c72f01cf3166b0570d8ccad244aa5a34143e36..5662ff9f86e10d569b486baea1d1892f8adf7edf 100644 (file)
@@ -275,8 +275,6 @@ struct gfs2_inode {
        spinlock_t i_spin;
        struct rw_semaphore i_rw_mutex;
        unsigned long i_last_pfault;
-
-       struct buffer_head *i_cache[GFS2_MAX_META_HEIGHT];
 };
 
 /*
index ad0fe373dca5430ce45cf7025fc4f7a2e0e8f4da..af493fc6c8ce7596c453068b6d34e765646f57d4 100644 (file)
@@ -293,11 +293,6 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
        return 0;
 }
 
-static void gfs2_inode_bh(struct gfs2_inode *ip, struct buffer_head *bh)
-{
-       ip->i_cache[0] = bh;
-}
-
 /**
  * gfs2_inode_refresh - Refresh the incore copy of the dinode
  * @ip: The GFS2 inode
@@ -965,7 +960,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 };
        int error;
        u64 generation;
-       struct buffer_head *bh=NULL;
+       struct buffer_head *bh = NULL;
 
        if (!name->len || name->len > GFS2_FNAMESIZE)
                return ERR_PTR(-ENAMETOOLONG);
@@ -1002,8 +997,6 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (IS_ERR(inode))
                goto fail_gunlock2;
 
-       gfs2_inode_bh(GFS2_I(inode), bh);
-
        error = gfs2_inode_refresh(GFS2_I(inode));
        if (error)
                goto fail_gunlock2;
@@ -1020,6 +1013,8 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (error)
                goto fail_gunlock2;
 
+       if (bh)
+               brelse(bh);
        if (!inode)
                return ERR_PTR(-ENOMEM);
        return inode;
@@ -1031,6 +1026,8 @@ fail_gunlock2:
 fail_gunlock:
        gfs2_glock_dq(ghs);
 fail:
+       if (bh)
+               brelse(bh);
        return ERR_PTR(error);
 }
 
index 7df7024732523b8beddb57e3a6d6c3d37e035768..70b404d2774b4099b8c76b2aab88a75a0fb6a7ed 100644 (file)
@@ -68,14 +68,12 @@ unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
  *
  */
 
-void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd)
+void gfs2_remove_from_ail(struct gfs2_bufdata *bd)
 {
        bd->bd_ail = NULL;
        list_del_init(&bd->bd_ail_st_list);
        list_del_init(&bd->bd_ail_gl_list);
        atomic_dec(&bd->bd_gl->gl_ail_count);
-       if (mapping)
-               gfs2_meta_cache_flush(GFS2_I(mapping->host));
        brelse(bd->bd_bh);
 }
 
@@ -248,7 +246,7 @@ static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
                bd = list_entry(head->prev, struct gfs2_bufdata,
                                bd_ail_st_list);
                gfs2_assert(sdp, bd->bd_ail == ai);
-               gfs2_remove_from_ail(bd->bd_bh->b_page->mapping, bd);
+               gfs2_remove_from_ail(bd);
        }
 }
 
index dae2824006273462408a78a36684a432ec16f9a6..24e7161486e270fecab278d39c83a85ebf4b5206 100644 (file)
@@ -59,7 +59,7 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
                                      struct buffer_head *real);
 void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl);
 void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
-void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd);
+void gfs2_remove_from_ail(struct gfs2_bufdata *bd);
 
 void gfs2_log_shutdown(struct gfs2_sbd *sdp);
 void gfs2_meta_syncfs(struct gfs2_sbd *sdp);
index 7ecfe0d3a4913e7d5dc2396599526cb2f781527f..653fd5a6203a551ba6f2c8fa75d570d4c3e02dba 100644 (file)
@@ -31,7 +31,6 @@ static void gfs2_init_inode_once(struct kmem_cache *cachep, void *foo)
        inode_init_once(&ip->i_inode);
        spin_lock_init(&ip->i_spin);
        init_rwsem(&ip->i_rw_mutex);
-       memset(ip->i_cache, 0, sizeof(ip->i_cache));
 }
 
 static void gfs2_init_glock_once(struct kmem_cache *cachep, void *foo)
index 4da423985e4f9178dd752a92fa5c102cd287e66a..01ef90253ed11a4d8c930f9d728f519afd69fe39 100644 (file)
@@ -317,7 +317,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int
        }
        if (bd) {
                if (bd->bd_ail) {
-                       gfs2_remove_from_ail(NULL, bd);
+                       gfs2_remove_from_ail(bd);
                        bh->b_private = NULL;
                        bd->bd_bh = NULL;
                        bd->bd_blkno = bh->b_blocknr;
@@ -357,32 +357,6 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
        }
 }
 
-/**
- * gfs2_meta_cache_flush - get rid of any references on buffers for this inode
- * @ip: The GFS2 inode
- *
- * This releases buffers that are in the most-recently-used array of
- * blocks used for indirect block addressing for this inode.
- */
-
-void gfs2_meta_cache_flush(struct gfs2_inode *ip)
-{
-       struct buffer_head **bh_slot;
-       unsigned int x;
-
-       spin_lock(&ip->i_spin);
-
-       for (x = 0; x < GFS2_MAX_META_HEIGHT; x++) {
-               bh_slot = &ip->i_cache[x];
-               if (*bh_slot) {
-                       brelse(*bh_slot);
-                       *bh_slot = NULL;
-               }
-       }
-
-       spin_unlock(&ip->i_spin);
-}
-
 /**
  * gfs2_meta_indirect_buffer - Get a metadata buffer
  * @ip: The GFS2 inode
@@ -391,8 +365,6 @@ void gfs2_meta_cache_flush(struct gfs2_inode *ip)
  * @new: Non-zero if we may create a new buffer
  * @bhp: the buffer is returned here
  *
- * Try to use the gfs2_inode's MRU metadata tree cache.
- *
  * Returns: errno
  */
 
@@ -401,58 +373,25 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_glock *gl = ip->i_gl;
-       struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height;
-       int in_cache = 0;
-
-       BUG_ON(!gl);
-       BUG_ON(!sdp);
-
-       spin_lock(&ip->i_spin);
-       if (*bh_slot && (*bh_slot)->b_blocknr == num) {
-               bh = *bh_slot;
-               get_bh(bh);
-               in_cache = 1;
-       }
-       spin_unlock(&ip->i_spin);
-
-       if (!bh)
-               bh = getbuf(gl, num, CREATE);
-
-       if (!bh)
-               return -ENOBUFS;
+       struct buffer_head *bh;
+       int ret = 0;
 
        if (new) {
-               if (gfs2_assert_warn(sdp, height))
-                       goto err;
-               meta_prep_new(bh);
+               BUG_ON(height == 0);
+               bh = gfs2_meta_new(gl, num);
                gfs2_trans_add_bh(ip->i_gl, bh, 1);
                gfs2_metatype_set(bh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
                gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
        } else {
                u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
-               if (!buffer_uptodate(bh)) {
-                       ll_rw_block(READ_META, 1, &bh);
-                       if (gfs2_meta_wait(sdp, bh))
-                               goto err;
+               ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh);
+               if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) {
+                       brelse(bh);
+                       ret = -EIO;
                }
-               if (gfs2_metatype_check(sdp, bh, mtype))
-                       goto err;
-       }
-
-       if (!in_cache) {
-               spin_lock(&ip->i_spin);
-               if (*bh_slot)
-                       brelse(*bh_slot);
-               *bh_slot = bh;
-               get_bh(bh);
-               spin_unlock(&ip->i_spin);
        }
-
        *bhp = bh;
-       return 0;
-err:
-       brelse(bh);
-       return -EIO;
+       return ret;
 }
 
 /**
index b7048222ebb46fb1c4fdd9157430823a48e8c603..73e3b1c76fe145c637707bb241faab0a0c00513a 100644 (file)
@@ -56,7 +56,6 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr,
 
 void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen);
 
-void gfs2_meta_cache_flush(struct gfs2_inode *ip);
 int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
                              int new, struct buffer_head **bhp);
 
index 1696e5d9d112c937e1de075bd19c1b54072f5444..4c4ef7f59909558028948dc5524488a7e5d236e6 100644 (file)
@@ -154,7 +154,6 @@ static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
        error = block_write_full_page(page, gfs2_get_block_noalloc, wbc);
        if (done_trans)
                gfs2_trans_end(sdp);
-       gfs2_meta_cache_flush(ip);
        return error;
 
 out_ignore:
index dd3e737f528e0b111387b506608e63fc99ef5c0b..5183dfb9342a7e580fca106e3875d17953b7a651 100644 (file)
@@ -543,7 +543,6 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
        if (error)
                return error;
 
-       gfs2_meta_cache_flush(ip);
        j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
 
        error = gfs2_find_jhead(sdp->sd_jdesc, &head);