Subject: LK_SHARED for VFS_VGET/FHTOVP
To: None <tech-kern@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-kern
Date: 05/25/2004 21:59:18
--NextPart-20040525213040-0071800
Content-Type: Text/Plain; charset=us-ascii

hi,

i'd like to add an additional "lkflag" argument to VFS_VGET
and VFS_FHTOVP so that nfsd won't try to acquire exclusive lock
unnecessarily.

the attached diff contains only ffs and nfs.
if no one objects, i'll do the rest of filesystems and check them in.

YAMAMOTO Takashi

--NextPart-20040525213040-0071800
Content-Type: Text/Plain; charset=us-ascii
Content-Disposition: attachment; filename="shlk.diff"

Index: sys/mount.h
===================================================================
--- sys/mount.h	(revision 682)
+++ sys/mount.h	(working copy)
@@ -233,9 +233,10 @@ struct vfsops {
 				    struct proc *));
 	int	(*vfs_sync)	__P((struct mount *, int, struct ucred *,
 				    struct proc *));
-	int	(*vfs_vget)	__P((struct mount *, ino_t, struct vnode **));
+	int	(*vfs_vget)	__P((struct mount *, ino_t, struct vnode **,
+				    int));
 	int	(*vfs_fhtovp)	__P((struct mount *, struct fid *,
-				    struct vnode **));
+				    struct vnode **, int));
 	int	(*vfs_vptofh)	__P((struct vnode *, struct fid *));
 	void	(*vfs_init)	__P((void));
 	void	(*vfs_reinit)	__P((void));
@@ -257,8 +258,10 @@ struct vfsops {
 #define VFS_QUOTACTL(MP,C,U,A,P)  (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A, P)
 #define VFS_STATVFS(MP, SBP, P)	  (*(MP)->mnt_op->vfs_statvfs)(MP, SBP, P)
 #define VFS_SYNC(MP, WAIT, C, P)  (*(MP)->mnt_op->vfs_sync)(MP, WAIT, C, P)
-#define VFS_VGET(MP, INO, VPP)	  (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP)
-#define VFS_FHTOVP(MP, FIDP, VPP) (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP)
+#define VFS_VGET(MP, INO, VPP, LKFLAG) \
+	(*(MP)->mnt_op->vfs_vget)(MP, INO, VPP, LKFLAG)
+#define VFS_FHTOVP(MP, FIDP, VPP, LKFLAG) \
+	(*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP, LKFLAG)
 #define VFS_CHECKEXP(MP, NAM, EXFLG, CRED) \
 	(*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED)
 #define	VFS_VPTOFH(VP, FIDP)	  (*(VP)->v_mount->mnt_op->vfs_vptofh)(VP, FIDP)
Index: kern/vfs_syscalls.c
===================================================================
--- kern/vfs_syscalls.c	(revision 682)
+++ kern/vfs_syscalls.c	(working copy)
@@ -1277,7 +1277,7 @@ sys_fhopen(l, v, retval)
 		goto bad;
 	}
 
-	if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)) != 0) {
+	if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp, LK_EXCLUSIVE)) != 0) {
 		vp = NULL;	/* most likely unnecessary sanity for bad: */
 		goto bad;
 	}
@@ -1397,7 +1397,7 @@ sys_fhstat(l, v, retval)
 
 	if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
 		return (ESTALE);
-	if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
+	if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp, LK_EXCLUSIVE)))
 		return (error);
 	error = vn_stat(vp, &sb, p);
 	vput(vp);
@@ -1437,7 +1437,7 @@ sys_fhstatvfs1(l, v, retval)
 
 	if ((mp = vfs_getvfs(&fh.fh_fsid)) == NULL)
 		return ESTALE;
-	if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp)))
+	if ((error = VFS_FHTOVP(mp, &fh.fh_fid, &vp, LK_EXCLUSIVE)))
 		return error;
 
 	mp = vp->v_mount;
Index: ufs/ufs/ufs_vnops.c
===================================================================
--- ufs/ufs/ufs_vnops.c	(revision 720)
+++ ufs/ufs/ufs_vnops.c	(working copy)
@@ -159,7 +159,7 @@ ufs_mknod(void *v)
 	vput(*vpp);
 	(*vpp)->v_type = VNON;
 	vgone(*vpp);
