From e58631da3c81e111dd78b54402762f8f6875aa62 Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 31 May 1998 17:27:58 +0000 Subject: NFS Jumbo commit part 1. Cosmetic and structural changes only. The aim of this part of commits is to minimize unnecessary differences between the other NFS's of similar origin. Yes, there are gratuitous changes here that the style folks won't like, but it makes the catch-up less difficult. --- sys/nfsserver/nfs.h | 18 +- sys/nfsserver/nfs_serv.c | 126 ++++---- sys/nfsserver/nfs_srvsock.c | 704 +++++++++++++++++++++---------------------- sys/nfsserver/nfs_srvsubs.c | 45 ++- sys/nfsserver/nfs_syscalls.c | 326 ++++++++++---------- sys/nfsserver/nfsm_subs.h | 31 +- sys/nfsserver/nfsproto.h | 4 +- sys/nfsserver/nfsrvstats.h | 18 +- 8 files changed, 644 insertions(+), 628 deletions(-) (limited to 'sys/nfsserver') diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h index 20093f6..a2fac06 100644 --- a/sys/nfsserver/nfs.h +++ b/sys/nfsserver/nfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $ + * $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $ */ #ifndef _NFS_NFS_H_ @@ -293,14 +293,6 @@ struct nfsstats { { "nfsprivport", CTLTYPE_INT }, \ } -/* - * Network address hash list element - */ -union nethostaddr { - u_long had_inetaddr; - struct sockaddr *had_nam; -}; - #ifdef KERNEL #ifdef MALLOC_DECLARE @@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq; #define NFSNOHASH(fhsum) \ (&nfsnodehashtbl[(fhsum) & nfsnodehash]) +/* + * Network address hash list element + */ +union nethostaddr { + u_long had_inetaddr; + struct sockaddr *had_nam; +}; + struct nfsuid { TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 4b08bc6..de7084e 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -33,8 +33,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)nfs_serv.c 8.3 (Berkeley) 1/12/94 - * $Id: nfs_serv.c,v 1.61 1998/05/20 09:05:48 peter Exp $ + * @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95 + * $Id: nfs_serv.c,v 1.62 1998/05/30 16:33:56 peter Exp $ */ /* @@ -140,8 +140,9 @@ nfsrv3_access(nfsd, slp, procp, mrq) fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, + (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(NFSX_UNSIGNED); nfsm_srvpostop_attr(1, (struct vattr *)0); return (0); @@ -204,8 +205,9 @@ nfsrv_getattr(nfsd, slp, procp, mrq) fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(0); return (0); } @@ -296,8 +298,9 @@ nfsrv_setattr(nfsd, slp, procp, mrq) /* * Now that we have all the fields, lets do it. */ - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, + (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(2 * NFSX_UNSIGNED); nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap); return (0); @@ -330,8 +333,8 @@ nfsrv_setattr(nfsd, slp, procp, mrq) if (vp->v_type == VDIR) { error = EISDIR; goto out; - } else if (error = nfsrv_access(vp, VWRITE, cred, rdonly, - procp, 0)) + } else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly, + procp, 0)) != 0) goto out; } error = VOP_SETATTR(vp, vap, cred, procp); @@ -537,8 +540,9 @@ nfsrv_readlink(nfsd, slp, procp, mrq) uiop->uio_rw = UIO_READ; uiop->uio_segflg = UIO_SYSSPACE; uiop->uio_procp = (struct proc *)0; - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { m_freem(mp3); nfsm_reply(2 * NFSX_UNSIGNED); nfsm_srvpostop_attr(1, (struct vattr *)0); @@ -620,8 +624,9 @@ nfsrv_read(nfsd, slp, procp, mrq) off = (off_t)fxdr_unsigned(u_long, *tl); } nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd)); - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(2 * NFSX_UNSIGNED); nfsm_srvpostop_attr(1, (struct vattr *)0); return (0); @@ -634,7 +639,7 @@ nfsrv_read(nfsd, slp, procp, mrq) } if (!error) { nqsrv_getl(vp, ND_READ); - if (error = nfsrv_access(vp, VREAD, cred, rdonly, procp, 1)) + if ((error = nfsrv_access(vp, VREAD, cred, rdonly, procp, 1)) != 0) error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 1); } getret = VOP_GETATTR(vp, vap, cred, procp); @@ -834,8 +839,9 @@ nfsrv_write(nfsd, slp, procp, mrq) nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); return (0); } - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(2 * NFSX_UNSIGNED); nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); return (0); @@ -1304,47 +1310,6 @@ nfsrvw_coalesce(owp, nfsd) } /* - * Sort the group list in increasing numerical order. - * (Insertion sort by Chris Torek, who was grossed out by the bubble sort - * that used to be here.) - */ -void -nfsrvw_sort(list, num) - register gid_t *list; - register int num; -{ - register int i, j; - gid_t v; - - /* Insertion sort. */ - for (i = 1; i < num; i++) { - v = list[i]; - /* find correct slot for value v, moving others up */ - for (j = i; --j >= 0 && v < list[j];) - list[j + 1] = list[j]; - list[j + 1] = v; - } -} - -/* - * copy credentials making sure that the result can be compared with bcmp(). - */ -void -nfsrv_setcred(incred, outcred) - register struct ucred *incred, *outcred; -{ - register int i; - - bzero((caddr_t)outcred, sizeof (struct ucred)); - outcred->cr_ref = 1; - outcred->cr_uid = incred->cr_uid; - outcred->cr_ngroups = incred->cr_ngroups; - for (i = 0; i < incred->cr_ngroups; i++) - outcred->cr_groups[i] = incred->cr_groups[i]; - nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups); -} - -/* * nfs create service * now does a truncate to 0 length via. setattr if it already exists */ @@ -1445,6 +1410,8 @@ nfsrv_create(nfsd, slp, procp, mrq) case VFIFO: rdev = fxdr_unsigned(long, sp->sa_size); break; + default: + break; }; } @@ -1496,7 +1463,7 @@ nfsrv_create(nfsd, slp, procp, mrq) nd.ni_cnd.cn_flags &= ~(LOCKPARENT | SAVESTART); nd.ni_cnd.cn_proc = procp; nd.ni_cnd.cn_cred = cred; - if (error = lookup(&nd)) { + if ((error = lookup(&nd)) != 0) { zfree(namei_zone, nd.ni_cnd.cn_pnbuf); nfsm_reply(0); } @@ -1801,9 +1768,7 @@ out: if (!error) { nqsrv_getl(nd.ni_dvp, ND_WRITE); nqsrv_getl(vp, ND_WRITE); - error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); - } else { VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); } @@ -2065,8 +2030,9 @@ nfsrv_link(nfsd, slp, procp, mrq) nfsm_srvmtofh(fhp); nfsm_srvmtofh(dfhp); nfsm_srvnamesiz(len); - if (error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); nfsm_srvpostop_attr(getret, &at); nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); @@ -2577,8 +2543,9 @@ nfsrv_readdir(nfsd, slp, procp, mrq) if (siz > xfer) siz = xfer; fullsiz = siz; - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(NFSX_UNSIGNED); nfsm_srvpostop_attr(getret, &at); return (0); @@ -2832,8 +2799,9 @@ nfsrv_readdirplus(nfsd, slp, procp, mrq) if (siz > xfer) siz = xfer; fullsiz = siz; - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(NFSX_UNSIGNED); nfsm_srvpostop_attr(getret, &at); return (0); @@ -3128,8 +3096,9 @@ nfsrv_commit(nfsd, slp, procp, mrq) fxdr_hyper(tl, &off); tl += 2; cnt = fxdr_unsigned(int, *tl); - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(2 * NFSX_UNSIGNED); nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft); return (0); @@ -3188,8 +3157,9 @@ nfsrv_statfs(nfsd, slp, procp, mrq) #endif fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(NFSX_UNSIGNED); nfsm_srvpostop_attr(getret, &at); return (0); @@ -3340,8 +3310,9 @@ nfsrv_pathconf(nfsd, slp, procp, mrq) #endif fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); - if (error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, - &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE)) { + error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, + &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); + if (error) { nfsm_reply(NFSX_UNSIGNED); nfsm_srvpostop_attr(getret, &at); return (0); @@ -3462,8 +3433,12 @@ nfsrv_access(vp, flags, cred, rdonly, p, override) */ if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) { switch (vp->v_type) { - case VREG: case VDIR: case VLNK: + case VREG: + case VDIR: + case VLNK: return (EROFS); + default: + break; } } /* @@ -3473,7 +3448,8 @@ nfsrv_access(vp, flags, cred, rdonly, p, override) if (vp->v_flag & VTEXT) return (ETXTBSY); } - if (error = VOP_GETATTR(vp, &vattr, cred, p)) + error = VOP_GETATTR(vp, &vattr, cred, p); + if (error) return (error); error = VOP_ACCESS(vp, flags, cred, p); /* diff --git a/sys/nfsserver/nfs_srvsock.c b/sys/nfsserver/nfs_srvsock.c index 3fe0cec..ca9517f 100644 --- a/sys/nfsserver/nfs_srvsock.c +++ b/sys/nfsserver/nfs_srvsock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 - * $Id: nfs_socket.c,v 1.31 1998/03/30 09:54:04 phk Exp $ + * $Id: nfs_socket.c,v 1.32 1998/05/19 07:11:23 peter Exp $ */ /* @@ -249,7 +249,7 @@ nfs_connect(nmp, rep) "nfscon", 2 * hz); if ((so->so_state & SS_ISCONNECTING) && so->so_error == 0 && rep && - (error = nfs_sigintr(nmp, rep, rep->r_procp))) { + (error = nfs_sigintr(nmp, rep, rep->r_procp)) != 0){ so->so_state &= ~SS_ISCONNECTING; splx(s); goto bad; @@ -335,7 +335,7 @@ nfs_reconnect(rep) int error; nfs_disconnect(nmp); - while ((error = nfs_connect(nmp, rep))) { + while ((error = nfs_connect(nmp, rep)) != 0) { if (error == EINTR || error == ERESTART) return (EINTR); (void) tsleep((caddr_t)&lbolt, PSOCK, "nfscon", 0); @@ -419,8 +419,7 @@ nfs_send(so, nam, top, rep) flags, curproc /*XXX*/); if (error) { if (rep) { - log(LOG_INFO, "nfs send error %d for server %s\n", - error, + log(LOG_INFO, "nfs send error %d for server %s\n",error, rep->r_nmp->nm_mountp->mnt_stat.f_mntfromname); /* * Deal with errors for the client side. @@ -518,7 +517,7 @@ tryagain: error = nfs_send(so, rep->r_nmp->nm_nam, m, rep); if (error) { if (error == EINTR || error == ERESTART || - (error = nfs_reconnect(rep))) { + (error = nfs_reconnect(rep)) != 0) { nfs_sndunlock(&rep->r_nmp->nm_flag, &rep->r_nmp->nm_state); return (error); @@ -1641,290 +1640,6 @@ nfs_realign(m, hsiz) } #ifndef NFS_NOSERVER -/* - * Socket upcall routine for the nfsd sockets. - * The caddr_t arg is a pointer to the "struct nfssvc_sock". - * Essentially do as much as possible non-blocking, else punt and it will - * be called with M_WAIT from an nfsd. - */ -void -nfsrv_rcv(so, arg, waitflag) - struct socket *so; - caddr_t arg; - int waitflag; -{ - register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg; - register struct mbuf *m; - struct mbuf *mp; - struct sockaddr *nam; - struct uio auio; - int flags, error; - - if ((slp->ns_flag & SLP_VALID) == 0) - return; -#ifdef notdef - /* - * Define this to test for nfsds handling this under heavy load. - */ - if (waitflag == M_DONTWAIT) { - slp->ns_flag |= SLP_NEEDQ; goto dorecs; - } -#endif - auio.uio_procp = NULL; - if (so->so_type == SOCK_STREAM) { - /* - * If there are already records on the queue, defer soreceive() - * to an nfsd so that there is feedback to the TCP layer that - * the nfs servers are heavily loaded. - */ - if (STAILQ_FIRST(&slp->ns_rec) && waitflag == M_DONTWAIT) { - slp->ns_flag |= SLP_NEEDQ; - goto dorecs; - } - - /* - * Do soreceive(). - */ - auio.uio_resid = 1000000000; - flags = MSG_DONTWAIT; - error = so->so_proto->pr_usrreqs->pru_soreceive - (so, &nam, &auio, &mp, (struct mbuf **)0, &flags); - if (error || mp == (struct mbuf *)0) { - if (error == EWOULDBLOCK) - slp->ns_flag |= SLP_NEEDQ; - else - slp->ns_flag |= SLP_DISCONN; - goto dorecs; - } - m = mp; - if (slp->ns_rawend) { - slp->ns_rawend->m_next = m; - slp->ns_cc += 1000000000 - auio.uio_resid; - } else { - slp->ns_raw = m; - slp->ns_cc = 1000000000 - auio.uio_resid; - } - while (m->m_next) - m = m->m_next; - slp->ns_rawend = m; - - /* - * Now try and parse record(s) out of the raw stream data. - */ - error = nfsrv_getstream(slp, waitflag); - if (error) { - if (error == EPERM) - slp->ns_flag |= SLP_DISCONN; - else - slp->ns_flag |= SLP_NEEDQ; - } - } else { - do { - auio.uio_resid = 1000000000; - flags = MSG_DONTWAIT; - error = so->so_proto->pr_usrreqs->pru_soreceive - (so, &nam, &auio, &mp, - (struct mbuf **)0, &flags); - if (mp) { - struct nfsrv_rec *rec; - rec = malloc(sizeof(struct nfsrv_rec), - M_NFSRVDESC, waitflag); - if (!rec) { - if (nam) - FREE(nam, M_SONAME); - m_freem(mp); - continue; - } - nfs_realign(mp, 10 * NFSX_UNSIGNED); - rec->nr_address = nam; - rec->nr_packet = mp; - STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); - } - if (error) { - if ((so->so_proto->pr_flags & PR_CONNREQUIRED) - && error != EWOULDBLOCK) { - slp->ns_flag |= SLP_DISCONN; - goto dorecs; - } - } - } while (mp); - } - - /* - * Now try and process the request records, non-blocking. - */ -dorecs: - if (waitflag == M_DONTWAIT && - (STAILQ_FIRST(&slp->ns_rec) - || (slp->ns_flag & (SLP_NEEDQ | SLP_DISCONN)))) - nfsrv_wakenfsd(slp); -} - -/* - * Try and extract an RPC request from the mbuf data list received on a - * stream socket. The "waitflag" argument indicates whether or not it - * can sleep. - */ -static int -nfsrv_getstream(slp, waitflag) - register struct nfssvc_sock *slp; - int waitflag; -{ - register struct mbuf *m, **mpp; - register char *cp1, *cp2; - register int len; - struct mbuf *om, *m2, *recm = 0; - u_long recmark; - - if (slp->ns_flag & SLP_GETSTREAM) - panic("nfs getstream"); - slp->ns_flag |= SLP_GETSTREAM; - for (;;) { - if (slp->ns_reclen == 0) { - if (slp->ns_cc < NFSX_UNSIGNED) { - slp->ns_flag &= ~SLP_GETSTREAM; - return (0); - } - m = slp->ns_raw; - if (m->m_len >= NFSX_UNSIGNED) { - bcopy(mtod(m, caddr_t), (caddr_t)&recmark, NFSX_UNSIGNED); - m->m_data += NFSX_UNSIGNED; - m->m_len -= NFSX_UNSIGNED; - } else { - cp1 = (caddr_t)&recmark; - cp2 = mtod(m, caddr_t); - while (cp1 < ((caddr_t)&recmark) + NFSX_UNSIGNED) { - while (m->m_len == 0) { - m = m->m_next; - cp2 = mtod(m, caddr_t); - } - *cp1++ = *cp2++; - m->m_data++; - m->m_len--; - } - } - slp->ns_cc -= NFSX_UNSIGNED; - recmark = ntohl(recmark); - slp->ns_reclen = recmark & ~0x80000000; - if (recmark & 0x80000000) - slp->ns_flag |= SLP_LASTFRAG; - else - slp->ns_flag &= ~SLP_LASTFRAG; - if (slp->ns_reclen < NFS_MINPACKET || slp->ns_reclen > NFS_MAXPACKET) { - slp->ns_flag &= ~SLP_GETSTREAM; - return (EPERM); - } - } - - /* - * Now get the record part. - */ - if (slp->ns_cc == slp->ns_reclen) { - recm = slp->ns_raw; - slp->ns_raw = slp->ns_rawend = (struct mbuf *)0; - slp->ns_cc = slp->ns_reclen = 0; - } else if (slp->ns_cc > slp->ns_reclen) { - len = 0; - m = slp->ns_raw; - om = (struct mbuf *)0; - while (len < slp->ns_reclen) { - if ((len + m->m_len) > slp->ns_reclen) { - m2 = m_copym(m, 0, slp->ns_reclen - len, - waitflag); - if (m2) { - if (om) { - om->m_next = m2; - recm = slp->ns_raw; - } else - recm = m2; - m->m_data += slp->ns_reclen - len; - m->m_len -= slp->ns_reclen - len; - len = slp->ns_reclen; - } else { - slp->ns_flag &= ~SLP_GETSTREAM; - return (EWOULDBLOCK); - } - } else if ((len + m->m_len) == slp->ns_reclen) { - om = m; - len += m->m_len; - m = m->m_next; - recm = slp->ns_raw; - om->m_next = (struct mbuf *)0; - } else { - om = m; - len += m->m_len; - m = m->m_next; - } - } - slp->ns_raw = m; - slp->ns_cc -= len; - slp->ns_reclen = 0; - } else { - slp->ns_flag &= ~SLP_GETSTREAM; - return (0); - } - - /* - * Accumulate the fragments into a record. - */ - mpp = &slp->ns_frag; - while (*mpp) - mpp = &((*mpp)->m_next); - *mpp = recm; - if (slp->ns_flag & SLP_LASTFRAG) { - struct nfsrv_rec *rec; - rec = malloc(sizeof(struct nfsrv_rec), M_NFSRVDESC, waitflag); - if (!rec) { - m_freem(slp->ns_frag); - } else { - nfs_realign(slp->ns_frag, 10 * NFSX_UNSIGNED); - rec->nr_address = (struct sockaddr *)0; - rec->nr_packet = slp->ns_frag; - STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); - } - slp->ns_frag = (struct mbuf *)0; - } - } -} - -/* - * Parse an RPC header. - */ -int -nfsrv_dorec(slp, nfsd, ndp) - register struct nfssvc_sock *slp; - struct nfsd *nfsd; - struct nfsrv_descript **ndp; -{ - struct nfsrv_rec *rec; - register struct mbuf *m; - struct sockaddr *nam; - register struct nfsrv_descript *nd; - int error; - - *ndp = NULL; - if ((slp->ns_flag & SLP_VALID) == 0 || !STAILQ_FIRST(&slp->ns_rec)) - return (ENOBUFS); - rec = STAILQ_FIRST(&slp->ns_rec); - STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link); - nam = rec->nr_address; - m = rec->nr_packet; - free(rec, M_NFSRVDESC); - MALLOC(nd, struct nfsrv_descript *, sizeof (struct nfsrv_descript), - M_NFSRVDESC, M_WAITOK); - nd->nd_md = nd->nd_mrep = m; - nd->nd_nam2 = nam; - nd->nd_dpos = mtod(m, caddr_t); - error = nfs_getreq(nd, nfsd, TRUE); - if (error) { - FREE(nam, M_SONAME); - free((caddr_t)nd, M_NFSRVDESC); - return (error); - } - *ndp = nd; - nfsd->nfsd_nd = nd; - return (0); -} /* * Parse an RPC request @@ -2117,60 +1832,361 @@ nfs_getreq(nd, nfsd, has_header) &nuidp->nu_haddr, nd->nd_nam2))) break; } - if (!nuidp) { - nd->nd_repstat = - (NFSERR_AUTHERR|AUTH_REJECTCRED); - nd->nd_procnum = NFSPROC_NOOP; - return (0); + if (!nuidp) { + nd->nd_repstat = + (NFSERR_AUTHERR|AUTH_REJECTCRED); + nd->nd_procnum = NFSPROC_NOOP; + return (0); + } + + /* + * Now, decrypt the timestamp using the session key + * and validate it. + */ +#ifdef NFSKERB + XXX +#endif + + tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec); + tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec); + if (nuidp->nu_expire < time_second || + nuidp->nu_timestamp.tv_sec > tvout.tv_sec || + (nuidp->nu_timestamp.tv_sec == tvout.tv_sec && + nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) { + nuidp->nu_expire = 0; + nd->nd_repstat = + (NFSERR_AUTHERR|AUTH_REJECTVERF); + nd->nd_procnum = NFSPROC_NOOP; + return (0); + } + nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr); + nd->nd_flag |= ND_KERBNICK; + }; + } else { + nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED); + nd->nd_procnum = NFSPROC_NOOP; + return (0); + } + + /* + * For nqnfs, get piggybacked lease request. + */ + if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) { + nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); + nd->nd_flag |= fxdr_unsigned(int, *tl); + if (nd->nd_flag & ND_LEASE) { + nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); + nd->nd_duration = fxdr_unsigned(int, *tl); + } else + nd->nd_duration = NQ_MINLEASE; + } else + nd->nd_duration = NQ_MINLEASE; + nd->nd_md = md; + nd->nd_dpos = dpos; + return (0); +nfsmout: + return (error); +} + + +static int +nfs_msg(p, server, msg) + struct proc *p; + char *server, *msg; +{ + tpr_t tpr; + + if (p) + tpr = tprintf_open(p); + else + tpr = NULL; + tprintf(tpr, "nfs server %s: %s\n", server, msg); + tprintf_close(tpr); + return (0); +} +/* + * Socket upcall routine for the nfsd sockets. + * The caddr_t arg is a pointer to the "struct nfssvc_sock". + * Essentially do as much as possible non-blocking, else punt and it will + * be called with M_WAIT from an nfsd. + */ +void +nfsrv_rcv(so, arg, waitflag) + struct socket *so; + caddr_t arg; + int waitflag; +{ + register struct nfssvc_sock *slp = (struct nfssvc_sock *)arg; + register struct mbuf *m; + struct mbuf *mp; + struct sockaddr *nam; + struct uio auio; + int flags, error; + + if ((slp->ns_flag & SLP_VALID) == 0) + return; +#ifdef notdef + /* + * Define this to test for nfsds handling this under heavy load. + */ + if (waitflag == M_DONTWAIT) { + slp->ns_flag |= SLP_NEEDQ; goto dorecs; + } +#endif + auio.uio_procp = NULL; + if (so->so_type == SOCK_STREAM) { + /* + * If there are already records on the queue, defer soreceive() + * to an nfsd so that there is feedback to the TCP layer that + * the nfs servers are heavily loaded. + */ + if (STAILQ_FIRST(&slp->ns_rec) && waitflag == M_DONTWAIT) { + slp->ns_flag |= SLP_NEEDQ; + goto dorecs; + } + + /* + * Do soreceive(). + */ + auio.uio_resid = 1000000000; + flags = MSG_DONTWAIT; + error = so->so_proto->pr_usrreqs->pru_soreceive + (so, &nam, &auio, &mp, (struct mbuf **)0, &flags); + if (error || mp == (struct mbuf *)0) { + if (error == EWOULDBLOCK) + slp->ns_flag |= SLP_NEEDQ; + else + slp->ns_flag |= SLP_DISCONN; + goto dorecs; + } + m = mp; + if (slp->ns_rawend) { + slp->ns_rawend->m_next = m; + slp->ns_cc += 1000000000 - auio.uio_resid; + } else { + slp->ns_raw = m; + slp->ns_cc = 1000000000 - auio.uio_resid; + } + while (m->m_next) + m = m->m_next; + slp->ns_rawend = m; + + /* + * Now try and parse record(s) out of the raw stream data. + */ + error = nfsrv_getstream(slp, waitflag); + if (error) { + if (error == EPERM) + slp->ns_flag |= SLP_DISCONN; + else + slp->ns_flag |= SLP_NEEDQ; + } + } else { + do { + auio.uio_resid = 1000000000; + flags = MSG_DONTWAIT; + error = so->so_proto->pr_usrreqs->pru_soreceive + (so, &nam, &auio, &mp, + (struct mbuf **)0, &flags); + if (mp) { + struct nfsrv_rec *rec; + rec = malloc(sizeof(struct nfsrv_rec), + M_NFSRVDESC, waitflag); + if (!rec) { + if (nam) + FREE(nam, M_SONAME); + m_freem(mp); + continue; + } + nfs_realign(mp, 10 * NFSX_UNSIGNED); + rec->nr_address = nam; + rec->nr_packet = mp; + STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); + } + if (error) { + if ((so->so_proto->pr_flags & PR_CONNREQUIRED) + && error != EWOULDBLOCK) { + slp->ns_flag |= SLP_DISCONN; + goto dorecs; + } } + } while (mp); + } - /* - * Now, decrypt the timestamp using the session key - * and validate it. - */ -#ifdef NFSKERB - XXX -#endif + /* + * Now try and process the request records, non-blocking. + */ +dorecs: + if (waitflag == M_DONTWAIT && + (STAILQ_FIRST(&slp->ns_rec) + || (slp->ns_flag & (SLP_NEEDQ | SLP_DISCONN)))) + nfsrv_wakenfsd(slp); +} - tvout.tv_sec = fxdr_unsigned(long, tvout.tv_sec); - tvout.tv_usec = fxdr_unsigned(long, tvout.tv_usec); - if (nuidp->nu_expire < time_second || - nuidp->nu_timestamp.tv_sec > tvout.tv_sec || - (nuidp->nu_timestamp.tv_sec == tvout.tv_sec && - nuidp->nu_timestamp.tv_usec > tvout.tv_usec)) { - nuidp->nu_expire = 0; - nd->nd_repstat = - (NFSERR_AUTHERR|AUTH_REJECTVERF); - nd->nd_procnum = NFSPROC_NOOP; - return (0); +/* + * Try and extract an RPC request from the mbuf data list received on a + * stream socket. The "waitflag" argument indicates whether or not it + * can sleep. + */ +static int +nfsrv_getstream(slp, waitflag) + register struct nfssvc_sock *slp; + int waitflag; +{ + register struct mbuf *m, **mpp; + register char *cp1, *cp2; + register int len; + struct mbuf *om, *m2, *recm = 0; + u_long recmark; + + if (slp->ns_flag & SLP_GETSTREAM) + panic("nfs getstream"); + slp->ns_flag |= SLP_GETSTREAM; + for (;;) { + if (slp->ns_reclen == 0) { + if (slp->ns_cc < NFSX_UNSIGNED) { + slp->ns_flag &= ~SLP_GETSTREAM; + return (0); + } + m = slp->ns_raw; + if (m->m_len >= NFSX_UNSIGNED) { + bcopy(mtod(m, caddr_t), (caddr_t)&recmark, NFSX_UNSIGNED); + m->m_data += NFSX_UNSIGNED; + m->m_len -= NFSX_UNSIGNED; + } else { + cp1 = (caddr_t)&recmark; + cp2 = mtod(m, caddr_t); + while (cp1 < ((caddr_t)&recmark) + NFSX_UNSIGNED) { + while (m->m_len == 0) { + m = m->m_next; + cp2 = mtod(m, caddr_t); + } + *cp1++ = *cp2++; + m->m_data++; + m->m_len--; } - nfsrv_setcred(&nuidp->nu_cr, &nd->nd_cr); - nd->nd_flag |= ND_KERBNICK; - }; - } else { - nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED); - nd->nd_procnum = NFSPROC_NOOP; + } + slp->ns_cc -= NFSX_UNSIGNED; + recmark = ntohl(recmark); + slp->ns_reclen = recmark & ~0x80000000; + if (recmark & 0x80000000) + slp->ns_flag |= SLP_LASTFRAG; + else + slp->ns_flag &= ~SLP_LASTFRAG; + if (slp->ns_reclen < NFS_MINPACKET || slp->ns_reclen > NFS_MAXPACKET) { + slp->ns_flag &= ~SLP_GETSTREAM; + return (EPERM); + } + } + + /* + * Now get the record part. + */ + if (slp->ns_cc == slp->ns_reclen) { + recm = slp->ns_raw; + slp->ns_raw = slp->ns_rawend = (struct mbuf *)0; + slp->ns_cc = slp->ns_reclen = 0; + } else if (slp->ns_cc > slp->ns_reclen) { + len = 0; + m = slp->ns_raw; + om = (struct mbuf *)0; + while (len < slp->ns_reclen) { + if ((len + m->m_len) > slp->ns_reclen) { + m2 = m_copym(m, 0, slp->ns_reclen - len, + waitflag); + if (m2) { + if (om) { + om->m_next = m2; + recm = slp->ns_raw; + } else + recm = m2; + m->m_data += slp->ns_reclen - len; + m->m_len -= slp->ns_reclen - len; + len = slp->ns_reclen; + } else { + slp->ns_flag &= ~SLP_GETSTREAM; + return (EWOULDBLOCK); + } + } else if ((len + m->m_len) == slp->ns_reclen) { + om = m; + len += m->m_len; + m = m->m_next; + recm = slp->ns_raw; + om->m_next = (struct mbuf *)0; + } else { + om = m; + len += m->m_len; + m = m->m_next; + } + } + slp->ns_raw = m; + slp->ns_cc -= len; + slp->ns_reclen = 0; + } else { + slp->ns_flag &= ~SLP_GETSTREAM; return (0); + } + + /* + * Accumulate the fragments into a record. + */ + mpp = &slp->ns_frag; + while (*mpp) + mpp = &((*mpp)->m_next); + *mpp = recm; + if (slp->ns_flag & SLP_LASTFRAG) { + struct nfsrv_rec *rec; + rec = malloc(sizeof(struct nfsrv_rec), M_NFSRVDESC, waitflag); + if (!rec) { + m_freem(slp->ns_frag); + } else { + nfs_realign(slp->ns_frag, 10 * NFSX_UNSIGNED); + rec->nr_address = (struct sockaddr *)0; + rec->nr_packet = slp->ns_frag; + STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); + } + slp->ns_frag = (struct mbuf *)0; + } } +} - /* - * For nqnfs, get piggybacked lease request. - */ - if (nqnfs && nd->nd_procnum != NQNFSPROC_EVICTED) { - nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); - nd->nd_flag |= fxdr_unsigned(int, *tl); - if (nd->nd_flag & ND_LEASE) { - nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); - nd->nd_duration = fxdr_unsigned(int, *tl); - } else - nd->nd_duration = NQ_MINLEASE; - } else - nd->nd_duration = NQ_MINLEASE; - nd->nd_md = md; - nd->nd_dpos = dpos; +/* + * Parse an RPC header. + */ +int +nfsrv_dorec(slp, nfsd, ndp) + register struct nfssvc_sock *slp; + struct nfsd *nfsd; + struct nfsrv_descript **ndp; +{ + struct nfsrv_rec *rec; + register struct mbuf *m; + struct sockaddr *nam; + register struct nfsrv_descript *nd; + int error; + + *ndp = NULL; + if ((slp->ns_flag & SLP_VALID) == 0 || !STAILQ_FIRST(&slp->ns_rec)) + return (ENOBUFS); + rec = STAILQ_FIRST(&slp->ns_rec); + STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link); + nam = rec->nr_address; + m = rec->nr_packet; + free(rec, M_NFSRVDESC); + MALLOC(nd, struct nfsrv_descript *, sizeof (struct nfsrv_descript), + M_NFSRVDESC, M_WAITOK); + nd->nd_md = nd->nd_mrep = m; + nd->nd_nam2 = nam; + nd->nd_dpos = mtod(m, caddr_t); + error = nfs_getreq(nd, nfsd, TRUE); + if (error) { + FREE(nam, M_SONAME); + free((caddr_t)nd, M_NFSRVDESC); + return (error); + } + *ndp = nd; + nfsd->nfsd_nd = nd; return (0); -nfsmout: - return (error); } /* @@ -2201,19 +2217,3 @@ nfsrv_wakenfsd(slp) nfsd_head_flag |= NFSD_CHECKSLP; } #endif /* NFS_NOSERVER */ - -static int -nfs_msg(p, server, msg) - struct proc *p; - char *server, *msg; -{ - tpr_t tpr; - - if (p) - tpr = tprintf_open(p); - else - tpr = NULL; - tprintf(tpr, "nfs server %s: %s\n", server, msg); - tprintf_close(tpr); - return (0); -} diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c index 93fca3c..27cece4 100644 --- a/sys/nfsserver/nfs_srvsubs.c +++ b/sys/nfsserver/nfs_srvsubs.c @@ -33,8 +33,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_subs.c,v 1.54 1998/05/19 07:11:24 peter Exp $ + * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 + * $Id: nfs_subs.c,v 1.55 1998/05/24 14:41:53 peter Exp $ */ /* @@ -2129,4 +2129,45 @@ nfsrv_object_create(vp) return (vfs_object_create(vp, curproc, curproc ? curproc->p_ucred : NULL, 1)); } + +/* + * Sort the group list in increasing numerical order. + * (Insertion sort by Chris Torek, who was grossed out by the bubble sort + * that used to be here.) + */ +void +nfsrvw_sort(list, num) + register gid_t *list; + register int num; +{ + register int i, j; + gid_t v; + + /* Insertion sort. */ + for (i = 1; i < num; i++) { + v = list[i]; + /* find correct slot for value v, moving others up */ + for (j = i; --j >= 0 && v < list[j];) + list[j + 1] = list[j]; + list[j + 1] = v; + } +} + +/* + * copy credentials making sure that the result can be compared with bcmp(). + */ +void +nfsrv_setcred(incred, outcred) + register struct ucred *incred, *outcred; +{ + register int i; + + bzero((caddr_t)outcred, sizeof (struct ucred)); + outcred->cr_ref = 1; + outcred->cr_uid = incred->cr_uid; + outcred->cr_ngroups = incred->cr_ngroups; + for (i = 0; i < incred->cr_ngroups; i++) + outcred->cr_groups[i] = incred->cr_groups[i]; + nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups); +} #endif /* NFS_NOSERVER */ diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c index 317b1c0..94f33e2 100644 --- a/sys/nfsserver/nfs_syscalls.c +++ b/sys/nfsserver/nfs_syscalls.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 - * $Id: nfs_syscalls.c,v 1.37 1998/03/30 09:54:17 phk Exp $ + * $Id: nfs_syscalls.c,v 1.38 1998/05/19 07:11:25 peter Exp $ */ #include @@ -252,8 +252,9 @@ nfssvc(p, uap) error = copyin(uap->argp, (caddr_t)nsd, sizeof (*nsd)); if (error) return (error); - if ((uap->flag & NFSSVC_AUTHIN) && ((nfsd = nsd->nsd_nfsd)) && - (nfsd->nfsd_slp->ns_flag & SLP_VALID)) { + if ((uap->flag & NFSSVC_AUTHIN) && + ((nfsd = nsd->nsd_nfsd)) != NULL && + (nfsd->nfsd_slp->ns_flag & SLP_VALID)) { slp = nfsd->nfsd_slp; /* @@ -465,11 +466,10 @@ nfssvc_nfsd(nsd, argp, p) writes_todo = 0; #endif if (nfsd == (struct nfsd *)0) { - nfsd = (struct nfsd *) + nsd->nsd_nfsd = nfsd = (struct nfsd *) malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK); bzero((caddr_t)nfsd, sizeof (struct nfsd)); s = splnet(); - nsd->nsd_nfsd = nfsd; nfsd->nfsd_procp = p; TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain); nfs_numnfsd++; @@ -746,6 +746,161 @@ done: nfsrv_init(TRUE); /* Reinitialize everything */ return (error); } + +/* + * Shut down a socket associated with an nfssvc_sock structure. + * Should be called with the send lock set, if required. + * The trick here is to increment the sref at the start, so that the nfsds + * will stop using it and clear ns_flag at the end so that it will not be + * reassigned during cleanup. + */ +static void +nfsrv_zapsock(slp) + register struct nfssvc_sock *slp; +{ + register struct nfsuid *nuidp, *nnuidp; + register struct nfsrv_descript *nwp, *nnwp; + struct socket *so; + struct file *fp; + struct nfsrv_rec *rec; + int s; + + slp->ns_flag &= ~SLP_ALLFLAGS; + fp = slp->ns_fp; + if (fp) { + slp->ns_fp = (struct file *)0; + so = slp->ns_so; + so->so_upcall = NULL; + soshutdown(so, 2); + closef(fp, (struct proc *)0); + if (slp->ns_nam) + FREE(slp->ns_nam, M_SONAME); + m_freem(slp->ns_raw); + while (rec = STAILQ_FIRST(&slp->ns_rec)) { + STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link); + if (rec->nr_address) + FREE(rec->nr_address, M_SONAME); + m_freem(rec->nr_packet); + free(rec, M_NFSRVDESC); + } + for (nuidp = slp->ns_uidlruhead.tqh_first; nuidp != 0; + nuidp = nnuidp) { + nnuidp = nuidp->nu_lru.tqe_next; + LIST_REMOVE(nuidp, nu_hash); + TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, nu_lru); + if (nuidp->nu_flag & NU_NAM) + FREE(nuidp->nu_nam, M_SONAME); + free((caddr_t)nuidp, M_NFSUID); + } + s = splsoftclock(); + for (nwp = slp->ns_tq.lh_first; nwp; nwp = nnwp) { + nnwp = nwp->nd_tq.le_next; + LIST_REMOVE(nwp, nd_tq); + free((caddr_t)nwp, M_NFSRVDESC); + } + LIST_INIT(&slp->ns_tq); + splx(s); + } +} + +/* + * Derefence a server socket structure. If it has no more references and + * is no longer valid, you can throw it away. + */ +void +nfsrv_slpderef(slp) + register struct nfssvc_sock *slp; +{ + if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) { + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); + free((caddr_t)slp, M_NFSSVC); + } +} + +/* + * Initialize the data structures for the server. + * Handshake with any new nfsds starting up to avoid any chance of + * corruption. + */ +void +nfsrv_init(terminating) + int terminating; +{ + register struct nfssvc_sock *slp, *nslp; + + if (nfssvc_sockhead_flag & SLP_INIT) + panic("nfsd init"); + nfssvc_sockhead_flag |= SLP_INIT; + if (terminating) { + for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) { + nslp = slp->ns_chain.tqe_next; + if (slp->ns_flag & SLP_VALID) + nfsrv_zapsock(slp); + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); + free((caddr_t)slp, M_NFSSVC); + } + nfsrv_cleancache(); /* And clear out server cache */ + } else + nfs_pub.np_valid = 0; + + TAILQ_INIT(&nfssvc_sockhead); + nfssvc_sockhead_flag &= ~SLP_INIT; + if (nfssvc_sockhead_flag & SLP_WANTINIT) { + nfssvc_sockhead_flag &= ~SLP_WANTINIT; + wakeup((caddr_t)&nfssvc_sockhead); + } + + TAILQ_INIT(&nfsd_head); + nfsd_head_flag &= ~NFSD_CHECKSLP; + + nfs_udpsock = (struct nfssvc_sock *) + malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); + bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock)); + STAILQ_INIT(&nfs_udpsock->ns_rec); + TAILQ_INIT(&nfs_udpsock->ns_uidlruhead); + TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain); + + nfs_cltpsock = (struct nfssvc_sock *) + malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); + bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock)); + STAILQ_INIT(&nfs_cltpsock->ns_rec); + TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead); + TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain); +} + +/* + * Add entries to the server monitor log. + */ +static void +nfsd_rt(sotype, nd, cacherep) + int sotype; + register struct nfsrv_descript *nd; + int cacherep; +{ + register struct drt *rt; + + rt = &nfsdrt.drt[nfsdrt.pos]; + if (cacherep == RC_DOIT) + rt->flag = 0; + else if (cacherep == RC_REPLY) + rt->flag = DRT_CACHEREPLY; + else + rt->flag = DRT_CACHEDROP; + if (sotype == SOCK_STREAM) + rt->flag |= DRT_TCP; + if (nd->nd_flag & ND_NQNFS) + rt->flag |= DRT_NQNFS; + else if (nd->nd_flag & ND_NFSV3) + rt->flag |= DRT_NFSV3; + rt->proc = nd->nd_procnum; + if (nd->nd_nam->sa_family == AF_INET) + rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr; + else + rt->ipadr = INADDR_ANY; + rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec); + getmicrotime(&rt->tstamp); + nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ; +} #endif /* NFS_NOSERVER */ static int nfs_defect = 0; @@ -794,7 +949,8 @@ nfssvc_iod(p) } if (error) { nfs_asyncdaemon[myiod] = 0; - if (nmp) nmp->nm_bufqiods--; + if (nmp) + nmp->nm_bufqiods--; nfs_iodwant[myiod] = NULL; nfs_iodmount[myiod] = NULL; nfs_numasync--; @@ -812,7 +968,6 @@ nfssvc_iod(p) (void) nfs_doio(bp, bp->b_rcred, (struct proc *)0); else (void) nfs_doio(bp, bp->b_wcred, (struct proc *)0); - /* * If there are more than one iod on this mount, then defect * so that the iods can be shared out fairly between the mounts @@ -829,61 +984,6 @@ nfssvc_iod(p) } } -/* - * Shut down a socket associated with an nfssvc_sock structure. - * Should be called with the send lock set, if required. - * The trick here is to increment the sref at the start, so that the nfsds - * will stop using it and clear ns_flag at the end so that it will not be - * reassigned during cleanup. - */ -static void -nfsrv_zapsock(slp) - register struct nfssvc_sock *slp; -{ - register struct nfsuid *nuidp, *nnuidp; - register struct nfsrv_descript *nwp, *nnwp; - struct socket *so; - struct file *fp; - struct nfsrv_rec *rec; - int s; - - slp->ns_flag &= ~SLP_ALLFLAGS; - fp = slp->ns_fp; - if (fp) { - slp->ns_fp = (struct file *)0; - so = slp->ns_so; - so->so_upcall = NULL; - soshutdown(so, 2); - closef(fp, (struct proc *)0); - if (slp->ns_nam) - FREE(slp->ns_nam, M_SONAME); - m_freem(slp->ns_raw); - while (rec = STAILQ_FIRST(&slp->ns_rec)) { - STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link); - if (rec->nr_address) - FREE(rec->nr_address, M_SONAME); - m_freem(rec->nr_packet); - free(rec, M_NFSRVDESC); - } - for (nuidp = slp->ns_uidlruhead.tqh_first; nuidp != 0; - nuidp = nnuidp) { - nnuidp = nuidp->nu_lru.tqe_next; - LIST_REMOVE(nuidp, nu_hash); - TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, nu_lru); - if (nuidp->nu_flag & NU_NAM) - FREE(nuidp->nu_nam, M_SONAME); - free((caddr_t)nuidp, M_NFSUID); - } - s = splsoftclock(); - for (nwp = slp->ns_tq.lh_first; nwp; nwp = nnwp) { - nnwp = nwp->nd_tq.le_next; - LIST_REMOVE(nwp, nd_tq); - free((caddr_t)nwp, M_NFSRVDESC); - } - LIST_INIT(&slp->ns_tq); - splx(s); - } -} /* * Get an authorization string for the uid by having the mount_nfs sitting @@ -1088,105 +1188,3 @@ nfsmout: *dposp = dpos; return (error); } - -#ifndef NFS_NOSERVER - -/* - * Derefence a server socket structure. If it has no more references and - * is no longer valid, you can throw it away. - */ -void -nfsrv_slpderef(slp) - register struct nfssvc_sock *slp; -{ - if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) { - TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); - free((caddr_t)slp, M_NFSSVC); - } -} - -/* - * Initialize the data structures for the server. - * Handshake with any new nfsds starting up to avoid any chance of - * corruption. - */ -void -nfsrv_init(terminating) - int terminating; -{ - register struct nfssvc_sock *slp, *nslp; - - if (nfssvc_sockhead_flag & SLP_INIT) - panic("nfsd init"); - nfssvc_sockhead_flag |= SLP_INIT; - if (terminating) { - for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) { - nslp = slp->ns_chain.tqe_next; - if (slp->ns_flag & SLP_VALID) - nfsrv_zapsock(slp); - TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); - free((caddr_t)slp, M_NFSSVC); - } - nfsrv_cleancache(); /* And clear out server cache */ - } else - nfs_pub.np_valid = 0; - - TAILQ_INIT(&nfssvc_sockhead); - nfssvc_sockhead_flag &= ~SLP_INIT; - if (nfssvc_sockhead_flag & SLP_WANTINIT) { - nfssvc_sockhead_flag &= ~SLP_WANTINIT; - wakeup((caddr_t)&nfssvc_sockhead); - } - - TAILQ_INIT(&nfsd_head); - nfsd_head_flag &= ~NFSD_CHECKSLP; - - nfs_udpsock = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); - bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock)); - STAILQ_INIT(&nfs_udpsock->ns_rec); - TAILQ_INIT(&nfs_udpsock->ns_uidlruhead); - TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain); - - nfs_cltpsock = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); - bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock)); - STAILQ_INIT(&nfs_cltpsock->ns_rec); - TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead); - TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain); -} - -/* - * Add entries to the server monitor log. - */ -static void -nfsd_rt(sotype, nd, cacherep) - int sotype; - register struct nfsrv_descript *nd; - int cacherep; -{ - register struct drt *rt; - - rt = &nfsdrt.drt[nfsdrt.pos]; - if (cacherep == RC_DOIT) - rt->flag = 0; - else if (cacherep == RC_REPLY) - rt->flag = DRT_CACHEREPLY; - else - rt->flag = DRT_CACHEDROP; - if (sotype == SOCK_STREAM) - rt->flag |= DRT_TCP; - if (nd->nd_flag & ND_NQNFS) - rt->flag |= DRT_NQNFS; - else if (nd->nd_flag & ND_NFSV3) - rt->flag |= DRT_NFSV3; - rt->proc = nd->nd_procnum; - if (nd->nd_nam->sa_family == AF_INET) - rt->ipadr = ((struct sockaddr_in *)nd->nd_nam)->sin_addr.s_addr; - else - rt->ipadr = INADDR_ANY; - rt->resptime = nfs_curusec() - (nd->nd_starttime.tv_sec * 1000000 + nd->nd_starttime.tv_usec); - getmicrotime(&rt->tstamp); - nfsdrt.pos = (nfsdrt.pos + 1) % NFSRTTLOGSIZ; -} -#endif /* NFS_NOSERVER */ diff --git a/sys/nfsserver/nfsm_subs.h b/sys/nfsserver/nfsm_subs.h index 35c95e7..c8176c9 100644 --- a/sys/nfsserver/nfsm_subs.h +++ b/sys/nfsserver/nfsm_subs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95 - * $Id: nfsm_subs.h,v 1.15 1998/03/30 09:54:41 phk Exp $ + * $Id: nfsm_subs.h,v 1.16 1998/05/16 15:11:24 bde Exp $ */ @@ -105,7 +105,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, if (t1 >= (s)) { \ (a) = (c)(dpos); \ dpos += (s); \ - } else if (t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) { \ + } else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \ error = t1; \ m_freem(mrep); \ goto nfsmout; \ @@ -122,8 +122,9 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, *(tl + ((t2>>2) - 2)) = 0; \ bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \ VTONFS(v)->n_fhsize); \ - } else if (t2 = nfsm_strtmbuf(&mb, &bpos, \ - (caddr_t)VTONFS(v)->n_fhp, VTONFS(v)->n_fhsize)) { \ + } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \ + (caddr_t)VTONFS(v)->n_fhp, \ + VTONFS(v)->n_fhsize)) != 0) { \ error = t2; \ m_freem(mreq); \ goto nfsmout; \ @@ -159,8 +160,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, (f) = 1; \ if (f) { \ nfsm_getfh(ttfhp, ttfhsize, (v3)); \ - if (t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \ - &ttnp)) { \ + if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \ + &ttnp)) != 0) { \ error = t1; \ m_freem(mrep); \ goto nfsmout; \ @@ -193,7 +194,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, #define nfsm_loadattr(v, a) \ { struct vnode *ttvp = (v); \ - if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) { \ + if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a))) != 0) { \ error = t1; \ m_freem(mrep); \ goto nfsmout; \ @@ -204,8 +205,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, { struct vnode *ttvp = (v); \ nfsm_dissect(tl, u_long *, NFSX_UNSIGNED); \ if ((f) = fxdr_unsigned(int, *tl)) { \ - if (t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \ - (struct vattr *)0)) { \ + if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \ + (struct vattr *)0)) != 0) { \ error = t1; \ (f) = 0; \ m_freem(mrep); \ @@ -275,14 +276,14 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, #define nfsm_mtouio(p,s) \ if ((s) > 0 && \ - (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos))) { \ + (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \ error = t1; \ m_freem(mrep); \ goto nfsmout; \ } #define nfsm_uiotom(p,s) \ - if (t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) { \ + if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \ error = t1; \ m_freem(mreq); \ goto nfsmout; \ @@ -297,8 +298,8 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, #define nfsm_rndup(a) (((a)+3)&(~0x3)) #define nfsm_request(v, t, p, c) \ - if (error = nfs_request((v), mreq, (t), (p), \ - (c), &mrep, &md, &dpos)) { \ + if ((error = nfs_request((v), mreq, (t), (p), \ + (c), &mrep, &md, &dpos)) != 0) { \ if (error & NFSERR_RETERR) \ error &= ~NFSERR_RETERR; \ else \ @@ -317,7 +318,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, *tl++ = txdr_unsigned(s); \ *(tl+((t2>>2)-2)) = 0; \ bcopy((caddr_t)(a), (caddr_t)tl, (s)); \ - } else if (t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) { \ + } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \ error = t2; \ m_freem(mreq); \ goto nfsmout; \ @@ -358,7 +359,7 @@ struct mbuf *nfsm_rpchead __P((struct ucred *cr, int nmflag, int procid, { t1 = mtod(md, caddr_t)+md->m_len-dpos; \ if (t1 >= (s)) { \ dpos += (s); \ - } else if (t1 = nfs_adv(&md, &dpos, (s), t1)) { \ + } else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \ error = t1; \ m_freem(mrep); \ goto nfsmout; \ diff --git a/sys/nfsserver/nfsproto.h b/sys/nfsserver/nfsproto.h index 6ce7c5b..ada9926 100644 --- a/sys/nfsserver/nfsproto.h +++ b/sys/nfsserver/nfsproto.h @@ -33,8 +33,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)nfsproto.h 8.1 (Berkeley) 6/10/93 - * $Id$ + * @(#)nfsproto.h 8.2 (Berkeley) 3/30/95 + * $Id: nfsproto.h,v 1.3 1997/02/22 09:42:50 peter Exp $ */ #ifndef _NFS_NFSPROTO_H_ diff --git a/sys/nfsserver/nfsrvstats.h b/sys/nfsserver/nfsrvstats.h index 20093f6..a2fac06 100644 --- a/sys/nfsserver/nfsrvstats.h +++ b/sys/nfsserver/nfsrvstats.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.4 (Berkeley) 5/1/95 - * $Id: nfs.h,v 1.35 1998/05/19 07:11:22 peter Exp $ + * $Id: nfs.h,v 1.36 1998/05/24 14:41:47 peter Exp $ */ #ifndef _NFS_NFS_H_ @@ -293,14 +293,6 @@ struct nfsstats { { "nfsprivport", CTLTYPE_INT }, \ } -/* - * Network address hash list element - */ -union nethostaddr { - u_long had_inetaddr; - struct sockaddr *had_nam; -}; - #ifdef KERNEL #ifdef MALLOC_DECLARE @@ -399,6 +391,14 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq; #define NFSNOHASH(fhsum) \ (&nfsnodehashtbl[(fhsum) & nfsnodehash]) +/* + * Network address hash list element + */ +union nethostaddr { + u_long had_inetaddr; + struct sockaddr *had_nam; +}; + struct nfsuid { TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ -- cgit v1.1