svn commit: r217063 - in head/sys/fs: nfs nfsserver

Rick Macklem rmacklem at FreeBSD.org
Thu Jan 6 19:50:11 UTC 2011


Author: rmacklem
Date: Thu Jan  6 19:50:11 2011
New Revision: 217063
URL: http://svn.freebsd.org/changeset/base/217063

Log:
  Since the VFS_LOCK_GIANT() code in the experimental NFS
  server is broken and the major file systems are now all
  mpsafe, modify the server so that it will only export
  mpsafe file systems. This was discussed on freebsd-fs@
  and removes a fair bit of crufty code.
  
  MFC after:	12 days

Modified:
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfs/nfsdport.h
  head/sys/fs/nfsserver/nfs_nfsdport.c
  head/sys/fs/nfsserver/nfs_nfsdserv.c
  head/sys/fs/nfsserver/nfs_nfsdsocket.c

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Thu Jan  6 19:32:00 2011	(r217062)
+++ head/sys/fs/nfs/nfs_var.h	Thu Jan  6 19:50:11 2011	(r217063)
@@ -570,8 +570,6 @@ int nfsvno_pathconf(vnode_t, int, regist
     NFSPROC_T *);
 vnode_t nfsvno_getvp(fhandle_t *);
 int nfsvno_advlock(vnode_t, int, u_int64_t, u_int64_t, NFSPROC_T *);
-void nfsvno_unlockvfs(mount_t);
-int nfsvno_lockvfs(mount_t);
 int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *);
 int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *);
 uint32_t nfsrv_hashfh(fhandle_t *);