-	error = VFS_VGET(mp, ino, vpp);
+	error = VFS_VGET(mp, ino, vpp, LK_EXCLUSIVE);
 	if (error != 0) {
 		*vpp = NULL;
 		return (error);
Index: ufs/ufs/ufs_lookup.c
===================================================================
--- ufs/ufs/ufs_lookup.c	(revision 671)
+++ ufs/ufs/ufs_lookup.c	(working copy)
@@ -493,7 +493,7 @@ found:
 		}
 		if (flags & ISDOTDOT)
 			VOP_UNLOCK(vdp, 0); /* race to get the inode */
-		error = VFS_VGET(vdp->v_mount, foundino, &tdp);
+		error = VFS_VGET(vdp->v_mount, foundino, &tdp, LK_EXCLUSIVE);
 		if (flags & ISDOTDOT)
 			vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY);
 		if (error)
@@ -537,7 +537,7 @@ found:
 			return (EISDIR);
 		if (flags & ISDOTDOT)
 			VOP_UNLOCK(vdp, 0); /* race to get the inode */
-		error = VFS_VGET(vdp->v_mount, foundino, &tdp);
+		error = VFS_VGET(vdp->v_mount, foundino, &tdp, LK_EXCLUSIVE);
 		if (flags & ISDOTDOT)
 			vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY);
 		if (error)
@@ -574,7 +574,7 @@ found:
 	if (flags & ISDOTDOT) {
 		VOP_UNLOCK(pdp, 0);	/* race to get the inode */
 		cnp->cn_flags |= PDIRUNLOCK;
-		error = VFS_VGET(vdp->v_mount, foundino, &tdp);
+		error = VFS_VGET(vdp->v_mount, foundino, &tdp, LK_EXCLUSIVE);
 		if (error) {
 			if (vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY) == 0)
 				cnp->cn_flags &= ~PDIRUNLOCK;
@@ -592,7 +592,7 @@ found:
 		VREF(vdp);	/* we want ourself, ie "." */
 		*vpp = vdp;
 	} else {
-		error = VFS_VGET(vdp->v_mount, foundino, &tdp);
+		error = VFS_VGET(vdp->v_mount, foundino, &tdp, LK_EXCLUSIVE);
 		if (error)
 			return (error);
 		if (!lockparent || !(flags & ISLASTCN)) {
@@ -1207,7 +1207,7 @@ ufs_checkpath(source, target, cred)
 			break;
 		vput(vp);
 		error = VFS_VGET(vp->v_mount,
-		    ufs_rw32(dirbuf.dotdot_ino, needswap), &vp);
+		    ufs_rw32(dirbuf.dotdot_ino, needswap), &vp, LK_EXCLUSIVE);
 		if (error) {
 			vp = NULL;
 			break;
Index: ufs/ufs/ufs_extern.h
===================================================================
--- ufs/ufs/ufs_extern.h	(revision 681)
+++ ufs/ufs/ufs_extern.h	(working copy)
@@ -156,7 +156,7 @@ void ufs_done __P((void));
 int ufs_start __P((struct mount *, int, struct proc *));
 int ufs_root __P((struct mount *, struct vnode **));
 int ufs_quotactl __P((struct mount *, int, uid_t, void *, struct proc *));
-int ufs_fhtovp __P((struct mount *, struct ufid *, struct vnode **));
+int ufs_fhtovp __P((struct mount *, struct ufid *, struct vnode **, int));
 int ufs_check_export __P((struct mount *, struct mbuf *, int *,
 		struct ucred **));
 
Index: ufs/ufs/ufs_vfsops.c
===================================================================
--- ufs/ufs/ufs_vfsops.c	(revision 681)
+++ ufs/ufs/ufs_vfsops.c	(working copy)
@@ -85,7 +85,7 @@ ufs_root(mp, vpp)
 	struct vnode *nvp;
 	int error;
 
-	if ((error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp)) != 0)
+	if ((error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp, LK_EXCLUSIVE)) != 0)
 		return (error);
 	*vpp = nvp;
 	return (0);
@@ -195,16 +195,17 @@ ufs_check_export(mp, nam, exflagsp, cred
  * filesystem has validated the file handle.
  */
 int
-ufs_fhtovp(mp, ufhp, vpp)
+ufs_fhtovp(mp, ufhp, vpp, lkflag)
 	struct mount *mp;
 	struct ufid *ufhp;
 	struct vnode **vpp;
+	int lkflag;
 {
 	struct vnode *nvp;
 	struct inode *ip;
 	int error;
 
-	if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) {
+	if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp, lkflag)) != 0) {
 		*vpp = NULLVP;
 		return (error);
 	}
