cluster-devel.redhat.com archive mirror
 help / color / mirror / Atom feed
From: swhiteho@redhat.com <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 3/4] [GFS2] Get inode buffer only once per block map call
Date: Tue, 12 Feb 2008 15:34:00 +0000	[thread overview]
Message-ID: <120283045255-git-send-email-swhiteho@redhat.com> (raw)
In-Reply-To: <12028304502947-git-send-email-swhiteho@redhat.com>

From: Steven Whitehouse <swhiteho@redhat.com>

In the case that we needed to grow the height of the metadata tree
we were looking up the inode buffer and then brelse()ing it despite
the fact that it is needed later in the block map process.

This patch ensures that we look up the inode's buffer once and only
once during the block map process.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index e27e660..f1f38ca 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -188,50 +188,45 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
 {
 	struct gfs2_inode *ip = GFS2_I(inode);
 	unsigned new_height = height - ip->i_height;
-	struct buffer_head *dibh;
+	struct buffer_head *dibh = mp->mp_bh[0];
 	struct gfs2_dinode *di;
-	int error;
 	__be64 *bp;
 	u64 bn;
 	unsigned n, i = 0;
 
-	if (height <= ip->i_height)
-		return 0;
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (error)
-		return error;
+	BUG_ON(height <= ip->i_height);
 
 	do {
 		n = new_height - i;
 		bn = gfs2_alloc_block(ip, &n);
 		gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, n);
 		do {
-			mp->mp_bh[i] = gfs2_meta_new(ip->i_gl, bn++);
-			gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[i], 1);
+			mp->mp_bh[i + 1] = gfs2_meta_new(ip->i_gl, bn++);
+			gfs2_trans_add_bh(ip->i_gl, mp->mp_bh[i + 1], 1);
 			i++;
 		} while(i < n);
 	} while(i < new_height);
 
 	n = 0;
-	bn = mp->mp_bh[0]->b_blocknr;
+	bn = mp->mp_bh[1]->b_blocknr;
 	if (new_height > 1) {
 		for(; n < new_height-1; n++) {
-			gfs2_metatype_set(mp->mp_bh[n], GFS2_METATYPE_IN,
+			gfs2_metatype_set(mp->mp_bh[n + 1], GFS2_METATYPE_IN,
 					  GFS2_FORMAT_IN);
-			gfs2_buffer_clear_tail(mp->mp_bh[n],
+			gfs2_buffer_clear_tail(mp->mp_bh[n + 1],
 					       sizeof(struct gfs2_meta_header));
-			bp = (__be64 *)(mp->mp_bh[n]->b_data +
+			bp = (__be64 *)(mp->mp_bh[n + 1]->b_data +
 				     sizeof(struct gfs2_meta_header));
-			*bp = cpu_to_be64(mp->mp_bh[n+1]->b_blocknr);
-			brelse(mp->mp_bh[n]);
-			mp->mp_bh[n] = NULL;
+			*bp = cpu_to_be64(mp->mp_bh[n+2]->b_blocknr);
+			brelse(mp->mp_bh[n+1]);
+			mp->mp_bh[n+1] = NULL;
 		}
 	}
-	gfs2_metatype_set(mp->mp_bh[n], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
-	gfs2_buffer_copy_tail(mp->mp_bh[n], sizeof(struct gfs2_meta_header),
+	gfs2_metatype_set(mp->mp_bh[n+1], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
+	gfs2_buffer_copy_tail(mp->mp_bh[n+1], sizeof(struct gfs2_meta_header),
 			      dibh, sizeof(struct gfs2_dinode));
-	brelse(mp->mp_bh[n]);
+	brelse(mp->mp_bh[n+1]);
+	mp->mp_bh[n+1] = NULL;
 	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
 	di = (struct gfs2_dinode *)dibh->b_data;
 	gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
@@ -240,8 +235,7 @@ static int build_height(struct inode *inode, struct metapath *mp, unsigned heigh
 	gfs2_add_inode_blocks(&ip->i_inode, new_height);
 	di->di_height = cpu_to_be16(ip->i_height);
 	di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
-	brelse(dibh);
-	return error;
+	return 0;
 }
 
 /**
@@ -391,11 +385,7 @@ static int lookup_metapath(struct inode *inode, struct metapath *mp,
 	struct gfs2_inode *ip = GFS2_I(inode);
 	unsigned int end_of_metadata = ip->i_height - 1;
 	unsigned int x;
-	int ret = gfs2_meta_inode_buffer(ip, &bh);
-	if (ret)
-		return ret;
-
-	mp->mp_bh[0] = bh;
+	int ret;
 
 	for (x = 0; x < end_of_metadata; x++) {
 		lookup_block(ip, x, mp, create, new, dblock);
@@ -515,6 +505,10 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
 	}
 	size = (lblock + 1) * bsize;
 
+	error = gfs2_meta_inode_buffer(ip, &mp.mp_bh[0]);
+	if (error)
+		goto out_fail;
+
 	if (size > arr[ip->i_height]) {
 		u8 height = ip->i_height;
 		if (!create)
-- 
1.5.1.2



  reply	other threads:[~2008-02-12 15:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-12 15:33 [Cluster-devel] [GFS2] More cleanup/bug fixes swhiteho
2008-02-12 15:33 ` [Cluster-devel] [PATCH 1/4] [GFS2] Add a function to interate over an extent swhiteho
2008-02-12 15:33   ` [Cluster-devel] [PATCH 2/4] [GFS2] Eliminate (almost) duplicate field from gfs2_inode swhiteho
2008-02-12 15:34     ` swhiteho [this message]
2008-02-12 15:34       ` [Cluster-devel] [PATCH 4/4] [GFS2] Fix bug where we called drop_bh incorrectly swhiteho

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=120283045255-git-send-email-swhiteho@redhat.com \
    --to=swhiteho@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).