Modified: head/sys/fs/nfs/nfsdport.h
==============================================================================
--- head/sys/fs/nfs/nfsdport.h	Thu Jan  6 19:32:00 2011	(r217062)
+++ head/sys/fs/nfs/nfsdport.h	Thu Jan  6 19:50:11 2011	(r217063)
@@ -52,7 +52,6 @@
  * needs to be returned by nfsd_fhtovp().
  */
 struct nfsexstuff {
-	int	nes_vfslocked;			/* required for all ports */
 	int	nes_exflag;			/* export flags */
 	int	nes_numsecflavor;		/* # of security flavors */
 	int	nes_secflavors[MAXSECFLAVORS];	/* and the flavors */

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c	Thu Jan  6 19:32:00 2011	(r217062)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c	Thu Jan  6 19:50:11 2011	(r217063)
@@ -332,18 +332,7 @@ nfsvno_namei(struct nfsrv_descript *nd, 
 		 * In either case ni_startdir will be dereferenced and NULLed
 		 * out.
 		 */
-		if (exp->nes_vfslocked)
-			ndp->ni_cnd.cn_flags |= GIANTHELD;
 		error = lookup(ndp);
-		/*
-		 * The Giant lock should only change when
-		 * crossing mount points.
-		 */
-		if (crossmnt) {
-			exp->nes_vfslocked =
-			    (ndp->ni_cnd.cn_flags & GIANTHELD) != 0;
-			ndp->ni_cnd.cn_flags &= ~GIANTHELD;
-		}
 		if (error)
 			break;
 
@@ -2471,7 +2460,10 @@ nfsvno_fhtovp(struct mount *mp, fhandle_
 
 	*credp = NULL;
 	exp->nes_numsecflavor = 0;
-	error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
+	if (VFS_NEEDSGIANT(mp))
+		error = ESTALE;
+	else
+		error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
 	if (error != 0)
 		/* Make sure the server replies ESTALE to the client. */
 		error = ESTALE;
@@ -2521,19 +2513,8 @@ nfsvno_pathconf(struct vnode *vp, int fl
  *	- get vp and export rights by calling nfsvno_fhtovp()
  *	- if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon
  *	  for AUTH_SYS
- * Also handle getting the Giant lock for the file system,
- * as required:
- * - if same mount point as *mpp
- *       do nothing
- *   else if *mpp == NULL
- *       if already locked
- *           leave it locked
- *       else
- *           call VFS_LOCK_GIANT()
- *   else
- *       if already locked
- *            unlock Giant
- *       call VFS_LOCK_GIANT()
+ *	- if mpp != NULL, return the mount point so that it can
+ *	  be used for vn_finished_write() by the caller
  */
 void
 nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
@@ -2549,27 +2530,14 @@ nfsd_fhtovp(struct nfsrv_descript *nd, s
 	 * Check for the special case of the nfsv4root_fh.
 	 */
 	mp = vfs_busyfs(&fhp->fh_fsid);
+	if (mpp != NULL)
+		*mpp = mp;
 	if (mp == NULL) {
 		*vpp = NULL;
 		nd->nd_repstat = ESTALE;
-		if (*mpp && exp->nes_vfslocked)
-			VFS_UNLOCK_GIANT(*mpp);
-		*mpp = NULL;
-		exp->nes_vfslocked = 0;
 		return;
 	}
 
-	/*
-	 * Now, handle Giant for the file system.
-	 */
-	if (*mpp != NULL && *mpp != mp && exp->nes_vfslocked) {
-		VFS_UNLOCK_GIANT(*mpp);
-		exp->nes_vfslocked = 0;
-	}
-	if (!exp->nes_vfslocked && *mpp != mp)
-		exp->nes_vfslocked = VFS_LOCK_GIANT(mp);
-
-	*mpp = mp;
 	if (startwrite)
 		vn_start_write(NULL, mpp, V_WAIT);
 
@@ -2633,12 +2601,9 @@ nfsd_fhtovp(struct nfsrv_descript *nd, s
 	if (nd->nd_repstat) {
 		if (startwrite)
 			vn_finished_write(mp);
-		if (exp->nes_vfslocked) {
-			VFS_UNLOCK_GIANT(mp);
-			exp->nes_vfslocked = 0;
-		}
 		*vpp = NULL;
-		*mpp = NULL;
+		if (mpp != NULL)
+			*mpp = NULL;
 	}
 }
 
@@ -2840,29 +2805,6 @@ nfsvno_advlock(struct vnode *vp, int fty
 }
 
 /*
- * Unlock an underlying local file system.
- */
-void
-nfsvno_unlockvfs(struct mount *mp)
-{
-
-	VFS_UNLOCK_GIANT(mp);
-}
-
-/*
- * Lock an underlying file system, as required, and return
- * whether or not it is locked.
- */
-int
-nfsvno_lockvfs(struct mount *mp)
-{
-	int ret;
-
-	ret = VFS_LOCK_GIANT(mp);
-	return (ret);
-}
-
-/*
  * Check the nfsv4 root exports.
  */
 int

Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c	Thu Jan  6 19:32:00 2011	(r217062)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c	Thu Jan  6 19:50:11 2011	(r217063)
@@ -1351,7 +1351,6 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 	struct nfsvattr fdirfor, fdiraft, tdirfor, tdiraft;
 	struct nfsexstuff tnes;
 	struct nfsrvfh tfh;
-	mount_t mp = NULL;
 	char *bufp, *tbufp = NULL;
 	u_long *hashp;
 
@@ -1387,9 +1386,7 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 			return (error);
 		}
 		nd->nd_cred->cr_uid = nd->nd_saveduid;
-		/* Won't lock vfs if already locked, mp == NULL */
-		tnes.nes_vfslocked = exp->nes_vfslocked;
-		nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, &mp, 0, p);
+		nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, 0, p);
 		if (tdp) {
 			tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
 			    p, 1);
@@ -1401,12 +1398,8 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 	if (!nd->nd_repstat) {
 		error = nfsrv_parsename(nd, tbufp, hashp, &tond.ni_pathlen);
 		if (error) {
-			if (tdp) {
-				if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
-				    !(nd->nd_flag & ND_NFSV4))
-					nfsvno_unlockvfs(mp);
+			if (tdp)
 				vrele(tdp);
-			}
 			vput(dp);
 			nfsvno_relpathbuf(&fromnd);
 			nfsvno_relpathbuf(&tond);
@@ -1420,12 +1413,8 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 			nfsrv_wcc(nd, tdirfor_ret, &tdirfor, tdiraft_ret,
 			    &tdiraft);
 		}
-		if (tdp) {
-			if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
-			    !(nd->nd_flag & ND_NFSV4))
-				nfsvno_unlockvfs(mp);
+		if (tdp)
 			vrele(tdp);
-		}
 		vput(dp);
 		nfsvno_relpathbuf(&fromnd);
 		nfsvno_relpathbuf(&tond);
@@ -1445,12 +1434,8 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 		}
 		if (fdirp)
 			vrele(fdirp);
-		if (tdp) {
-			if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
-			    !(nd->nd_flag & ND_NFSV4))
-				nfsvno_unlockvfs(mp);
+		if (tdp)
 			vrele(tdp);
