aboutsummaryrefslogtreecommitdiff
path: root/sys/nfs4client
diff options
context:
space:
mode:
authorMohan Srinivasan <mohans@FreeBSD.org>2006-09-13 18:39:09 +0000
committerMohan Srinivasan <mohans@FreeBSD.org>2006-09-13 18:39:09 +0000
commit7d7d9e22427335af6d0ff1fe811ac085fb8bf204 (patch)
treeecb7983045b3f7e892ee6bce4b4f36f4080332f4 /sys/nfs4client
parentcec65ede6c3990b5974f201c2c2ece974d037b0a (diff)
downloadsrc-7d7d9e22427335af6d0ff1fe811ac085fb8bf204.tar.gz
src-7d7d9e22427335af6d0ff1fe811ac085fb8bf204.zip
Fixes up the handling of shared vnode lock lookups in the NFS client,
adds a FS type specific flag indicating that the FS supports shared vnode lock lookups, adds some logic in vfs_lookup.c to test this flag and set lock flags appropriately. - amd on 6.x is a non-starter (without this change). Using amd under heavy load results in a deadlock (with cascading vnode locks all the way to the root) very quickly. - This change should also fix the more general problem of cascading vnode deadlocks when an NFS server goes down. Ideally, we wouldn't need these changes, as enabling shared vnode lock lookups globally would work. Unfortunately, UFS, for example isn't ready for shared vnode lock lookups, crashing pretty quickly. This change is the result of discussions with Stephan Uphoff (ups@). Reviewed by: ups@
Notes
Notes: svn path=/head/; revision=162288
Diffstat (limited to 'sys/nfs4client')
-rw-r--r--sys/nfs4client/nfs4_vfsops.c4
-rw-r--r--sys/nfs4client/nfs4_vnops.c12
2 files changed, 8 insertions, 8 deletions
diff --git a/sys/nfs4client/nfs4_vfsops.c b/sys/nfs4client/nfs4_vfsops.c
index 0eb113bcfeaa..6bb1b9cbacd4 100644
--- a/sys/nfs4client/nfs4_vfsops.c
+++ b/sys/nfs4client/nfs4_vfsops.c
@@ -200,7 +200,7 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
#ifndef nolint
sfp = NULL;
#endif
- error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
+ error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
if (error)
return (error);
vp = NFSTOV(np);
@@ -724,7 +724,7 @@ nfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
int error;
nmp = VFSTONFS(mp);
- error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
+ error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
if (error)
return (error);
vp = NFSTOV(np);
diff --git a/sys/nfs4client/nfs4_vnops.c b/sys/nfs4client/nfs4_vnops.c
index f0e920ed268d..5867471234bf 100644
--- a/sys/nfs4client/nfs4_vnops.c
+++ b/sys/nfs4client/nfs4_vnops.c
@@ -497,7 +497,7 @@ nfs4_openrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
if (vp == NULL) {
/* New file */
error = nfs_nget(dvp->v_mount, &getfh.fh_val,
- getfh.fh_len, &np);
+ getfh.fh_len, &np, LK_EXCLUSIVE);
if (error != 0)
goto nfsmout;
@@ -1031,7 +1031,7 @@ nfs4_lookup(struct vop_lookup_args *ap)
if (NFS_CMPFH(np, fhp, fhsize))
return (EISDIR);
- error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
+ error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
if (error)
return (error);
@@ -1047,7 +1047,7 @@ nfs4_lookup(struct vop_lookup_args *ap)
if (flags & ISDOTDOT) {
VOP_UNLOCK(dvp, 0, td);
- error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
+ error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
if (error)
return (error);
@@ -1058,7 +1058,7 @@ nfs4_lookup(struct vop_lookup_args *ap)
VREF(dvp);
newvp = dvp;
} else {
- error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
+ error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
if (error)
return (error);
newvp = NFSTOV(np);
@@ -1431,7 +1431,7 @@ nfs4_createrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
nfsm_v4dissect_getattr(&cp, &ga);
nfsm_v4dissect_getfh(&cp, &gfh);
- error = nfs_nget(dvp->v_mount, &gfh.fh_val, gfh.fh_len, &np);
+ error = nfs_nget(dvp->v_mount, &gfh.fh_val, gfh.fh_len, &np, LK_EXCLUSIVE);
if (error != 0)
goto nfsmout;
@@ -2336,7 +2336,7 @@ nfs4_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred,
VREF(dvp);
newvp = dvp;
} else {
- error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np);
+ error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, LK_EXCLUSIVE);
if (error) {
m_freem(mrep);
return (error);