Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=549ae0ac3d574a682e82b02e79259a65445a675b
Commit:     549ae0ac3d574a682e82b02e79259a65445a675b
Parent:     a34fbc6363256387372331000462691bc4b3f5a9
Author:     Wendy Cheng <[EMAIL PROTECTED]>
AuthorDate: Tue Feb 6 03:52:16 2007 -0500
Committer:  Steven Whitehouse <[EMAIL PROTECTED]>
CommitDate: Tue Feb 6 11:36:01 2007 -0500

    [GFS2] nfsd readdirplus assertion failure
    
    Glock assertion failure found in '07 NFS connectathon. One of the NFSDs
    is doing a "readdirplus" procedure call. It passes the logic into
    gfs2_readdir() where it obtains its directory inode glock. This is then
    followed by filehandle construction that invokes lookup code. It hits
    the assertion failure while trying to obtain the inode glock again
    inside gfs2_drevalidate().
    
    This patch bypasses the recursive glock call if caller already holds the
    lock.
    
    Signed-off-by: S. Wendy Cheng <[EMAIL PROTECTED]>
    Signed-off-by: Steven Whitehouse <[EMAIL PROTECTED]>
---
 fs/gfs2/ops_dentry.c |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index d355899..9187eb1 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -46,6 +46,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct 
nameidata *nd)
        struct gfs2_inum_host inum;
        unsigned int type;
        int error;
+       int had_lock=0;
 
        if (inode && is_bad_inode(inode))
                goto invalid;
@@ -53,9 +54,12 @@ static int gfs2_drevalidate(struct dentry *dentry, struct 
nameidata *nd)
        if (sdp->sd_args.ar_localcaching)
                goto valid;
 
-       error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
-       if (error)
-               goto fail;
+       had_lock = gfs2_glock_is_locked_by_me(dip->i_gl);
+       if (!had_lock) {
+               error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
+               if (error)
+                       goto fail;
+       } 
 
        error = gfs2_dir_search(parent->d_inode, &dentry->d_name, &inum, &type);
        switch (error) {
@@ -82,13 +86,15 @@ static int gfs2_drevalidate(struct dentry *dentry, struct 
nameidata *nd)
        }
 
 valid_gunlock:
-       gfs2_glock_dq_uninit(&d_gh);
+       if (!had_lock)
+               gfs2_glock_dq_uninit(&d_gh);
 valid:
        dput(parent);
        return 1;
 
 invalid_gunlock:
-       gfs2_glock_dq_uninit(&d_gh);
+       if (!had_lock)
+               gfs2_glock_dq_uninit(&d_gh);
 invalid:
        if (inode && S_ISDIR(inode->i_mode)) {
                if (have_submounts(dentry))
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to