-		}
 		nfsvno_relpathbuf(&tond);
 		return (0);
 	}
@@ -1465,9 +1450,6 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 	if (tdirp)
 		tdiraft_ret = nfsvno_getattr(tdirp, &tdiraft, nd->nd_cred, p,
 		    0);
-	if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
-	    !(nd->nd_flag & ND_NFSV4))
-		nfsvno_unlockvfs(mp);
 	if (fdirp)
 		vrele(fdirp);
 	if (tdirp)
@@ -1505,7 +1487,6 @@ nfsrvd_link(struct nfsrv_descript *nd, i
 	struct nfsvattr dirfor, diraft, at;
 	struct nfsexstuff tnes;
 	struct nfsrvfh dfh;
-	mount_t mp = NULL;
 	char *bufp;
 	u_long *hashp;
 
@@ -1541,9 +1522,7 @@ nfsrvd_link(struct nfsrv_descript *nd, i
 				/* tovp is always NULL unless NFSv4 */
 				return (error);
 			}
-			/* Won't lock vfs if already locked, mp == NULL */
-			tnes.nes_vfslocked = exp->nes_vfslocked;
-			nfsd_fhtovp(nd, &dfh, LK_EXCLUSIVE, &dp, &tnes, &mp, 0,
+			nfsd_fhtovp(nd, &dfh, LK_EXCLUSIVE, &dp, &tnes, NULL, 0,
 			    p);
 			if (dp)
 				NFSVOPUNLOCK(dp, 0, p);
@@ -1556,12 +1535,8 @@ nfsrvd_link(struct nfsrv_descript *nd, i
 		error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
 		if (error) {
 			vrele(vp);
-			if (dp) {
-				if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
-				    !(nd->nd_flag & ND_NFSV4))
-					nfsvno_unlockvfs(mp);
+			if (dp)
 				vrele(dp);
-			}
 			nfsvno_relpathbuf(&named);
 			return (error);
 		}
@@ -1591,9 +1566,6 @@ nfsrvd_link(struct nfsrv_descript *nd, i
 		diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
 		vrele(dirp);
 	}
-	if (tnes.nes_vfslocked && !exp->nes_vfslocked &&
-	    !(nd->nd_flag & ND_NFSV4))
-		nfsvno_unlockvfs(mp);
 	vrele(vp);
 	if (nd->nd_flag & ND_NFSV3) {
 		nfsrv_postopattr(nd, getret, &at);
@@ -3101,7 +3073,6 @@ nfsrvd_secinfo(struct nfsrv_descript *nd
 	vnode_t dirp = NULL, vp;
 	struct nfsrvfh fh;
 	struct nfsexstuff retnes;
-	mount_t mp;
 	u_int32_t *sizp;
 	int error, savflag, i;
 	char *bufp;
@@ -3134,12 +3105,10 @@ nfsrvd_secinfo(struct nfsrv_descript *nd
 	fh.nfsrvfh_len = NFSX_MYFH;
 	vp = named.ni_vp;
 	nd->nd_repstat = nfsvno_getfh(vp, (fhandle_t *)fh.nfsrvfh_data, p);
-	mp = vnode_mount(vp);	/* so it won't try to re-lock filesys */
-	retnes.nes_vfslocked = exp->nes_vfslocked;
 	vput(vp);
 	savflag = nd->nd_flag;
 	if (!nd->nd_repstat) {
-		nfsd_fhtovp(nd, &fh, LK_SHARED, &vp, &retnes, &mp, 0, p);
+		nfsd_fhtovp(nd, &fh, LK_SHARED, &vp, &retnes, NULL, 0, p);
 		if (vp)
 			vput(vp);
 	}

Modified: head/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdsocket.c	Thu Jan  6 19:32:00 2011	(r217062)
+++ head/sys/fs/nfsserver/nfs_nfsdsocket.c	Thu Jan  6 19:50:11 2011	(r217063)
@@ -386,7 +386,6 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, 
 				lktype = LK_SHARED;
 			else
 				lktype = LK_EXCLUSIVE;
-			nes.nes_vfslocked = 0;
 			if (nd->nd_flag & ND_PUBLOOKUP)
 				nfsd_fhtovp(nd, &nfs_pubfh, lktype, &vp, &nes,
 				    &mp, nfs_writerpc[nd->nd_procnum], p);
@@ -415,12 +414,8 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, 
 	if (nd->nd_repstat && (nd->nd_flag & ND_NFSV2)) {
 		*nd->nd_errp = nfsd_errmap(nd);
 		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
-		if (mp != NULL) {
-			if (nfs_writerpc[nd->nd_procnum])
-				NFS_ENDWRITE(mp);
-			if (nes.nes_vfslocked)
-				nfsvno_unlockvfs(mp);
-		}
+		if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
+			vn_finished_write(mp);
 		return;
 	}
 
@@ -445,12 +440,8 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, 
 			error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram,
 			    vp, p, &nes);
 		}
-		if (mp) {
-			if (nfs_writerpc[nd->nd_procnum])
-				NFS_ENDWRITE(mp);
-			if (nes.nes_vfslocked)
-				nfsvno_unlockvfs(mp);
-		}
+		if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
+			vn_finished_write(mp);
 		NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
 	}
 	if (error) {
@@ -498,9 +489,10 @@ nfsrvd_compound(struct nfsrv_descript *n
 	u_char tag[NFSV4_SMALLSTR + 1], *tagstr;
 	vnode_t vp, nvp, savevp;
 	struct nfsrvfh fh;
-	mount_t mp, savemp, temp_mp = NULL;
+	mount_t new_mp, temp_mp = NULL;
 	struct ucred *credanon;
 	struct nfsexstuff nes, vpnes, savevpnes;
+	fsid_t cur_fsid, save_fsid;
 	static u_int64_t compref = 0;
 
 	NFSVNO_EXINIT(&vpnes);
@@ -597,8 +589,8 @@ nfsrvd_compound(struct nfsrv_descript *n
 	}
 
 	savevp = vp = NULL;
-	savevpnes.nes_vfslocked = vpnes.nes_vfslocked = 0;
-	savemp = mp = NULL;
+	save_fsid.val[0] = save_fsid.val[1] = 0;
+	cur_fsid.val[0] = cur_fsid.val[1] = 0;
 	NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
 	taglen = fxdr_unsigned(int, *tl);
 	if (taglen < 0) {
@@ -704,46 +696,44 @@ nfsrvd_compound(struct nfsrv_descript *n
 			error = nfsrv_mtofh(nd, &fh);
 			if (error)
 				goto nfsmout;
-			if (!nd->nd_repstat) {
-				nes.nes_vfslocked = vpnes.nes_vfslocked;
-				nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes, &mp,
-				    0, p);
-			}
+			if (!nd->nd_repstat)
+				nfsd_fhtovp(nd, &fh, LK_SHARED, &nvp, &nes,
+				    NULL, 0, p);
 			/* For now, allow this for non-export FHs */
 			if (!nd->nd_repstat) {
 				if (vp)
 					vrele(vp);
 				vp = nvp;
-				NFSVOPUNLOCK(vp, 0, p);
+				cur_fsid = vp->v_mount->mnt_stat.f_fsid;
+				VOP_UNLOCK(vp, 0);
 				vpnes = nes;
 			}
 			break;
 		case NFSV4OP_PUTPUBFH:
-			if (nfs_pubfhset) {
-			    nes.nes_vfslocked = vpnes.nes_vfslocked;
+			if (nfs_pubfhset)
 			    nfsd_fhtovp(nd, &nfs_pubfh, LK_SHARED, &nvp,
-				&nes, &mp, 0, p);
-			} else {
+				&nes, NULL, 0, p);
+			else
 			    nd->nd_repstat = NFSERR_NOFILEHANDLE;
-			}
 			if (!nd->nd_repstat) {
 				if (vp)
 					vrele(vp);
 				vp = nvp;
-				NFSVOPUNLOCK(vp, 0, p);
+				cur_fsid = vp->v_mount->mnt_stat.f_fsid;
+				VOP_UNLOCK(vp, 0);
 				vpnes = nes;
 			}
 			break;
 		case NFSV4OP_PUTROOTFH:
 			if (nfs_rootfhset) {
-				nes.nes_vfslocked = vpnes.nes_vfslocked;
 				nfsd_fhtovp(nd, &nfs_rootfh, LK_SHARED, &nvp,
-				    &nes, &mp, 0, p);
+				    &nes, NULL, 0, p);
 				if (!nd->nd_repstat) {
 					if (vp)
 						vrele(vp);
 					vp = nvp;
-					NFSVOPUNLOCK(vp, 0, p);
+					cur_fsid = vp->v_mount->mnt_stat.f_fsid;
+					VOP_UNLOCK(vp, 0);
 					vpnes = nes;
 				}
 			} else
@@ -759,7 +749,7 @@ nfsrvd_compound(struct nfsrv_descript *n
 					VREF(vp);
 					savevp = vp;
 					savevpnes = vpnes;
-					savemp = mp;
+					save_fsid = cur_fsid;
 				}
 			} else {
 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
@@ -771,23 +761,10 @@ nfsrvd_compound(struct nfsrv_descript *n
 				/* If vp == savevp, a no-op */
 				if (vp != savevp) {
 					VREF(savevp);
-					if (mp == NULL || savemp == NULL)
-						panic("nfscmpmp");
-					if (!savevpnes.nes_vfslocked &&
-					    vpnes.nes_vfslocked) {
-						if (mp == savemp)
-							panic("nfscmp2");
-						nfsvno_unlockvfs(mp);
-					} else if (savevpnes.nes_vfslocked &&
-					    !vpnes.nes_vfslocked) {
-						if (mp == savemp)
-							panic("nfscmp3");
-						savevpnes.nes_vfslocked = nfsvno_lockvfs(savemp);
-					}
 					vrele(vp);
 					vp = savevp;
 					vpnes = savevpnes;
-					mp = savemp;
+					cur_fsid = save_fsid;
 				}
 			} else {
 				nd->nd_repstat = NFSERR_RESTOREFH;
@@ -841,11 +818,14 @@ nfsrvd_compound(struct nfsrv_descript *n
 			error = (*(nfsrv4_ops1[op]))(nd, isdgram, vp,
 			    &nvp, (fhandle_t *)fh.nfsrvfh_data, p, &vpnes);
 			if (!error && !nd->nd_repstat) {
-			    if (vfs_statfs(mp)->f_fsid.val[0] !=
-				vfs_statfs(vnode_mount(nvp))->f_fsid.val[0] ||
-				vfs_statfs(mp)->f_fsid.val[1] !=
-				vfs_statfs(vnode_mount(nvp))->f_fsid.val[1]) {
-				    nd->nd_repstat = nfsvno_checkexp(vnode_mount(nvp),
+			    if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP) {
+				new_mp = nvp->v_mount;
+				if (cur_fsid.val[0] !=
+				    new_mp->mnt_stat.f_fsid.val[0] ||
+				    cur_fsid.val[1] !=
+				    new_mp->mnt_stat.f_fsid.val[1]) {
+				    /* crossed a server mount point */
+				    nd->nd_repstat = nfsvno_checkexp(new_mp,
 					nd->nd_nam, &nes, &credanon);
 				    if (!nd->nd_repstat)
 					nd->nd_repstat = nfsd_excred(nd,
@@ -853,17 +833,13 @@ nfsrvd_compound(struct nfsrv_descript *n
 				    if (credanon != NULL)
 					crfree(credanon);
 				    if (!nd->nd_repstat) {
-					if (vpnes.nes_vfslocked)
-					    nfsvno_unlockvfs(mp);
-					mp = vnode_mount(nvp);
 					vpnes = nes;
-					vpnes.nes_vfslocked =
-					    nfsvno_lockvfs(mp);
+					cur_fsid = new_mp->mnt_stat.f_fsid;
 				    }
+				}
+				/* Lookup ops return a locked vnode */
+				VOP_UNLOCK(nvp, 0);
 			    }
-			    if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP)
-				    /* Lookup ops return a locked vnode */
-				    VOP_UNLOCK(nvp, 0);
 			    if (!nd->nd_repstat) {
 				    vrele(vp);
 				    vp = nvp;
@@ -876,7 +852,8 @@ nfsrvd_compound(struct nfsrv_descript *n
 			if (vp == NULL || savevp == NULL) {
 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
 				break;
-			} else if (mp != savemp) {
+			} else if (cur_fsid.val[0] != save_fsid.val[0] ||
+			    cur_fsid.val[1] != save_fsid.val[1]) {
 				nd->nd_repstat = NFSERR_XDEV;
 				break;
 			}
@@ -960,8 +937,6 @@ nfsmout:
 	} else {
 		*retopsp = txdr_unsigned(retops);
 	}
-	if (mp && vpnes.nes_vfslocked)
-		nfsvno_unlockvfs(mp);
 	if (vp)
 		vrele(vp);
 	if (savevp)


More information about the svn-src-all mailing list