Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 May 2004 21:39:10 -0700 (PDT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 53379 for review
Message-ID:  <200405240439.i4O4dAOj092730@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=53379

Change 53379 by rwatson@rwatson_paprika on 2004/05/23 21:38:10

	Integrate netperf_socket from FreeBSD CVS HEAD:
	
	- Loop back the NFS server subsystem lock merged from
	  rwatson_netperf to CVS.

Affected files ...

.. //depot/projects/netperf_socket/sys/nfsserver/nfs.h#7 integrate
.. //depot/projects/netperf_socket/sys/nfsserver/nfs_serv.c#5 integrate
.. //depot/projects/netperf_socket/sys/nfsserver/nfs_srvcache.c#5 integrate
.. //depot/projects/netperf_socket/sys/nfsserver/nfs_srvsock.c#6 integrate
.. //depot/projects/netperf_socket/sys/nfsserver/nfs_srvsubs.c#5 integrate
.. //depot/projects/netperf_socket/sys/nfsserver/nfs_syscalls.c#6 integrate
.. //depot/projects/netperf_socket/sys/nfsserver/nfsm_subs.h#3 integrate

Differences ...

==== //depot/projects/netperf_socket/sys/nfsserver/nfs.h#7 (text+ko) ====

@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
- * $FreeBSD: src/sys/nfsserver/nfs.h,v 1.74 2004/04/11 13:33:34 peadar Exp $
+ * $FreeBSD: src/sys/nfsserver/nfs.h,v 1.75 2004/05/24 04:06:14 rwatson Exp $
  */
 
 #ifndef _NFSSERVER_NFS_H_
@@ -116,6 +116,13 @@
 
 #ifdef _KERNEL
 
+extern struct mtx nfsd_mtx;
+#define	NFSD_LOCK_ASSERT()	mtx_assert(&nfsd_mtx, MA_OWNED)
+#define	NFSD_UNLOCK_ASSERT()	mtx_assert(&nfsd_mtx, MA_NOTOWNED)
+#define	NFSD_LOCK_DONTCARE()
+#define	NFSD_LOCK()	mtx_lock(&nfsd_mtx)
+#define	NFSD_UNLOCK()	mtx_unlock(&nfsd_mtx)
+
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_NFSRVDESC);
 MALLOC_DECLARE(M_NFSD);
@@ -145,8 +152,8 @@
 	nfsrv_rpc_autherr;
 
 /* Procedure table data */
-extern int	nfsrvv2_procid[NFS_NPROCS];
-extern int	nfsrv_nfsv3_procid[NFS_NPROCS];
+extern const int	nfsrvv2_procid[NFS_NPROCS];
+extern const int	nfsrv_nfsv3_procid[NFS_NPROCS];
 extern int32_t (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *nd,
 		    struct nfssvc_sock *slp, struct thread *td,
 		    struct mbuf **mreqp);

==== //depot/projects/netperf_socket/sys/nfsserver/nfs_serv.c#5 (text+ko) ====