Index: ufs/ffs/ffs_softdep.c
===================================================================
--- ufs/ffs/ffs_softdep.c	(revision 679)
+++ ufs/ffs/ffs_softdep.c	(working copy)
@@ -3263,7 +3263,8 @@ handle_workitem_remove(dirrem)
 	ino_t oldinum;
 	int error;
 
-	if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp)) != 0) {
+	if ((error = VFS_VGET(dirrem->dm_mnt, dirrem->dm_oldinum, &vp,
+	    LK_EXCLUSIVE)) != 0) {
 		softdep_error("handle_workitem_remove: vget", error);
 		return;
 	}
@@ -4739,7 +4740,7 @@ softdep_fsync(vp)
 		 */
 		FREE_LOCK(&lk);
 		VOP_UNLOCK(vp, 0);
-		error = VFS_VGET(mnt, parentino, &pvp);
+		error = VFS_VGET(mnt, parentino, &pvp, LK_EXCLUSIVE);
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 		if (error != 0)
 			return (error);
@@ -5286,7 +5287,8 @@ flush_pagedep_deps(pvp, mp, diraddhdp)
 		if (dap->da_state & MKDIR_BODY) {
 			FREE_LOCK(&lk);
 			ipflag = vn_setrecurse(pvp);	/* XXX */
-			if ((error = VFS_VGET(mp, inum, &vp)) != 0)
+			if ((error = VFS_VGET(mp, inum, &vp,
+			    LK_EXCLUSIVE)) != 0)
 				break;
 			if ((error = VOP_FSYNC(vp, p->p_ucred, 0, 0, 0, p)) ||
 			    (error = VOP_FSYNC(vp, p->p_ucred, 0, 0, 0, p))) {
@@ -5476,7 +5478,8 @@ clear_remove(p)
 			if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
 				continue;
 			FREE_LOCK(&lk);
-			if ((error = VFS_VGET(mp, ino, &vp)) != 0) {
+			if ((error = VFS_VGET(mp, ino, &vp,
+			    LK_EXCLUSIVE)) != 0) {
 				softdep_error("clear_remove: vget", error);
 				vn_finished_write(mp, 0);
 				return;
@@ -5549,7 +5552,7 @@ clear_inodedeps(p)
 		if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
 			continue;
 		FREE_LOCK(&lk);
-		if ((error = VFS_VGET(mp, ino, &vp)) != 0) {
+		if ((error = VFS_VGET(mp, ino, &vp, LK_EXCLUSIVE)) != 0) {
 			softdep_error("clear_inodedeps: vget", error);
 			vn_finished_write(mp, 0);
 			return;
Index: ufs/ffs/ffs_extern.h
===================================================================
--- ufs/ffs/ffs_extern.h	(revision 720)
+++ ufs/ffs/ffs_extern.h	(working copy)
@@ -131,8 +131,8 @@ int ffs_unmount __P((struct mount *, int
 int ffs_flushfiles __P((struct mount *, int, struct proc *));
 int ffs_statvfs __P((struct mount *, struct statvfs *, struct proc *));
 int ffs_sync __P((struct mount *, int, struct ucred *, struct proc *));
-int ffs_vget __P((struct mount *, ino_t, struct vnode **));
-int ffs_fhtovp __P((struct mount *, struct fid *, struct vnode **));
+int ffs_vget __P((struct mount *, ino_t, struct vnode **, int));
+int ffs_fhtovp __P((struct mount *, struct fid *, struct vnode **, int));
 int ffs_vptofh __P((struct vnode *, struct fid *));
 int ffs_sbupdate __P((struct ufsmount *, int));
 int ffs_cgupdate __P((struct ufsmount *, int));
Index: ufs/ffs/ffs_vfsops.c
===================================================================
--- ufs/ffs/ffs_vfsops.c	(revision 720)
+++ ufs/ffs/ffs_vfsops.c	(working copy)
@@ -1344,10 +1344,11 @@ loop:
  * done by the calling routine.
  */
 int
-ffs_vget(mp, ino, vpp)
+ffs_vget(mp, ino, vpp, lkflag)
 	struct mount *mp;
 	ino_t ino;
 	struct vnode **vpp;
+	int lkflag;
 {
 	struct fs *fs;
 	struct inode *ip;
@@ -1360,7 +1361,8 @@ ffs_vget(mp, ino, vpp)
 	ump = VFSTOUFS(mp);
 	dev = ump->um_dev;
 
-	if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL)
+retry:
+	if ((*vpp = ufs_ihashget(dev, ino, lkflag)) != NULL)
 		return (0);
 
 	/* Allocate a new vnode/inode. */
@@ -1375,7 +1377,7 @@ ffs_vget(mp, ino, vpp)
 	 */
 
 	do {
-		if ((*vpp = ufs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) {
+		if ((*vpp = ufs_ihashget(dev, ino, lkflag)) != NULL) {
 			ungetnewvnode(vp);
 			return (0);
 		}
@@ -1467,6 +1469,13 @@ ffs_vget(mp, ino, vpp)
 		ip->i_gid = ip->i_ffs1_ogid;			/* XXX */
 	}							/* XXX */
 	uvm_vnp_setsize(vp, ip->i_size);
+	if (lkflag != LK_EXCLUSIVE) {
+		VOP_UNLOCK(vp, 0);
+		if (lkflag && vn_lock(vp, lkflag)) {
+			vrele(vp);
+			goto retry;
+		}
+	}
 	*vpp = vp;
 	return (0);
 }
@@ -1482,10 +1491,11 @@ ffs_vget(mp, ino, vpp)
  *   those rights via. exflagsp and credanonp
  */
 int
-ffs_fhtovp(mp, fhp, vpp)
+ffs_fhtovp(mp, fhp, vpp, lkflag)
 	struct mount *mp;
 	struct fid *fhp;
 	struct vnode **vpp;
+	int lkflag;
 {
 	struct ufid *ufhp;
 	struct fs *fs;
@@ -1495,7 +1505,7 @@ ffs_fhtovp(mp, fhp, vpp)
 	if (ufhp->ufid_ino < ROOTINO ||
 	    ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
 		return (ESTALE);
-	return (ufs_fhtovp(mp, ufhp, vpp));
+	return (ufs_fhtovp(mp, ufhp, vpp, lkflag));
 }
 
 /*
Index: ufs/ffs/ffs_alloc.c
===================================================================
--- ufs/ffs/ffs_alloc.c	(revision 671)
+++ ufs/ffs/ffs_alloc.c	(working copy)
@@ -695,7 +695,7 @@ ffs_valloc(v)
 	ino = (ino_t)ffs_hashalloc(pip, cg, ipref, mode, ffs_nodealloccg);
 	if (ino == 0)
 		goto noinodes;
-	error = VFS_VGET(pvp->v_mount, ino, ap->a_vpp);
+	error = VFS_VGET(pvp->v_mount, ino, ap->a_vpp, LK_EXCLUSIVE);
 	if (error) {
 		VOP_VFREE(pvp, ino, mode);
 		return (error);
Index: nfs/nfsmount.h
===================================================================
--- nfs/nfsmount.h	(revision 720)
+++ nfs/nfsmount.h	(working copy)
@@ -190,8 +190,9 @@ int	nfs_quotactl __P((struct mount *mp, 
 int	nfs_statvfs __P((struct mount *mp, struct statvfs *sbp, struct proc *p));
 int	nfs_sync __P((struct mount *mp, int waitfor, struct ucred *cred,
 		struct proc *p));
-int	nfs_vget __P((struct mount *, ino_t, struct vnode **));
-int	nfs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
+int	nfs_vget __P((struct mount *, ino_t, struct vnode **, int));
+int	nfs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp,
+		int));
 int	nfs_checkexp __P((struct mount *mp, struct mbuf *nam, int *exflagsp,
 		struct ucred **credanonp));
 int	nfs_vptofh __P((struct vnode *vp, struct fid *fhp));
Index: nfs/nfs_vfsops.c
===================================================================
--- nfs/nfs_vfsops.c	(revision 720)
+++ nfs/nfs_vfsops.c	(working copy)
@@ -959,10 +959,11 @@ loop:
  */
 /* ARGSUSED */
 int
-nfs_vget(mp, ino, vpp)
+nfs_vget(mp, ino, vpp, lkflag)
 	struct mount *mp;
 	ino_t ino;
 	struct vnode **vpp;
+	int lkflag;
 {
 
 	return (EOPNOTSUPP);
@@ -1021,10 +1022,11 @@ SYSCTL_SETUP(sysctl_vfs_nfs_setup, "sysc
  */
 /* ARGSUSED */
 int
-nfs_fhtovp(mp, fhp, vpp)
+nfs_fhtovp(mp, fhp, vpp, lkflag)
 	struct mount *mp;
 	struct fid *fhp;
 	struct vnode **vpp;
+	int lkflag;
 {
 
 	return (EINVAL);
Index: nfs/nfs_nqlease.c
===================================================================
--- nfs/nfs_nqlease.c	(revision 720)
+++ nfs/nfs_nqlease.c	(working copy)
@@ -735,7 +735,7 @@ nqnfsrv_getlease(nfsd, slp, procp, mrq)
 	nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
 	flags = fxdr_unsigned(int, *tl++);
 	nfsd->nd_duration = fxdr_unsigned(int, *tl);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
+	error = nfsrv_fhtovp(fhp, LK_EXCLUSIVE, &vp, cred, slp, nam, &rdonly,
 		(nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(0);
Index: nfs/nfs_subs.c
===================================================================
--- nfs/nfs_subs.c	(revision 671)
+++ nfs/nfs_subs.c	(working copy)
@@ -1948,7 +1948,7 @@ nfs_namei(ndp, fhp, len, slp, nam, mdp, 
 	/*
 	 * Extract and set starting directory.
 	 */
-	error = nfsrv_fhtovp(fhp, FALSE, &dp, ndp->ni_cnd.cn_cred, slp,
+	error = nfsrv_fhtovp(fhp, 0, &dp, ndp->ni_cnd.cn_cred, slp,
 	    nam, &rdonly, kerbflag, pubflag);
 	if (error)
 		goto out;
@@ -2346,22 +2346,24 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, s
 	error = VFS_CHECKEXP(mp, nam, &exflags, &credanon);
 	if (error)
 		return (error);
-	error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
+	error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp, lockflag);
 	if (error)
 		return (error);
 
+	KASSERT(!lockflag || VOP_ISLOCKED(*vpp) == lockflag);
+
 	if (!(exflags & (MNT_EXNORESPORT|MNT_EXPUBLIC))) {
 		saddr = mtod(nam, struct sockaddr_in *);
 		if ((saddr->sin_family == AF_INET) &&
 		    ntohs(saddr->sin_port) >= IPPORT_RESERVED) {
-			vput(*vpp);
-			return (NFSERR_AUTHERR | AUTH_TOOWEAK);
+			error = NFSERR_AUTHERR | AUTH_TOOWEAK;
+			goto out;
 		}
 #ifdef INET6
 		if ((saddr->sin_family == AF_INET6) &&
 		    ntohs(saddr->sin_port) >= IPV6PORT_RESERVED) {
-			vput(*vpp);
-			return (NFSERR_AUTHERR | AUTH_TOOWEAK);
+			error = NFSERR_AUTHERR | AUTH_TOOWEAK;
+			goto out;
 		}
 #endif
 	}
@@ -2370,12 +2372,12 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, s
 	 */
 	if (exflags & MNT_EXKERB) {
 		if (!kerbflag) {
-			vput(*vpp);
-			return (NFSERR_AUTHERR | AUTH_TOOWEAK);
+			error = NFSERR_AUTHERR | AUTH_TOOWEAK;
+			goto out;
 		}
 	} else if (kerbflag) {
-		vput(*vpp);
-		return (NFSERR_AUTHERR | AUTH_TOOWEAK);
+		error = NFSERR_AUTHERR | AUTH_TOOWEAK;
+		goto out;
 	} else if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) {
 		cred->cr_uid = credanon->cr_uid;
 		cred->cr_gid = credanon->cr_gid;
@@ -2387,9 +2389,13 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, s
 		*rdonlyp = 1;
 	else
 		*rdonlyp = 0;
-	if (!lockflag)
-		VOP_UNLOCK(*vpp, 0);
-	return (0);
+out:
+	if (error) {
+		if (lockflag)
+			VOP_UNLOCK(*vpp, 0);
+		vrele(*vpp);
+	}
+	return error;
 }
 
 /*
Index: nfs/nfs_serv.c
===================================================================
--- nfs/nfs_serv.c	(revision 671)
+++ nfs/nfs_serv.c	(working copy)
@@ -122,7 +122,7 @@ nfsrv3_access(nfsd, slp, procp, mrq)
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam, &rdonly,
 	    (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
@@ -190,7 +190,7 @@ nfsrv_getattr(nfsd, slp, procp, mrq)
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam, &rdonly,
 	    (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(0);
@@ -286,7 +286,7 @@ nfsrv_setattr(nfsd, slp, procp, mrq)
 	/*
 	 * Now that we have all the fields, lets do it.
 	 */
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
+	error = nfsrv_fhtovp(fhp, LK_EXCLUSIVE, &vp, cred, slp, nam, &rdonly,
 	    (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
@@ -531,7 +531,7 @@ nfsrv_readlink(nfsd, slp, procp, mrq)
 	uiop->uio_rw = UIO_READ;
 	uiop->uio_segflg = UIO_SYSSPACE;
 	uiop->uio_procp = (struct proc *)0;
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		m_freem(mp3);
@@ -615,7 +615,7 @@ nfsrv_read(nfsd, slp, procp, mrq)
 	nfsm_dissect(tl, uint32_t *, NFSX_UNSIGNED);
 	reqlen = fxdr_unsigned(uint32_t, *tl);
 	reqlen = MIN(reqlen, NFS_SRVMAXDATA(nfsd));
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
@@ -892,7 +892,7 @@ nfsrv_write(nfsd, slp, procp, mrq)
 		vn_finished_write(mntp, 0);
 		return (0);
 	}
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_EXCLUSIVE, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
@@ -1162,7 +1162,7 @@ loop1:
 		cred = &nfsd->nd_cr;
 		v3 = (nfsd->nd_flag & ND_NFSV3);
 		forat_ret = aftat_ret = 1;
-		error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, cred, slp, 
+		error = nfsrv_fhtovp(&nfsd->nd_fh, LK_EXCLUSIVE, &vp, cred, slp,
 		    nfsd->nd_nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH),
 		    FALSE);
 		if (!error) {
@@ -2074,7 +2074,7 @@ nfsrv_link(nfsd, slp, procp, mrq)
 	vn_start_write(NULL, &mp, V_WAIT);
 	nfsm_srvmtofh(dfhp);
 	nfsm_srvnamesiz(len);
-	error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, 0, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
@@ -2603,7 +2603,7 @@ nfsrv_readdir(nfsd, slp, procp, mrq)
 	if (siz > xfer)
 		siz = xfer;
 	fullsiz = siz;
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (!error && vp->v_type != VDIR) {
 		error = ENOTDIR;
@@ -2862,7 +2862,7 @@ nfsrv_readdirplus(nfsd, slp, procp, mrq)
 	if (siz > xfer)
 		siz = xfer;
 	fullsiz = siz;
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (!error && vp->v_type != VDIR) {
 		error = ENOTDIR;
@@ -2923,7 +2923,8 @@ again:
 	 * even be here otherwise.
 	 */
 	if (!getret) {
-		if ((getret = VFS_VGET(vp->v_mount, at.va_fileid, &nvp)))
+		if ((getret = VFS_VGET(vp->v_mount, at.va_fileid, &nvp,
+		    LK_SHARED)))
 			getret = (getret == EOPNOTSUPP) ?
 				NFSERR_NOTSUPP : NFSERR_IO;
 		else
@@ -3007,7 +3008,8 @@ again:
 			 * For readdir_and_lookup get the vnode using
 			 * the file number.
 			 */
-			if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp))
+			if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp,
+			    LK_SHARED))
 				goto invalid;
 			memset((caddr_t)nfhp, 0, NFSX_V3FH);
 			nfhp->fh_fsid =
@@ -3164,7 +3166,7 @@ nfsrv_commit(nfsd, slp, procp, mrq)
 	off = fxdr_hyper(tl);
 	tl += 2;
 	cnt = fxdr_unsigned(uint32_t, *tl);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_EXCLUSIVE, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
@@ -3230,7 +3232,7 @@ nfsrv_statfs(nfsd, slp, procp, mrq)
 #endif
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
@@ -3304,7 +3306,7 @@ nfsrv_fsinfo(nfsd, slp, procp, mrq)
 #endif
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
@@ -3380,7 +3382,7 @@ nfsrv_pathconf(nfsd, slp, procp, mrq)
 #endif
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
+	error = nfsrv_fhtovp(fhp, LK_SHARED, &vp, cred, slp, nam,
 		 &rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);

--NextPart-20040525213040-0071800--