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


Reply via email to