@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_serv.c,v 1.140 2004/04/12 13:02:21 mux Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_serv.c,v 1.141 2004/05/24 04:06:14 rwatson Exp $");
 
 /*
  * nfs version 2 and 3 server calls to vnode ops
@@ -179,6 +179,8 @@
 	u_long testmode, nfsmode;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	if (!v3)
 		panic("nfsrv3_access: v3 proc called on a v2 connection");
@@ -211,9 +213,13 @@
 	if ((nfsmode & testmode) &&
 		nfsrv_access(vp, VEXEC, cred, rdonly, td, 0))
 		nfsmode &= ~testmode;
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);
 	getret = VOP_GETATTR(vp, vap, cred, td);
 	vput(vp);
+	mtx_unlock(&Giant);
 	vp = NULL;
+	NFSD_LOCK();
 	nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED);
 	nfsm_srvpostop_attr(getret, vap);
 	tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
@@ -245,6 +251,8 @@
 	int error = 0, rdonly;
 	struct mbuf *mb, *mreq;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
@@ -254,9 +262,13 @@
 		error = 0;
 		goto nfsmout;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);
 	error = VOP_GETATTR(vp, vap, cred, td);
 	vput(vp);
+	mtx_unlock(&Giant);
 	vp = NULL;
+	NFSD_LOCK();
 	nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
 	if (error) {
 		error = 0;
@@ -299,6 +311,8 @@
 	struct timespec guard;
 	struct mount *mp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
@@ -306,7 +320,11 @@
 		error = ESTALE;
 		goto out;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
+	mtx_unlock(&Giant);
+	NFSD_LOCK();
 	VATTR_NULL(vap);
 	if (v3) {
 		nfsm_srvsattr(vap);
@@ -363,20 +381,26 @@
 	 * vp now an active resource, pay careful attention to cleanup
 	 */
 	if (v3) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		error = preat_ret = VOP_GETATTR(vp, &preat, cred, td);
 		if (!error && gcheck &&
 			(preat.va_ctime.tv_sec != guard.tv_sec ||
 			 preat.va_ctime.tv_nsec != guard.tv_nsec))
 			error = NFSERR_NOT_SYNC;
 		if (error) {
+			mtx_unlock(&Giant);	/* VFS */
 			vput(vp);
 			vp = NULL;
+			NFSD_LOCK();
 			nfsm_reply(NFSX_WCCDATA(v3));
 			if (v3)
 				nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
 			error = 0;
 			goto nfsmout;
 		}
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 	}
 
 	/*
@@ -396,13 +420,23 @@
 			td, 0)) != 0)
 			goto out;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	error = VOP_SETATTR(vp, vap, cred, td);
 	postat_ret = VOP_GETATTR(vp, vap, cred, td);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	if (!error)
 		error = postat_ret;
 out:
-	if (vp != NULL)
+	if (vp != NULL) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		vput(vp);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
+	}
+
 	vp = NULL;
 	nfsm_reply(NFSX_WCCORFATTR(v3));
 	if (v3) {
@@ -416,9 +450,13 @@
 	/* fall through */
 
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);
 	if (vp)
 		vput(vp);
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);
+	NFSD_LOCK();
 	return(error);
 }
 
@@ -444,6 +482,8 @@
 	struct mbuf *mb, *mreq;
 	struct vattr va, dirattr, *vap = &va;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
 
@@ -464,11 +504,15 @@
 	 * structure in case macros jump to nfsmout.
 	 */
 
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (error) {
 		if (dirp) {
 			vrele(dirp);
 			dirp = NULL;
 		}
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
 			nfsm_srvpostop_attr(dirattr_ret, &dirattr);
@@ -549,6 +593,8 @@
 	 */
 
 	if (error) {
+		mtx_unlock(&Giant);
+		NFSD_LOCK();
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
 			nfsm_srvpostop_attr(dirattr_ret, &dirattr);
@@ -577,7 +623,9 @@
 		error = VOP_GETATTR(vp, vap, cred, td);
 
 	vput(vp);
+	mtx_unlock(&Giant);	/* VFS */
 	ndp->ni_vp = NULL;
+	NFSD_LOCK();
 	nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
 	if (error) {
 		if (v3)
@@ -595,6 +643,8 @@
 	}
 
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (dirp)
 		vrele(dirp);
 	NDFREE(&nd, NDF_ONLY_PNBUF);
@@ -602,6 +652,8 @@
 		vrele(ndp->ni_startdir);
 	if (ndp->ni_vp)
 		vput(ndp->ni_vp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return (error);
 }
 
@@ -630,6 +682,8 @@
 	fhandle_t *fhp;
 	struct uio io, *uiop = &io;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 #ifndef nolint
 	mp = NULL;
@@ -639,6 +693,7 @@
 	nfsm_srvmtofh(fhp);
 	len = 0;
 	i = 0;
+	NFSD_UNLOCK();
 	while (len < NFS_MAXPATHLEN) {
 		MGET(nmp, M_TRYWAIT, MT_DATA);
 		MCLGET(nmp, M_TRYWAIT);
@@ -666,6 +721,7 @@
 	uiop->uio_rw = UIO_READ;
 	uiop->uio_segflg = UIO_SYSSPACE;
 	uiop->uio_td = NULL;
+	NFSD_LOCK();
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
@@ -674,18 +730,20 @@
 		error = 0;
 		goto nfsmout;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (vp->v_type != VLNK) {
 		if (v3)
 			error = EINVAL;
 		else
 			error = ENXIO;
-		goto out;
-	}
-	error = VOP_READLINK(vp, uiop, cred);
-out:
+	} else 
+		error = VOP_READLINK(vp, uiop, cred);
 	getret = VOP_GETATTR(vp, &attr, cred, td);
 	vput(vp);
+	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
+	NFSD_LOCK();
 	nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED);
 	if (v3)
 		nfsm_srvpostop_attr(getret, &attr);
@@ -705,8 +763,13 @@
 nfsmout:
 	if (mp3)
 		m_freem(mp3);
-	if (vp)
+	if (vp) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		vput(vp);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
+	}
 	return(error);
 }
 
