FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 12-12-2007, 12:21 AM
Bob Peterson
 
Default Only find indirect pointer buffers once

Hi,

Function gfs2_block_map was re-reading blocks used to store indirect
block pointers on every call. This patch tries to find the buffers
associated with those blocks in the le_list and, if found, re-uses them
instead of re-reading them every time.
The buffers are only used for block lookups (not modified) so I don't
think this should impact anything, except being a bit faster.

There's also a slight optimization in function find_metapath, which is
used a lot.

Regards,

Bob Peterson
Red Hat GFS

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
--
.../fs/gfs2/bmap.c | 46 +++++++++++++++++---
1 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/gfs2-2.6.git.patch7/fs/gfs2/bmap.c b/gfs2-2.6.git.patch8/fs/gfs2/bmap.c
index 0974912..9b6e871 100644
--- a/gfs2-2.6.git.patch7/fs/gfs2/bmap.c
+++ b/gfs2-2.6.git.patch8/fs/gfs2/bmap.c
@@ -342,11 +342,10 @@ static void find_metapath(struct gfs2_inode *ip, u64 block,
struct metapath *mp)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
- u64 b = block;
unsigned int i;

for (i = ip->i_di.di_height; i--
- mp->mp_list[i] = do_div(b, sdp->sd_inptrs);
+ mp->mp_list[i] = do_div(block, sdp->sd_inptrs);

}

@@ -441,6 +440,31 @@ static inline void bmap_unlock(struct inode *inode, int create)
}

/**
+ * find_bh - Try to locate a buffer head for a given data block
+ * @sdp: the filesystem
+ * @lblock: The logical block number
+ * @bhp: Pointer to a pointer to a buffer head to contain the one found
+ *
+ * Returns: 1 if a bh was found for dblock, or 0 if dblock was not found
+ */
+static int find_bh(struct gfs2_sbd *sdp, u64 dblock, struct buffer_head **bhp)
+{
+ struct gfs2_bufdata *bd = NULL;
+ struct buffer_head *bh;
+ int ret = 0;
+
+ list_for_each_entry(bd, &sdp->sd_log_le_buf, bd_le.le_list) {
+ bh = bd->bd_bh;
+ if (bh && buffer_mapped(bh) && bh->b_blocknr == dblock) {
+ *bhp = bh;
+ ret = 1;
+ break;
+ }
+ }
+ return ret;
+}
+
+/**
* gfs2_block_map - Map a block from an inode to a disk block
* @inode: The inode
* @lblock: The logical block number
@@ -470,6 +494,7 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
struct metapath mp;
u64 size;
struct buffer_head *dibh = NULL;
+ int existing_bh;

BUG_ON(maxlen == 0);

@@ -502,16 +527,22 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
goto out_fail;
dibh = bh;
get_bh(dibh);
+ existing_bh = 0;

for (x = 0; x < end_of_metadata; x++) {
lookup_block(ip, bh, x, &mp, create, &new, &dblock);
- brelse(bh);
+ if (!existing_bh)
+ brelse(bh);
if (!dblock)
goto out_ok;

- error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh);
- if (error)
- goto out_fail;
+ existing_bh = new ? 0 : find_bh(sdp, dblock, &bh);
+ if (!existing_bh) {
+ error = gfs2_meta_indirect_buffer(ip, x+1, dblock,
+ new, &bh);
+ if (error)
+ goto out_fail;
+ }
}

boundary = lookup_block(ip, bh, end_of_metadata, &mp, create, &new, &dblock);
@@ -538,7 +569,8 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
}
}
out_brelse:
- brelse(bh);
+ if (!existing_bh)
+ brelse(bh);
out_ok:
error = 0;
out_fail:
 

Thread Tools




All times are GMT. The time now is 08:09 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org