diff options
author | peter <peter@FreeBSD.org> | 1999-02-25 00:03:51 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1999-02-25 00:03:51 +0000 |
commit | 2cb5b6d7d54b14e1086055e6a5d05f9f96e0fc40 (patch) | |
tree | 825e5c3db3b7c2856f892529f74b6ee4c88e4044 /sys/nfsclient/nfs_nfsiod.c | |
parent | 3ad14cacdcabd4212b9384d2ea5ef5eb8a144543 (diff) | |
download | FreeBSD-src-2cb5b6d7d54b14e1086055e6a5d05f9f96e0fc40.zip FreeBSD-src-2cb5b6d7d54b14e1086055e6a5d05f9f96e0fc40.tar.gz |
Untangle the nfs send and receive queue locking a little. One lock
routine was [ab]used for two different things, and you couldn't tell from
the wait channel which one had wedged.
Catch a few things missing from NFS_NOSERVER.
Diffstat (limited to 'sys/nfsclient/nfs_nfsiod.c')
-rw-r--r-- | sys/nfsclient/nfs_nfsiod.c | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index c7c2a48..38b5af2 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 - * $Id: nfs_syscalls.c,v 1.46 1999/02/16 10:49:53 dfr Exp $ + * $Id: nfs_syscalls.c,v 1.47 1999/02/18 09:19:41 dfr Exp $ */ #include <sys/param.h> @@ -89,7 +89,9 @@ extern int nfsrvw_procrastinate_v3; struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock; static int nuidhash_max = NFS_MAXUIDHASH; +#ifndef NFS_NOSERVER static void nfsrv_zapsock __P((struct nfssvc_sock *slp)); +#endif static int nfssvc_iod __P((struct proc *)); #define TRUE 1 @@ -466,8 +468,6 @@ nfssvc_nfsd(nsd, argp, p) register struct mbuf *m; register int siz; register struct nfssvc_sock *slp; - register struct socket *so; - register int *solockp; struct nfsd *nfsd = nsd->nsd_nfsd; struct nfsrv_descript *nd = NULL; struct mbuf *mreq; @@ -527,13 +527,10 @@ nfssvc_nfsd(nsd, argp, p) nfsrv_zapsock(slp); else if (slp->ns_flag & SLP_NEEDQ) { slp->ns_flag &= ~SLP_NEEDQ; - (void) nfs_sndlock(&slp->ns_solock, - &slp->ns_solock, - (struct nfsreq *)0); + (void) nfs_slplock(slp, 1); nfsrv_rcv(slp->ns_so, (caddr_t)slp, M_WAIT); - nfs_sndunlock(&slp->ns_solock, - &slp->ns_solock); + nfs_slpunlock(slp); } error = nfsrv_dorec(slp, nfsd, &nd); cur_usec = nfs_curusec(); @@ -561,12 +558,7 @@ nfssvc_nfsd(nsd, argp, p) continue; } splx(s); - so = slp->ns_so; - sotype = so->so_type; - if (so->so_proto->pr_flags & PR_CONNREQUIRED) - solockp = &slp->ns_solock; - else - solockp = (int *)0; + sotype = slp->ns_so->so_type; if (nd) { getmicrotime(&nd->nd_starttime); if (nd->nd_nam2) @@ -692,11 +684,10 @@ nfssvc_nfsd(nsd, argp, p) M_PREPEND(m, NFSX_UNSIGNED, M_WAIT); *mtod(m, u_int32_t *) = htonl(0x80000000 | siz); } - if (solockp) - (void) nfs_sndlock(solockp, solockp, - (struct nfsreq *)0); + if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED) + (void) nfs_slplock(slp, 1); if (slp->ns_flag & SLP_VALID) - error = nfs_send(so, nd->nd_nam2, m, NULL); + error = nfs_send(slp->ns_so, nd->nd_nam2, m, NULL); else { error = EPIPE; m_freem(m); @@ -709,8 +700,8 @@ nfssvc_nfsd(nsd, argp, p) m_freem(nd->nd_mrep); if (error == EPIPE) nfsrv_zapsock(slp); - if (solockp) - nfs_sndunlock(solockp, solockp); + if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED) + nfs_slpunlock(slp); if (error == EINTR || error == ERESTART) { free((caddr_t)nd, M_NFSRVDESC); nfsrv_slpderef(slp); @@ -835,6 +826,44 @@ nfsrv_slpderef(slp) } /* + * Lock a socket against others. + */ +int +nfs_slplock(slp, wait) + register struct nfssvc_sock *slp; + int wait; +{ + int *statep = &slp->ns_solock; + + if (!wait && (*statep & NFSSTA_SNDLOCK)) + return(0); /* already locked, fail */ + while (*statep & NFSSTA_SNDLOCK) { + *statep |= NFSSTA_WANTSND; + (void) tsleep((caddr_t)statep, PZERO - 1, "nfsslplck", 0); + } + *statep |= NFSSTA_SNDLOCK; + return (1); +} + +/* + * Unlock the stream socket for others. + */ +void +nfs_slpunlock(slp) + register struct nfssvc_sock *slp; +{ + int *statep = &slp->ns_solock; + + if ((*statep & NFSSTA_SNDLOCK) == 0) + panic("nfs slpunlock"); + *statep &= ~NFSSTA_SNDLOCK; + if (*statep & NFSSTA_WANTSND) { + *statep &= ~NFSSTA_WANTSND; + wakeup((caddr_t)statep); + } +} + +/* * Initialize the data structures for the server. * Handshake with any new nfsds starting up to avoid any chance of * corruption. |