@@ -741,6 +804,8 @@
 	off_t off;
 	int ioflag = 0;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
@@ -779,18 +844,24 @@
 		if ((error = nfsrv_access(vp, VREAD, cred, rdonly, td, 1)) != 0)
 			error = nfsrv_access(vp, VEXEC, cred, rdonly, td, 1);
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	getret = VOP_GETATTR(vp, vap, cred, td);
 	if (!error)
 		error = getret;
 	if (error) {
 		vput(vp);
+		mtx_unlock(&Giant);	/* VFS */
 		vp = NULL;
+		NFSD_LOCK();
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
 			nfsm_srvpostop_attr(getret, vap);
 		error = 0;
 		goto nfsmout;
 	}
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 
 	/*
 	 * Calculate byte count to read
@@ -870,6 +941,7 @@
 		tl += (NFSX_V2FATTR / sizeof (u_int32_t));
 	}
 	len = left = nfsm_rndup(cnt);
+	NFSD_UNLOCK();
 	if (cnt > 0) {
 		/*
 		 * Generate the mbuf list with the uio_iov ref. to it.
@@ -915,6 +987,7 @@
 		uiop->uio_resid = len;
 		uiop->uio_rw = UIO_READ;
 		uiop->uio_segflg = UIO_SYSSPACE;
+		mtx_lock(&Giant);	/* VFS */
 		error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred);
 		off = uiop->uio_offset;
 		nh->nh_nextr = off;
@@ -924,6 +997,8 @@
 				error = getret;
 			m_freem(mreq);
 			vput(vp);
+			mtx_unlock(&Giant);	/* VFS */
+			NFSD_LOCK();
 			vp = NULL;
 			nfsm_reply(NFSX_POSTOPATTR(v3));
 			if (v3)
@@ -933,9 +1008,13 @@
 		}
 	} else {
 		uiop->uio_resid = 0;
+		mtx_lock(&Giant);	/* VFS */
 	}
+	mtx_assert(&Giant, MA_OWNED);	/* VFS */
 	vput(vp);
+	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
+	NFSD_LOCK();
 	nfsm_srvfillattr(vap, fp);
 	tlen = len - uiop->uio_resid;
 	cnt = cnt < tlen ? cnt : tlen;
@@ -951,8 +1030,13 @@
 	}
 	*tl = txdr_unsigned(cnt);
 nfsmout:
-	if (vp)
+	if (vp) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		vput(vp);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
+	}
 	return(error);
 }
 
@@ -988,6 +1072,8 @@
 	off_t off;
 	struct mount *mntp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	if (mrep == NULL) {
 		*mrq = NULL;
@@ -1000,7 +1086,11 @@
 		error = ESTALE;
 		goto ereply;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	(void) vn_start_write(NULL, &mntp, V_WAIT);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	if (v3) {
 		tl = nfsm_dissect(u_int32_t *, 5 * NFSX_UNSIGNED);
 		off = fxdr_hyper(tl);
@@ -1063,8 +1153,13 @@
 		error = 0;
 		goto nfsmout;
 	}
-	if (v3)
+	if (v3) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		forat_ret = VOP_GETATTR(vp, &forat, cred, td);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
+	}
 	if (vp->v_type != VREG) {
 		if (v3)
 			error = EINVAL;
@@ -1074,7 +1169,11 @@
 	if (!error)
 		error = nfsrv_access(vp, VWRITE, cred, rdonly, td, 1);
 	if (error) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		vput(vp);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 		vp = NULL;
 		nfsm_reply(NFSX_WCCDATA(v3));
 		if (v3)
@@ -1083,6 +1182,7 @@
 		goto nfsmout;
 	}
 
