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;
}