[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] [GFS2 patch] Performance gain creating dinodes



Hi,

In function gfs2_inode_lookup, it calls gfs2_glock_get to fetch
the glock associated with the inode.  However, when a new inode
is being created, the calling function, gfs2_createi, already
has that information.  By passing the existing glock in as a
parameter, it can avoid looking up the glock in the hash table,
which involves locking the hash table and possible contention.

Regards,

Bob Peterson
Red Hat Clustering & GFS
--
 fs/gfs2/dir.c        |    3 ++-
 fs/gfs2/inode.c      |   18 ++++++++++++------
 fs/gfs2/inode.h      |    3 ++-
 fs/gfs2/ops_export.c |    2 +-
 fs/gfs2/ops_fstype.c |    2 +-
 fs/gfs2/rgrp.c       |    2 +-
 7 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index eed040d..bd18ffc 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1501,7 +1501,8 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
 		inode = gfs2_inode_lookup(dir->i_sb, 
 				be16_to_cpu(dent->de_type),
 				be64_to_cpu(dent->de_inum.no_addr),
-				be64_to_cpu(dent->de_inum.no_formal_ino), 0);
+				be64_to_cpu(dent->de_inum.no_formal_ino), 0,
+				NULL);
 		brelse(bh);
 		return inode;
 	}
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 3a9ef52..8e69d1f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -166,10 +166,11 @@ void gfs2_set_iop(struct inode *inode)
  * Returns: A VFS inode, or an error
  */
 
-struct inode *gfs2_inode_lookup(struct super_block *sb, 
+struct inode *gfs2_inode_lookup(struct super_block *sb,
 				unsigned int type,
 				u64 no_addr,
-				u64 no_formal_ino, int skip_freeing)
+				u64 no_formal_ino, int skip_freeing,
+				struct gfs2_glock *existing_gl)
 {
 	struct inode *inode;
 	struct gfs2_inode *ip;
@@ -190,9 +191,14 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
 		inode->i_private = ip;
 		ip->i_no_formal_ino = no_formal_ino;
 
-		error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
-		if (unlikely(error))
-			goto fail;
+		if (existing_gl) {
+			ip->i_gl = existing_gl;
+			atomic_inc(&ip->i_gl->gl_ref);
+		} else {
+			error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
+			if (unlikely(error))
+				goto fail;
+		}
 		ip->i_gl->gl_object = ip;
 
 		error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
@@ -1016,7 +1022,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 
 	inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode),
 					inum.no_addr,
-					inum.no_formal_ino, 0);
+				  inum.no_formal_ino, 0, ghs[1].gh_gl);
 	if (IS_ERR(inode))
 		goto fail_gunlock2;
 
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 580da45..072dce3 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -76,7 +76,8 @@ void gfs2_inode_attr_in(struct gfs2_inode *ip);
 void gfs2_set_iop(struct inode *inode);
 struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, 
 				u64 no_addr, u64 no_formal_ino,
-				int skip_freeing);
+				int skip_freeing,
+				struct gfs2_glock *existing_gl);
 struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr);
 
 int gfs2_inode_refresh(struct gfs2_inode *ip);
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index 990d9f4..65d8630 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -203,7 +203,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
 
 	inode = gfs2_inode_lookup(sb, DT_UNKNOWN,
 					inum->no_addr,
-					0, 0);
+				  0, 0, NULL);
 	if (IS_ERR(inode)) {
 		error = PTR_ERR(inode);
 		goto fail;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index ef9c6c4..f1e70ef 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -228,7 +228,7 @@ fail:
 static inline struct inode *gfs2_lookup_root(struct super_block *sb,
 					     u64 no_addr)
 {
-	return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0);
+	return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0, NULL);
 }
 
 static int init_sb(struct gfs2_sbd *sdp, int silent, int undo)
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 7e8f0b1..1085fe2 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -935,7 +935,7 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
 			continue;
 		*last_unlinked = no_addr;
 		inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
-					  no_addr, -1, 1);
+					  no_addr, -1, 1, NULL);
 		if (!IS_ERR(inode))
 			return inode;
 	}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]