+	NFSD_UNLOCK();
 	if (len > 0) {
 	    MALLOC(ivp, struct iovec *, cnt * sizeof (struct iovec), M_TEMP,
 		M_WAITOK);
@@ -1116,12 +1216,18 @@
 	    uiop->uio_segflg = UIO_SYSSPACE;
 	    uiop->uio_td = NULL;
 	    uiop->uio_offset = off;
+	    mtx_lock(&Giant);	/* VFS */
 	    error = VOP_WRITE(vp, uiop, ioflags, cred);
+	    /* XXXRW: unlocked write. */
 	    nfsrvstats.srvvop_writes++;
 	    FREE((caddr_t)iv, M_TEMP);
-	}
+	} else
+	    mtx_lock(&Giant);	/* VFS */
+	mtx_assert(&Giant, MA_OWNED);	/* VFS */
 	aftat_ret = VOP_GETATTR(vp, vap, cred, td);
 	vput(vp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	vp = NULL;
 	if (!error)
 		error = aftat_ret;
@@ -1159,9 +1265,13 @@
 	}
 	error = 0;
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (vp)
 		vput(vp);
 	vn_finished_write(mntp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return(error);
 }
 
@@ -1195,6 +1305,8 @@
 	u_quad_t cur_usec;
 	struct mount *mntp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 #ifndef nolint
 	i = 0;
