mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 05:41:55 +00:00
[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 <wcheng@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
parent
a34fbc6363
commit
549ae0ac3d
@ -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;
|
||||
|
||||
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,12 +86,14 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
|
||||
}
|
||||
|
||||
valid_gunlock:
|
||||
if (!had_lock)
|
||||
gfs2_glock_dq_uninit(&d_gh);
|
||||
valid:
|
||||
dput(parent);
|
||||
return 1;
|
||||
|
||||
invalid_gunlock:
|
||||
if (!had_lock)
|
||||
gfs2_glock_dq_uninit(&d_gh);
|
||||
invalid:
|
||||
if (inode && S_ISDIR(inode->i_mode)) {
|
||||
|
Loading…
Reference in New Issue
Block a user