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>