@@ -1348,8 +1460,13 @@
 		error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, cred, slp,
 		    nfsd->nd_nam, &rdonly, TRUE);
 		if (!error) {
-		    if (v3)
+		    if (v3) {
+			NFSD_UNLOCK();
+			mtx_lock(&Giant);	/* VFS */
 			forat_ret = VOP_GETATTR(vp, &forat, cred, td);
+			mtx_unlock(&Giant);	/* VFS */
+			NFSD_LOCK();
+		    }
 		    if (vp->v_type != VREG) {
 			if (v3)
 			    error = EINVAL;
@@ -1361,6 +1478,7 @@
 		}
 		if (!error)
 		    error = nfsrv_access(vp, VWRITE, cred, rdonly, td, 1);
+		NFSD_UNLOCK();
 		if (nfsd->nd_stable == NFSV3WRITE_UNSTABLE)
 		    ioflags = IO_NODELOCKED;
 		else if (nfsd->nd_stable == NFSV3WRITE_DATASYNC)
@@ -1372,6 +1490,7 @@
 		uiop->uio_td = NULL;
 		uiop->uio_offset = nfsd->nd_off;
 		uiop->uio_resid = nfsd->nd_eoff - nfsd->nd_off;
+		mtx_lock(&Giant);	/* VFS */
 		if (uiop->uio_resid > 0) {
 		    mp = mrep;
 		    i = 0;
@@ -1402,6 +1521,7 @@
 		    }
 		    if (!error) {
 			error = VOP_WRITE(vp, uiop, ioflags, cred);
+			/* XXXRW: unlocked write. */
 			nfsrvstats.srvvop_writes++;
 			vn_finished_write(mntp);
 		    }
@@ -1413,6 +1533,8 @@
 		    vput(vp);
 		    vp = NULL;
 		}
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 
 		/*
 		 * Loop around generating replies for all write rpcs that have
@@ -1507,6 +1629,8 @@
         struct mbuf *mp;
 	struct nfsrv_descript *p;
 
+	NFSD_LOCK_ASSERT();
+
 	NFS_DPF(WG, ("C%03x-%03x",
 		     nfsd->nd_retxid & 0xfff, owp->nd_retxid & 0xfff));
         LIST_REMOVE(nfsd, nd_hash);
@@ -1573,6 +1697,8 @@
 	u_char cverf[NFSX_V3CREATEVERF];
 	struct mount *mp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 #ifndef nolint
 	rdev = 0;
@@ -1585,7 +1711,11 @@
 		error = ESTALE;
 		goto ereply;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	(void) vn_start_write(NULL, &mp, V_WAIT);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_srvnamesiz(len);
 
 	nd.ni_cnd.cn_cred = cred;
@@ -1604,7 +1734,11 @@
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
 	if (dirp && !v3) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		vrele(dirp);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 		dirp = NULL;
 	}
 	if (error) {
@@ -1679,6 +1813,8 @@
 	 * The only possible error we can have at this point is EEXIST.
 	 * nd.ni_vp will also be non-NULL in that case.
 	 */
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (nd.ni_vp == NULL) {
 		if (vap->va_mode == (mode_t)VNOVAL)
 			vap->va_mode = 0;
@@ -1797,6 +1933,8 @@
 		}
 	}
 ereply:
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
 		if (!error) {
@@ -1813,6 +1951,8 @@
 	error = 0;
 
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (nd.ni_startdir) {
 		vrele(nd.ni_startdir);
 		nd.ni_startdir = NULL;
@@ -1829,6 +1969,8 @@
 	if (nd.ni_vp)
 		vput(nd.ni_vp);
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return (error);
 }
 
@@ -1858,6 +2000,8 @@
 	struct mount *mp = NULL;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	if (!v3)
 		panic("nfsrv_mknod: v3 proc called on a v2 connection");
@@ -1869,7 +2013,11 @@
 		error = ESTALE;
 		goto ereply;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	(void) vn_start_write(NULL, &mp, V_WAIT);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_srvnamesiz(len);
 
 	nd.ni_cnd.cn_cred = cred;
@@ -1915,6 +2063,8 @@
 	vap->va_type = vtyp;
 	if (vap->va_mode == (mode_t)VNOVAL)
 		vap->va_mode = 0;
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (vtyp == VSOCK) {
 		vrele(nd.ni_startdir);
 		nd.ni_startdir = NULL;
@@ -1987,6 +2137,8 @@
 		VOP_UNLOCK(dirp, 0, td);
 	}
 ereply:
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
 	if (v3) {
 		if (!error) {
@@ -1995,9 +2147,15 @@
 		}
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return (0);
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (dirp)
 		vrele(dirp);
 	if (nd.ni_startdir)
@@ -2012,6 +2170,8 @@
 	if (nd.ni_vp)
 		vput(nd.ni_vp);
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return (error);
 }
 
@@ -2037,6 +2197,8 @@
 	fhandle_t *fhp;
 	struct mount *mp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
 
@@ -2046,7 +2208,11 @@
 		error = ESTALE;
 		goto ereply;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	(void) vn_start_write(NULL, &mp, V_WAIT);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_srvnamesiz(len);
 
 	nd.ni_cnd.cn_cred = cred;
@@ -2054,6 +2220,8 @@
 	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3,  &dirfor, &dirfor_ret, td, FALSE);
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (dirp && !v3) {
 		vrele(dirp);
 		dirp = NULL;
@@ -2099,6 +2267,8 @@
 		vrele(dirp);
 		dirp = NULL;
 	}
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 ereply:
 	nfsm_reply(NFSX_WCCDATA(v3));
 	if (v3) {
@@ -2106,6 +2276,8 @@
 		error = 0;
 	}
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (nd.ni_dvp) {
 		if (nd.ni_dvp == nd.ni_vp)
@@ -2116,6 +2288,8 @@
 	if (nd.ni_vp)
 		vput(nd.ni_vp);
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return(error);
 }
 
@@ -2144,6 +2318,8 @@
 	uid_t saved_uid;
 	struct mount *mp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 #ifndef nolint
 	fvp = NULL;
@@ -2176,7 +2352,11 @@
 	error = nfs_namei(&fromnd, ffhp, len, slp, nam, &md,
 		&dpos, &fdirp, v3, &fdirfor, &fdirfor_ret, td, FALSE);
 	if (fdirp && !v3) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		vrele(fdirp);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 		fdirp = NULL;
 	}
 	if (error) {
@@ -2197,6 +2377,8 @@
 	tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
 	error = nfs_namei(&tond, tfhp, len2, slp, nam, &md,
 		&dpos, &tdirp, v3, &tdirfor, &tdirfor_ret, td, FALSE);
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (tdirp && !v3) {
 		vrele(tdirp);
 		tdirp = NULL;
@@ -2282,9 +2464,13 @@
 	/* fall through */
 
 out1:
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_reply(2 * NFSX_WCCDATA(v3));
 	if (v3) {
 		/* Release existing locks to prevent deadlock. */
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		if (tond.ni_dvp) {
 			if (tond.ni_dvp == tond.ni_vp)
 				vrele(tond.ni_dvp);
@@ -2306,6 +2492,8 @@
 			tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred, td);
 			VOP_UNLOCK(tdirp, 0, td);
 		}
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 		nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
 		nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
 	}
@@ -2316,6 +2504,8 @@
 	/*
 	 * Clear out tond related fields
 	 */
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (tdirp)
 		vrele(tdirp);
 	if (tond.ni_startdir)
@@ -2344,6 +2534,8 @@
 		vrele(fromnd.ni_vp);
 
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return (error);
 }
 
@@ -2369,6 +2561,8 @@
 	fhandle_t *fhp, *dfhp;
 	struct mount *mp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
 
@@ -2379,7 +2573,11 @@
 		error = ESTALE;
 		goto ereply;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	(void) vn_start_write(NULL, &mp, V_WAIT);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_srvmtofh(dfhp);
 	nfsm_srvnamesiz(len);
 
@@ -2394,6 +2592,8 @@
 		error = 0;
 		goto nfsmout;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (v3)
 		getret = VOP_GETATTR(vp, &at, cred, td);
 	if (vp->v_type == VDIR) {
@@ -2404,8 +2604,12 @@
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
 	nd.ni_cnd.cn_flags = LOCKPARENT;
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	error = nfs_namei(&nd, dfhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (dirp && !v3) {
 		vrele(dirp);
 		dirp = NULL;
@@ -2459,6 +2663,8 @@
 			VOP_UNLOCK(dirp, 0, td);
 		}
 	}
+	mtx_lock(&Giant);	/* VFS */
+	NFSD_LOCK();
 ereply:
 	nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
@@ -2469,6 +2675,8 @@
 	/* fall through */
 
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (dirp)
 		vrele(dirp);
@@ -2483,6 +2691,8 @@
 	if (nd.ni_vp)
 		vrele(nd.ni_vp);
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return(error);
 }
 
@@ -2512,6 +2722,8 @@
 	fhandle_t *fhp;
 	struct mount *mp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
 
@@ -2521,13 +2733,19 @@
 		error = ESTALE;
 		goto out;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	(void) vn_start_write(NULL, &mp, V_WAIT);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
 	nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART;
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	if (dirp && !v3) {
 		vrele(dirp);
 		dirp = NULL;
@@ -2626,6 +2844,8 @@
 		vrele(nd.ni_startdir);
 		nd.ni_startdir = NULL;
 	}
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
 		if (!error) {
@@ -2638,6 +2858,8 @@
 	/* fall through */
 
 nfsmout:
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (nd.ni_dvp) {
 		if (nd.ni_dvp == nd.ni_vp)
@@ -2655,6 +2877,8 @@
 		FREE(pathcp, M_TEMP);
 
 	vn_finished_write(mp);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	return (error);
 }
 
@@ -2684,6 +2908,8 @@
 	fhandle_t *fhp;
 	struct mount *mp = NULL;
 
+	NFSD_LOCK_ASSERT();
+
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
 
@@ -2693,7 +2919,11 @@
 		error = ESTALE;
 		goto out;
 	}
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	(void) vn_start_write(NULL, &mp, V_WAIT);
+	mtx_unlock(&Giant);	/* VFS */
+	NFSD_LOCK();
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
@@ -2702,7 +2932,11 @@
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
 	if (dirp && !v3) {
+		NFSD_UNLOCK();
+		mtx_lock(&Giant);	/* VFS */
 		vrele(dirp);
+		mtx_unlock(&Giant);	/* VFS */
+		NFSD_LOCK();
 		dirp = NULL;
 	}
 	if (error) {
@@ -2725,6 +2959,8 @@
 	 * nd.ni_vp, if it exists, is referenced but not locked.
 	 */
 
+	NFSD_UNLOCK();
+	mtx_lock(&Giant);	/* VFS */
 	vap->va_type = VDIR;
 	if (nd.ni_vp != NULL) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200405240439.i4O4dAOj092730>