diff options
Diffstat (limited to 'sys/nfsserver')
-rw-r--r-- | sys/nfsserver/nfs.h | 133 | ||||
-rw-r--r-- | sys/nfsserver/nfs_fha.c | 5 | ||||
-rw-r--r-- | sys/nfsserver/nfs_serv.c | 424 | ||||
-rw-r--r-- | sys/nfsserver/nfs_srvcache.c | 391 | ||||
-rw-r--r-- | sys/nfsserver/nfs_srvkrpc.c | 5 | ||||
-rw-r--r-- | sys/nfsserver/nfs_srvsock.c | 818 | ||||
-rw-r--r-- | sys/nfsserver/nfs_srvsubs.c | 86 | ||||
-rw-r--r-- | sys/nfsserver/nfs_syscalls.c | 723 | ||||
-rw-r--r-- | sys/nfsserver/nfsrvcache.h | 42 |
9 files changed, 4 insertions, 2623 deletions
diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h index 25fe8ae..b907a06 100644 --- a/sys/nfsserver/nfs.h +++ b/sys/nfsserver/nfs.h @@ -176,102 +176,6 @@ extern int32_t (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *nd, #define NWDELAYHASH(sock, f) \ (&(sock)->ns_wdelayhashtbl[(*((u_int32_t *)(f))) % NFS_WDELAYHASHSIZ]) -#ifdef NFS_LEGACYRPC -/* - * Network address hash list element - */ -union nethostaddr { - u_int32_t had_inetaddr; - struct sockaddr *had_nam; -}; - -struct nfsrv_rec { - STAILQ_ENTRY(nfsrv_rec) nr_link; - struct sockaddr *nr_address; - struct mbuf *nr_packet; -}; - -struct nfssvc_sock { - TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ - struct file *ns_fp; - struct socket *ns_so; - struct sockaddr *ns_nam; - struct mbuf *ns_raw; - struct mbuf *ns_rawend; - STAILQ_HEAD(, nfsrv_rec) ns_rec; - struct mbuf *ns_frag; - int ns_flag; - int ns_solock; - int ns_cc; - int ns_reclen; - u_int32_t ns_sref; - LIST_HEAD(, nfsrv_descript) ns_tq; /* Write gather lists */ - LIST_HEAD(nfsrvw_delayhash, nfsrv_descript) ns_wdelayhashtbl[NFS_WDELAYHASHSIZ]; -}; - -/* Bits for "ns_flag" */ -#define SLP_VALID 0x01 /* Socket valid for use (XXX) */ -#define SLP_DOREC 0x02 /* Socket ready for processing */ -#define SLP_NEEDQ 0x04 /* Socket has request queued */ -#define SLP_DISCONN 0x08 /* Error received from stream socket */ -#define SLP_GETSTREAM 0x10 /* nfsrv_getstream in prog on sock */ -#define SLP_LASTFRAG 0x20 /* Socket received end-of-record */ -#define SLP_ALLFLAGS 0xff - -extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead; -extern int nfssvc_sockhead_flag; -#define SLP_INIT 0x01 -#define SLP_WANTINIT 0x02 - -/* - * One of these structures is allocated for each nfsd. - */ -struct nfsd { - TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */ - int nfsd_flag; /* NFSD_ flags */ - struct nfssvc_sock *nfsd_slp; /* Current socket */ - int nfsd_authlen; /* Authenticator len */ - u_char nfsd_authstr[RPCAUTH_MAXSIZ]; /* Authenticator data */ - int nfsd_verflen; /* and the Verifier */ - u_char nfsd_verfstr[RPCVERF_MAXSIZ]; - struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */ -}; - -/* Bits for "nfsd_flag" */ -#define NFSD_WAITING 0x01 -#define NFSD_REQINPROG 0x02 - -/* - * This structure is used by the server for describing each request. - * Some fields are used only when write request gathering is performed. - */ -struct nfsrv_descript { - u_quad_t nd_time; /* Write deadline (usec) */ - off_t nd_off; /* Start byte offset */ - off_t nd_eoff; /* and end byte offset */ - LIST_ENTRY(nfsrv_descript) nd_hash; /* Hash list */ - LIST_ENTRY(nfsrv_descript) nd_tq; /* and timer list */ - LIST_HEAD(, nfsrv_descript) nd_coalesce;/* coalesced writes */ - struct mbuf *nd_mrep; /* Request mbuf list */ - struct mbuf *nd_md; /* Current dissect mbuf */ - struct mbuf *nd_mreq; /* Reply mbuf list */ - struct sockaddr *nd_nam; /* and socket addr */ - struct sockaddr *nd_nam2; /* return socket addr */ - caddr_t nd_dpos; /* Current dissect pos */ - u_int32_t nd_procnum; /* RPC # */ - int nd_stable; /* storage type */ - int nd_flag; /* nd_flag */ - int nd_len; /* Length of this write */ - int nd_repstat; /* Reply status */ - u_int32_t nd_retxid; /* Reply xid */ - struct timeval nd_starttime; /* Time RPC initiated */ - fhandle_t nd_fh; /* File handle */ - struct ucred *nd_cr; /* Credentials */ - int nd_credflavor; /* Security flavor */ -}; - -#else - /* * This structure is used by the server for describing each request. */ @@ -291,26 +195,9 @@ struct nfsrv_descript { int nd_credflavor; /* Security flavor */ }; -#endif - /* Bits for "nd_flag" */ #define ND_NFSV3 0x08 -#ifdef NFS_LEGACYRPC - -extern TAILQ_HEAD(nfsd_head, nfsd) nfsd_head; -extern int nfsd_head_flag; -#define NFSD_CHECKSLP 0x01 - -/* - * These macros compare nfsrv_descript structures. - */ -#define NFSW_CONTIG(o, n) \ - ((o)->nd_eoff >= (n)->nd_off && \ - !bcmp((caddr_t)&(o)->nd_fh, (caddr_t)&(n)->nd_fh, NFSX_V3FH)) - -#endif - /* * Defines for WebNFS */ @@ -353,26 +240,6 @@ extern int nfs_debug; #endif -#ifdef NFS_LEGACYRPC -int netaddr_match(int, union nethostaddr *, struct sockaddr *); -int nfs_getreq(struct nfsrv_descript *, struct nfsd *, int); -int nfsrv_send(struct socket *, struct sockaddr *, struct mbuf *); -int nfsrv_dorec(struct nfssvc_sock *, struct nfsd *, - struct nfsrv_descript **); -int nfs_slplock(struct nfssvc_sock *, int); -void nfs_slpunlock(struct nfssvc_sock *); -void nfsrv_initcache(void); -void nfsrv_destroycache(void); -void nfsrv_timer(void *); -int nfsrv_getcache(struct nfsrv_descript *, struct mbuf **); -void nfsrv_updatecache(struct nfsrv_descript *, int, struct mbuf *); -void nfsrv_cleancache(void); -int nfsrv_rcv(struct socket *so, void *arg, int waitflag); -void nfsrv_slpderef(struct nfssvc_sock *slp); -void nfsrv_wakenfsd(struct nfssvc_sock *slp); -int nfsrv_writegather(struct nfsrv_descript **, struct nfssvc_sock *, - struct mbuf **); -#endif struct mbuf *nfs_rephead(int, struct nfsrv_descript *, int, struct mbuf **, caddr_t *); void nfsm_srvfattr(struct nfsrv_descript *, struct vattr *, diff --git a/sys/nfsserver/nfs_fha.c b/sys/nfsserver/nfs_fha.c index 27dc9b3..901a0ce 100644 --- a/sys/nfsserver/nfs_fha.c +++ b/sys/nfsserver/nfs_fha.c @@ -39,14 +39,11 @@ __FBSDID("$FreeBSD$"); #include <rpc/rpc.h> #include <nfs/xdr_subs.h> -#include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsserver/nfs.h> #include <nfsserver/nfsm_subs.h> #include <nfsserver/nfs_fha.h> -#ifndef NFS_LEGACYRPC - static MALLOC_DEFINE(M_NFS_FHA, "NFS FHA", "NFS FHA"); /* Sysctl defaults. */ @@ -598,5 +595,3 @@ fhe_stats_sysctl(SYSCTL_HANDLER_ARGS) sbuf_delete(&sb); return (error); } - -#endif /* !NFS_LEGACYRPC */ diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index b6a61a8..00be15e 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -93,7 +93,6 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_object.h> #include <nfs/nfsproto.h> -#include <nfs/rpcv2.h> #include <nfsserver/nfs.h> #include <nfs/xdr_subs.h> #include <nfsserver/nfsm_subs.h> @@ -142,10 +141,6 @@ SYSCTL_STRUCT(_vfs_nfsrv, NFS_NFSRVSTATS, nfsrvstats, CTLFLAG_RW, static int nfsrv_access(struct vnode *, accmode_t, struct ucred *, int, int); -#ifdef NFS_LEGACYRPC -static void nfsrvw_coalesce(struct nfsrv_descript *, - struct nfsrv_descript *); -#endif /* * Clear nameidata fields that are tested in nsfmout cleanup code prior @@ -1229,425 +1224,6 @@ nfsmout: return(error); } -#ifdef NFS_LEGACYRPC - -/* - * XXX dfr - write gathering isn't supported by the new RPC code since - * its really only useful for NFSv2. If there is a real need, we could - * attempt to fit it into the filehandle affinity system, e.g. by - * looking to see if there are queued write requests that overlap this - * one. - */ - -/* - * For the purposes of write gathering, we must decide if the credential - * associated with two pending requests have equivilent privileges. Since - * NFS only uses a subset of the BSD ucred -- the effective uid and group - * IDs -- we have a compare routine that checks only the relevant fields. - */ -static int -nfsrv_samecred(struct ucred *cr1, struct ucred *cr2) -{ - int i; - - if (cr1->cr_uid != cr2->cr_uid) - return (0); - if (cr1->cr_ngroups != cr2->cr_ngroups) - return (0); - for (i = 0; i < cr1->cr_ngroups; i++) { - if (cr1->cr_groups[i] != cr2->cr_groups[i]) - return (0); - } - return (1); -} - -/* - * NFS write service with write gathering support. Called when - * nfsrvw_procrastinate > 0. - * See: Chet Juszczak, "Improving the Write Performance of an NFS Server", - * in Proc. of the Winter 1994 Usenix Conference, pg. 247-259, San Franscisco, - * Jan. 1994. - */ -int -nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct iovec *ivp; - struct mbuf *mp; - struct nfsrv_descript *wp, *nfsd, *owp, *swp; - struct nfs_fattr *fp; - int i; - struct iovec *iov; - struct nfsrvw_delayhash *wpp; - struct ucred *cred; - struct vattr va, forat; - u_int32_t *tl; - caddr_t bpos, dpos; - int error = 0, rdonly, len, forat_ret = 1; - int ioflags, aftat_ret = 1, s, adjust, v3, zeroing; - struct mbuf *mb, *mreq, *mrep, *md; - struct vnode *vp = NULL; - struct uio io, *uiop = &io; - u_quad_t cur_usec; - struct mount *mntp = NULL; - int mvfslocked; - int vfslocked; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); -#ifndef nolint - i = 0; - len = 0; -#endif - vfslocked = 0; - *mrq = NULL; - if (*ndp) { - nfsd = *ndp; - *ndp = NULL; - mrep = nfsd->nd_mrep; - md = nfsd->nd_md; - dpos = nfsd->nd_dpos; - cred = nfsd->nd_cr; - v3 = (nfsd->nd_flag & ND_NFSV3); - LIST_INIT(&nfsd->nd_coalesce); - nfsd->nd_mreq = NULL; - nfsd->nd_stable = NFSV3WRITE_FILESYNC; - cur_usec = nfs_curusec(); - nfsd->nd_time = cur_usec + - (v3 ? nfsrvw_procrastinate_v3 : nfsrvw_procrastinate); - - /* - * Now, get the write header.. - */ - nfsm_srvmtofh(&nfsd->nd_fh); - if (v3) { - tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED); - nfsd->nd_off = fxdr_hyper(tl); - tl += 3; - nfsd->nd_stable = fxdr_unsigned(int, *tl++); - } else { - tl = nfsm_dissect_nonblock(u_int32_t *, 4 * NFSX_UNSIGNED); - nfsd->nd_off = (off_t)fxdr_unsigned(u_int32_t, *++tl); - tl += 2; - if (nfs_async) - nfsd->nd_stable = NFSV3WRITE_UNSTABLE; - } - len = fxdr_unsigned(int32_t, *tl); - nfsd->nd_len = len; - nfsd->nd_eoff = nfsd->nd_off + len; - - /* - * Trim the header out of the mbuf list and trim off any trailing - * junk so that the mbuf list has only the write data. - */ - zeroing = 1; - i = 0; - mp = mrep; - while (mp) { - if (mp == md) { - zeroing = 0; - adjust = dpos - mtod(mp, caddr_t); - mp->m_len -= adjust; - if (mp->m_len > 0 && adjust > 0) - mp->m_data += adjust; - } - if (zeroing) - mp->m_len = 0; - else { - i += mp->m_len; - if (i > len) { - mp->m_len -= (i - len); - zeroing = 1; - } - } - mp = mp->m_next; - } - if (len > NFS_MAXDATA || len < 0 || i < len) { -nfsmout: - m_freem(mrep); - error = EIO; - nfsm_writereply(2 * NFSX_UNSIGNED); - if (v3) - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va); - nfsd->nd_mreq = mreq; - nfsd->nd_mrep = NULL; - nfsd->nd_time = 0; - } - - /* - * Add this entry to the hash and time queues. - */ - s = splsoftclock(); - owp = NULL; - wp = LIST_FIRST(&slp->ns_tq); - while (wp && wp->nd_time < nfsd->nd_time) { - owp = wp; - wp = LIST_NEXT(wp, nd_tq); - } - NFS_DPF(WG, ("Q%03x", nfsd->nd_retxid & 0xfff)); - if (owp) { - LIST_INSERT_AFTER(owp, nfsd, nd_tq); - } else { - LIST_INSERT_HEAD(&slp->ns_tq, nfsd, nd_tq); - } - if (nfsd->nd_mrep) { - wpp = NWDELAYHASH(slp, nfsd->nd_fh.fh_fid.fid_data); - owp = NULL; - wp = LIST_FIRST(wpp); - while (wp && - bcmp((caddr_t)&nfsd->nd_fh,(caddr_t)&wp->nd_fh, NFSX_V3FH)){ - owp = wp; - wp = LIST_NEXT(wp, nd_hash); - } - while (wp && wp->nd_off < nfsd->nd_off && - !bcmp((caddr_t)&nfsd->nd_fh,(caddr_t)&wp->nd_fh, NFSX_V3FH)) { - owp = wp; - wp = LIST_NEXT(wp, nd_hash); - } - if (owp) { - LIST_INSERT_AFTER(owp, nfsd, nd_hash); - - /* - * Search the hash list for overlapping entries and - * coalesce. - */ - for(; nfsd && NFSW_CONTIG(owp, nfsd); nfsd = wp) { - wp = LIST_NEXT(nfsd, nd_hash); - if (nfsrv_samecred(owp->nd_cr, nfsd->nd_cr)) - nfsrvw_coalesce(owp, nfsd); - } - } else { - LIST_INSERT_HEAD(wpp, nfsd, nd_hash); - } - } - splx(s); - } - - /* - * Now, do VOP_WRITE()s for any one(s) that need to be done now - * and generate the associated reply mbuf list(s). - */ -loop1: - cur_usec = nfs_curusec(); - s = splsoftclock(); - for (nfsd = LIST_FIRST(&slp->ns_tq); nfsd; nfsd = owp) { - owp = LIST_NEXT(nfsd, nd_tq); - if (nfsd->nd_time > cur_usec) - break; - if (nfsd->nd_mreq) - continue; - NFS_DPF(WG, ("P%03x", nfsd->nd_retxid & 0xfff)); - LIST_REMOVE(nfsd, nd_tq); - LIST_REMOVE(nfsd, nd_hash); - splx(s); - mrep = nfsd->nd_mrep; - nfsd->nd_mrep = NULL; - cred = nfsd->nd_cr; - v3 = (nfsd->nd_flag & ND_NFSV3); - forat_ret = aftat_ret = 1; - error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, &vfslocked, nfsd, - slp, nfsd->nd_nam, &rdonly, TRUE); - if (!error) { - if (v3) - forat_ret = VOP_GETATTR(vp, &forat, cred); - if (vp->v_type != VREG) { - if (v3) - error = EINVAL; - else - error = (vp->v_type == VDIR) ? EISDIR : EACCES; - } - } else { - vp = NULL; - } - if (!error) - error = nfsrv_access(vp, VWRITE, cred, rdonly, 1); - if (nfsd->nd_stable == NFSV3WRITE_UNSTABLE) - ioflags = IO_NODELOCKED; - else if (nfsd->nd_stable == NFSV3WRITE_DATASYNC) - ioflags = (IO_SYNC | IO_NODELOCKED); - else - ioflags = (IO_METASYNC | IO_SYNC | IO_NODELOCKED); - uiop->uio_rw = UIO_WRITE; - uiop->uio_segflg = UIO_SYSSPACE; - uiop->uio_td = NULL; - uiop->uio_offset = nfsd->nd_off; - uiop->uio_resid = nfsd->nd_eoff - nfsd->nd_off; - if (uiop->uio_resid > 0) { - mp = mrep; - i = 0; - while (mp) { - if (mp->m_len > 0) - i++; - mp = mp->m_next; - } - uiop->uio_iovcnt = i; - iov = malloc(i * sizeof (struct iovec), - M_TEMP, M_WAITOK); - uiop->uio_iov = ivp = iov; - mp = mrep; - while (mp) { - if (mp->m_len > 0) { - ivp->iov_base = mtod(mp, caddr_t); - ivp->iov_len = mp->m_len; - ivp++; - } - mp = mp->m_next; - } - mvfslocked = 0; - if (!error) { - if (vn_start_write(vp, &mntp, V_NOWAIT) != 0) { - VOP_UNLOCK(vp, 0); - error = vn_start_write(NULL, &mntp, V_WAIT); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - } - mvfslocked = VFS_LOCK_GIANT(mntp); - } - if (!error) { - error = VOP_WRITE(vp, uiop, ioflags, cred); - /* Unlocked write. */ - nfsrvstats.srvvop_writes++; - vn_finished_write(mntp); - } - VFS_UNLOCK_GIANT(mvfslocked); - free((caddr_t)iov, M_TEMP); - } - m_freem(mrep); - if (vp) { - aftat_ret = VOP_GETATTR(vp, &va, cred); - vput(vp); - vp = NULL; - } - VFS_UNLOCK_GIANT(vfslocked); - /* - * Loop around generating replies for all write rpcs that have - * now been completed. - */ - swp = nfsd; - do { - NFS_DPF(WG, ("R%03x", nfsd->nd_retxid & 0xfff)); - if (error) { - nfsm_writereply(NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va); - } - } else { - nfsm_writereply(NFSX_PREOPATTR(v3) + - NFSX_POSTOPORFATTR(v3) + 2 * NFSX_UNSIGNED + - NFSX_WRITEVERF(v3)); - if (v3) { - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va); - tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(nfsd->nd_len); - *tl++ = txdr_unsigned(swp->nd_stable); - /* - * Actually, there is no need to txdr these fields, - * but it may make the values more human readable, - * for debugging purposes. - */ - if (nfsver.tv_sec == 0) - nfsver = boottime; - *tl++ = txdr_unsigned(nfsver.tv_sec); - *tl = txdr_unsigned(nfsver.tv_usec); - } else { - fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(&va, fp); - } - } - nfsd->nd_mreq = mreq; - if (nfsd->nd_mrep) - panic("nfsrv_write: nd_mrep not free"); - - /* - * Done. Put it at the head of the timer queue so that - * the final phase can return the reply. - */ - s = splsoftclock(); - if (nfsd != swp) { - nfsd->nd_time = 0; - LIST_INSERT_HEAD(&slp->ns_tq, nfsd, nd_tq); - } - nfsd = LIST_FIRST(&swp->nd_coalesce); - if (nfsd) { - LIST_REMOVE(nfsd, nd_tq); - } - splx(s); - } while (nfsd); - s = splsoftclock(); - swp->nd_time = 0; - LIST_INSERT_HEAD(&slp->ns_tq, swp, nd_tq); - splx(s); - goto loop1; - } - splx(s); - - /* - * Search for a reply to return. - */ - s = splsoftclock(); - LIST_FOREACH(nfsd, &slp->ns_tq, nd_tq) - if (nfsd->nd_mreq) { - NFS_DPF(WG, ("X%03x", nfsd->nd_retxid & 0xfff)); - LIST_REMOVE(nfsd, nd_tq); - *mrq = nfsd->nd_mreq; - *ndp = nfsd; - break; - } - splx(s); - return (0); -} - -/* - * Coalesce the write request nfsd into owp. To do this we must: - * - remove nfsd from the queues - * - merge nfsd->nd_mrep into owp->nd_mrep - * - update the nd_eoff and nd_stable for owp - * - put nfsd on owp's nd_coalesce list - * NB: Must be called at splsoftclock(). - */ -static void -nfsrvw_coalesce(struct nfsrv_descript *owp, struct nfsrv_descript *nfsd) -{ - int overlap; - struct mbuf *mp; - struct nfsrv_descript *p; - - NFS_DPF(WG, ("C%03x-%03x", - nfsd->nd_retxid & 0xfff, owp->nd_retxid & 0xfff)); - LIST_REMOVE(nfsd, nd_hash); - LIST_REMOVE(nfsd, nd_tq); - if (owp->nd_eoff < nfsd->nd_eoff) { - overlap = owp->nd_eoff - nfsd->nd_off; - if (overlap < 0) - panic("nfsrv_coalesce: bad off"); - if (overlap > 0) - m_adj(nfsd->nd_mrep, overlap); - mp = owp->nd_mrep; - while (mp->m_next) - mp = mp->m_next; - mp->m_next = nfsd->nd_mrep; - owp->nd_eoff = nfsd->nd_eoff; - } else - m_freem(nfsd->nd_mrep); - nfsd->nd_mrep = NULL; - if (nfsd->nd_stable == NFSV3WRITE_FILESYNC) - owp->nd_stable = NFSV3WRITE_FILESYNC; - else if (nfsd->nd_stable == NFSV3WRITE_DATASYNC && - owp->nd_stable == NFSV3WRITE_UNSTABLE) - owp->nd_stable = NFSV3WRITE_DATASYNC; - LIST_INSERT_HEAD(&owp->nd_coalesce, nfsd, nd_tq); - - /* - * If nfsd had anything else coalesced into it, transfer them - * to owp, otherwise their replies will never get sent. - */ - for (p = LIST_FIRST(&nfsd->nd_coalesce); p; - p = LIST_FIRST(&nfsd->nd_coalesce)) { - LIST_REMOVE(p, nd_tq); - LIST_INSERT_HEAD(&owp->nd_coalesce, p, nd_tq); - } -} - -#endif - /* * nfs create service * now does a truncate to 0 length via. setattr if it already exists diff --git a/sys/nfsserver/nfs_srvcache.c b/sys/nfsserver/nfs_srvcache.c deleted file mode 100644 index 5121690..0000000 --- a/sys/nfsserver/nfs_srvcache.c +++ /dev/null @@ -1,391 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_srvcache.c 8.3 (Berkeley) 3/30/95 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Reference: Chet Juszczak, "Improving the Performance and Correctness - * of an NFS Server", in Proc. Winter 1989 USENIX Conference, - * pages 53-63. San Diego, February 1989. - */ -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/systm.h> -#include <sys/lock.h> -#include <sys/mbuf.h> -#include <sys/mutex.h> -#include <sys/socket.h> -#include <sys/socketvar.h> /* for sodupsockaddr */ -#include <sys/eventhandler.h> - -#include <netinet/in.h> -#include <nfs/rpcv2.h> -#include <nfs/nfsproto.h> -#include <nfsserver/nfs.h> -#include <nfsserver/nfsrvcache.h> - -#ifdef NFS_LEGACYRPC - -static long numnfsrvcache; -static long desirednfsrvcache; - -#define NFSRCHASH(xid) \ - (&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash]) -static LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl; -static TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead; -static u_long nfsrvhash; -static eventhandler_tag nfsrv_nmbclusters_tag; - -#define TRUE 1 -#define FALSE 0 - -#define NETFAMILY(rp) \ - (((rp)->rc_flag & RC_NAM) ? (rp)->rc_nam->sa_family : AF_INET) - -/* - * Static array that defines which nfs rpc's are nonidempotent - */ -static const int nonidempotent[NFS_NPROCS] = { - FALSE, - FALSE, - TRUE, - FALSE, - FALSE, - FALSE, - FALSE, - TRUE, - TRUE, - TRUE, - TRUE, - TRUE, - TRUE, - TRUE, - TRUE, - TRUE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, -}; - -/* True iff the rpc reply is an nfs status ONLY! */ -static const int nfsv2_repstat[NFS_NPROCS] = { - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - FALSE, - TRUE, - TRUE, - TRUE, - TRUE, - FALSE, - TRUE, - FALSE, - FALSE, -}; - -/* - * Size the NFS server's duplicate request cache at 1/2 the nmbclsters, floating - * within a (64, 2048) range. This is to prevent all mbuf clusters being tied up - * in the NFS dupreq cache for small values of nmbclusters. - */ -static void -nfsrvcache_size_change(void *tag) -{ - desirednfsrvcache = nmbclusters /2; - if (desirednfsrvcache > NFSRVCACHE_MAX_SIZE) - desirednfsrvcache = NFSRVCACHE_MAX_SIZE; - if (desirednfsrvcache < NFSRVCACHE_MIN_SIZE) - desirednfsrvcache = NFSRVCACHE_MIN_SIZE; -} - -/* - * Initialize the server request cache list - */ -void -nfsrv_initcache(void) -{ - nfsrvcache_size_change(NULL); - nfsrvhashtbl = hashinit(desirednfsrvcache, M_NFSD, &nfsrvhash); - TAILQ_INIT(&nfsrvlruhead); - nfsrv_nmbclusters_tag = EVENTHANDLER_REGISTER(nmbclusters_change, - nfsrvcache_size_change, NULL, EVENTHANDLER_PRI_FIRST); -} - -/* - * Teardown the server request cache list - */ -void -nfsrv_destroycache(void) -{ - KASSERT(TAILQ_EMPTY(&nfsrvlruhead), ("%s: pending requests", __func__)); - EVENTHANDLER_DEREGISTER(nmbclusters_change, nfsrv_nmbclusters_tag); - hashdestroy(nfsrvhashtbl, M_NFSD, nfsrvhash); -} - -/* - * Look for the request in the cache - * If found then - * return action and optionally reply - * else - * insert it in the cache - * - * The rules are as follows: - * - if in progress, return DROP request - * - if completed within DELAY of the current time, return DROP it - * - if completed a longer time ago return REPLY if the reply was cached or - * return DOIT - * Update/add new request at end of lru list - */ -int -nfsrv_getcache(struct nfsrv_descript *nd, struct mbuf **repp) -{ - struct nfsrvcache *rp; - struct mbuf *mb; - struct sockaddr_in *saddr; - caddr_t bpos; - int ret; - - NFSD_LOCK_ASSERT(); - - /* - * Don't cache recent requests for reliable transport protocols. - * (Maybe we should for the case of a reconnect, but..) - */ - if (!nd->nd_nam2) - return (RC_DOIT); -loop: - LIST_FOREACH(rp, NFSRCHASH(nd->nd_retxid), rc_hash) { - if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc && - netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nd->nd_nam)) { - NFS_DPF(RC, ("H%03x", rp->rc_xid & 0xfff)); - if ((rp->rc_flag & RC_LOCKED) != 0) { - rp->rc_flag |= RC_WANTED; - (void) msleep(rp, &nfsd_mtx, PZERO-1, - "nfsrc", 0); - goto loop; - } - rp->rc_flag |= RC_LOCKED; - /* If not at end of LRU chain, move it there */ - if (TAILQ_NEXT(rp, rc_lru)) { - TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru); - TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru); - } - if (rp->rc_state == RC_UNUSED) - panic("nfsrv cache"); - if (rp->rc_state == RC_INPROG) { - nfsrvstats.srvcache_inproghits++; - ret = RC_DROPIT; - } else if (rp->rc_flag & RC_REPSTATUS) { - nfsrvstats.srvcache_nonidemdonehits++; - NFSD_UNLOCK(); - *repp = nfs_rephead(0, nd, rp->rc_status, - &mb, &bpos); - ret = RC_REPLY; - NFSD_LOCK(); - } else if (rp->rc_flag & RC_REPMBUF) { - nfsrvstats.srvcache_nonidemdonehits++; - NFSD_UNLOCK(); - *repp = m_copym(rp->rc_reply, 0, M_COPYALL, - M_WAIT); - NFSD_LOCK(); - ret = RC_REPLY; - } else { - nfsrvstats.srvcache_idemdonehits++; - rp->rc_state = RC_INPROG; - ret = RC_DOIT; - } - rp->rc_flag &= ~RC_LOCKED; - if (rp->rc_flag & RC_WANTED) { - rp->rc_flag &= ~RC_WANTED; - wakeup(rp); - } - return (ret); - } - } - nfsrvstats.srvcache_misses++; - NFS_DPF(RC, ("M%03x", nd->nd_retxid & 0xfff)); - if (numnfsrvcache < desirednfsrvcache) { - NFSD_UNLOCK(); - rp = (struct nfsrvcache *)malloc((u_long)sizeof *rp, - M_NFSD, M_WAITOK | M_ZERO); - NFSD_LOCK(); - numnfsrvcache++; - rp->rc_flag = RC_LOCKED; - } else { - rp = TAILQ_FIRST(&nfsrvlruhead); - while ((rp->rc_flag & RC_LOCKED) != 0) { - rp->rc_flag |= RC_WANTED; - (void) msleep(rp, &nfsd_mtx, PZERO-1, "nfsrc", 0); - rp = TAILQ_FIRST(&nfsrvlruhead); - } - rp->rc_flag |= RC_LOCKED; - LIST_REMOVE(rp, rc_hash); - TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru); - if (rp->rc_flag & RC_REPMBUF) - m_freem(rp->rc_reply); - if (rp->rc_flag & RC_NAM) - free(rp->rc_nam, M_SONAME); - rp->rc_flag &= (RC_LOCKED | RC_WANTED); - } - TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru); - rp->rc_state = RC_INPROG; - rp->rc_xid = nd->nd_retxid; - saddr = (struct sockaddr_in *)nd->nd_nam; - switch (saddr->sin_family) { - case AF_INET: - rp->rc_flag |= RC_INETADDR; - rp->rc_inetaddr = saddr->sin_addr.s_addr; - break; -/* case AF_INET6: */ -/* case AF_ISO: */ - default: - /* - * XXXRW: Seems like we should only set RC_NAM if we - * actually manage to set rc_nam to something non-NULL. - */ - rp->rc_flag |= RC_NAM; - rp->rc_nam = sodupsockaddr(nd->nd_nam, M_NOWAIT); - break; - }; - rp->rc_proc = nd->nd_procnum; - LIST_INSERT_HEAD(NFSRCHASH(nd->nd_retxid), rp, rc_hash); - rp->rc_flag &= ~RC_LOCKED; - if (rp->rc_flag & RC_WANTED) { - rp->rc_flag &= ~RC_WANTED; - wakeup(rp); - } - return (RC_DOIT); -} - -/* - * Update a request cache entry after the rpc has been done - */ -void -nfsrv_updatecache(struct nfsrv_descript *nd, int repvalid, struct mbuf *repmbuf) -{ - struct nfsrvcache *rp; - - NFSD_LOCK_ASSERT(); - - if (!nd->nd_nam2) - return; -loop: - LIST_FOREACH(rp, NFSRCHASH(nd->nd_retxid), rc_hash) { - if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc && - netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nd->nd_nam)) { - NFS_DPF(RC, ("U%03x", rp->rc_xid & 0xfff)); - if ((rp->rc_flag & RC_LOCKED) != 0) { - rp->rc_flag |= RC_WANTED; - (void) msleep(rp, &nfsd_mtx, PZERO-1, - "nfsrc", 0); - goto loop; - } - rp->rc_flag |= RC_LOCKED; - if (rp->rc_state == RC_DONE) { - /* - * This can occur if the cache is too small. - * Retransmits of the same request aren't - * dropped so we may see the operation - * complete more then once. - */ - if (rp->rc_flag & RC_REPMBUF) { - m_freem(rp->rc_reply); - rp->rc_flag &= ~RC_REPMBUF; - } - } - rp->rc_state = RC_DONE; - /* - * If we have a valid reply update status and save - * the reply for non-idempotent rpc's. - */ - if (repvalid && nonidempotent[nd->nd_procnum]) { - if ((nd->nd_flag & ND_NFSV3) == 0 && - nfsv2_repstat[ - nfsrvv2_procid[nd->nd_procnum]]) { - rp->rc_status = nd->nd_repstat; - rp->rc_flag |= RC_REPSTATUS; - } else { - NFSD_UNLOCK(); - rp->rc_reply = m_copym(repmbuf, - 0, M_COPYALL, M_WAIT); - NFSD_LOCK(); - rp->rc_flag |= RC_REPMBUF; - } - } - rp->rc_flag &= ~RC_LOCKED; - if (rp->rc_flag & RC_WANTED) { - rp->rc_flag &= ~RC_WANTED; - wakeup(rp); - } - return; - } - } - NFS_DPF(RC, ("L%03x", nd->nd_retxid & 0xfff)); -} - -/* - * Clean out the cache. Called when the last nfsd terminates. - */ -void -nfsrv_cleancache(void) -{ - struct nfsrvcache *rp, *nextrp; - - NFSD_LOCK_ASSERT(); - - TAILQ_FOREACH_SAFE(rp, &nfsrvlruhead, rc_lru, nextrp) { - LIST_REMOVE(rp, rc_hash); - TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru); - if (rp->rc_flag & RC_REPMBUF) - m_freem(rp->rc_reply); - if (rp->rc_flag & RC_NAM) - free(rp->rc_nam, M_SONAME); - free(rp, M_NFSD); - } - numnfsrvcache = 0; -} - -#endif /* NFS_LEGACYRPC */ diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c index 99edac5..54b1c4a 100644 --- a/sys/nfsserver/nfs_srvkrpc.c +++ b/sys/nfsserver/nfs_srvkrpc.c @@ -75,7 +75,6 @@ __FBSDID("$FreeBSD$"); #include <rpc/replay.h> #include <nfs/xdr_subs.h> -#include <nfs/rpcv2.h> #include <nfs/nfsproto.h> #include <nfsserver/nfs.h> #include <nfsserver/nfsm_subs.h> @@ -84,8 +83,6 @@ __FBSDID("$FreeBSD$"); #include <security/mac/mac_framework.h> -#ifndef NFS_LEGACYRPC - static MALLOC_DEFINE(M_NFSSVC, "nfss_srvsock", "Nfs server structure"); MALLOC_DEFINE(M_NFSRVDESC, "nfss_srvdesc", "NFS server socket descriptor"); @@ -607,5 +604,3 @@ nfsrv_init(int terminating) NFSD_LOCK(); } - -#endif /* !NFS_LEGACYRPC */ diff --git a/sys/nfsserver/nfs_srvsock.c b/sys/nfsserver/nfs_srvsock.c deleted file mode 100644 index b5c3fa2..0000000 --- a/sys/nfsserver/nfs_srvsock.c +++ /dev/null @@ -1,818 +0,0 @@ -/*- - * Copyright (c) 1989, 1991, 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * Socket operations for use by nfs - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/jail.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mbuf.h> -#include <sys/mount.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/protosw.h> -#include <sys/refcount.h> -#include <sys/signalvar.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/sysctl.h> -#include <sys/syslog.h> -#include <sys/vnode.h> - -#include <netinet/in.h> -#include <netinet/tcp.h> - -#include <nfs/rpcv2.h> -#include <nfs/nfsproto.h> -#include <nfsserver/nfs.h> -#include <nfs/xdr_subs.h> -#include <nfsserver/nfsm_subs.h> - -#include <security/mac/mac_framework.h> - -#ifdef NFS_LEGACYRPC - -#define TRUE 1 -#define FALSE 0 - -static int nfs_realign_test; -static int nfs_realign_count; - -SYSCTL_DECL(_vfs_nfsrv); - -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, ""); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, ""); - - -/* - * There is a congestion window for outstanding rpcs maintained per mount - * point. The cwnd size is adjusted in roughly the way that: - * Van Jacobson, Congestion avoidance and Control, In "Proceedings of - * SIGCOMM '88". ACM, August 1988. - * describes for TCP. The cwnd size is chopped in half on a retransmit timeout - * and incremented by 1/cwnd when each rpc reply is received and a full cwnd - * of rpcs is in progress. - * (The sent count and cwnd are scaled for integer arith.) - * Variants of "slow start" were tried and were found to be too much of a - * performance hit (ave. rtt 3 times larger), - * I suspect due to the large rtt that nfs rpcs have. - */ -#define NFS_CWNDSCALE 256 -#define NFS_MAXCWND (NFS_CWNDSCALE * 32) -struct callout nfsrv_callout; - -static void nfs_realign(struct mbuf **pm, int hsiz); /* XXX SHARED */ -static int nfsrv_getstream(struct nfssvc_sock *, int); - -int32_t (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *nd, - struct nfssvc_sock *slp, - struct mbuf **mreqp) = { - nfsrv_null, - nfsrv_getattr, - nfsrv_setattr, - nfsrv_lookup, - nfsrv3_access, - nfsrv_readlink, - nfsrv_read, - nfsrv_write, - nfsrv_create, - nfsrv_mkdir, - nfsrv_symlink, - nfsrv_mknod, - nfsrv_remove, - nfsrv_rmdir, - nfsrv_rename, - nfsrv_link, - nfsrv_readdir, - nfsrv_readdirplus, - nfsrv_statfs, - nfsrv_fsinfo, - nfsrv_pathconf, - nfsrv_commit, - nfsrv_noop -}; - - -/* - * Generate the rpc reply header - * siz arg. is used to decide if adding a cluster is worthwhile - */ -struct mbuf * -nfs_rephead(int siz, struct nfsrv_descript *nd, int err, - struct mbuf **mbp, caddr_t *bposp) -{ - u_int32_t *tl; - struct mbuf *mreq; - caddr_t bpos; - struct mbuf *mb; - - nd->nd_repstat = err; - if (err && (nd->nd_flag & ND_NFSV3) == 0) /* XXX recheck */ - siz = 0; - MGETHDR(mreq, M_WAIT, MT_DATA); - mb = mreq; - /* - * If this is a big reply, use a cluster else - * try and leave leading space for the lower level headers. - */ - mreq->m_len = 6 * NFSX_UNSIGNED; - siz += RPC_REPLYSIZ; - if ((max_hdr + siz) >= MINCLSIZE) { - MCLGET(mreq, M_WAIT); - } else - mreq->m_data += min(max_hdr, M_TRAILINGSPACE(mreq)); - tl = mtod(mreq, u_int32_t *); - bpos = ((caddr_t)tl) + mreq->m_len; - *tl++ = txdr_unsigned(nd->nd_retxid); - *tl++ = nfsrv_rpc_reply; - if (err == ERPCMISMATCH || (err & NFSERR_AUTHERR)) { - *tl++ = nfsrv_rpc_msgdenied; - if (err & NFSERR_AUTHERR) { - *tl++ = nfsrv_rpc_autherr; - *tl = txdr_unsigned(err & ~NFSERR_AUTHERR); - mreq->m_len -= NFSX_UNSIGNED; - bpos -= NFSX_UNSIGNED; - } else { - *tl++ = nfsrv_rpc_mismatch; - *tl++ = txdr_unsigned(RPC_VER2); - *tl = txdr_unsigned(RPC_VER2); - } - } else { - *tl++ = nfsrv_rpc_msgaccepted; - /* - * Send a RPCAUTH_NULL verifier - no Kerberos. - */ - *tl++ = 0; - *tl++ = 0; - switch (err) { - case EPROGUNAVAIL: - *tl = txdr_unsigned(RPC_PROGUNAVAIL); - break; - case EPROGMISMATCH: - *tl = txdr_unsigned(RPC_PROGMISMATCH); - tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(2); - *tl = txdr_unsigned(3); - break; - case EPROCUNAVAIL: - *tl = txdr_unsigned(RPC_PROCUNAVAIL); - break; - case EBADRPC: - *tl = txdr_unsigned(RPC_GARBAGE); - break; - default: - *tl = 0; - if (err != NFSERR_RETVOID) { - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - if (err) - *tl = txdr_unsigned(nfsrv_errmap(nd, err)); - else - *tl = 0; - } - break; - } - } - *mbp = mb; - *bposp = bpos; - if (err != 0 && err != NFSERR_RETVOID) - nfsrvstats.srvrpc_errs++; - return mreq; -} - - -/* - * nfs_realign: - * - * Check for badly aligned mbuf data and realign by copying the unaligned - * portion of the data into a new mbuf chain and freeing the portions - * of the old chain that were replaced. - * - * We cannot simply realign the data within the existing mbuf chain - * because the underlying buffers may contain other rpc commands and - * we cannot afford to overwrite them. - * - * We would prefer to avoid this situation entirely. The situation does - * not occur with NFS/UDP and is supposed to only occassionally occur - * with TCP. Use vfs.nfs.realign_count and realign_test to check this. - */ -static void -nfs_realign(struct mbuf **pm, int hsiz) /* XXX COMMON */ -{ - struct mbuf *m; - struct mbuf *n = NULL; - int off = 0; - - ++nfs_realign_test; - while ((m = *pm) != NULL) { - if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - MGET(n, M_WAIT, MT_DATA); - if (m->m_len >= MINCLSIZE) { - MCLGET(n, M_WAIT); - } - n->m_len = 0; - break; - } - pm = &m->m_next; - } - - /* - * If n is non-NULL, loop on m copying data, then replace the - * portion of the chain that had to be realigned. - */ - if (n != NULL) { - ++nfs_realign_count; - while (m) { - m_copyback(n, off, m->m_len, mtod(m, caddr_t)); - off += m->m_len; - m = m->m_next; - } - m_freem(*pm); - *pm = n; - } -} - - -/* - * Parse an RPC request - * - verify it - * - fill in the cred struct. - */ -int -nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) -{ - int len, i; - u_int32_t *tl; - caddr_t dpos; - u_int32_t nfsvers, auth_type; - int error = 0; - struct mbuf *mrep, *md; - - NFSD_LOCK_ASSERT(); - - mrep = nd->nd_mrep; - md = nd->nd_md; - dpos = nd->nd_dpos; - if (has_header) { - tl = nfsm_dissect_nonblock(u_int32_t *, 10 * NFSX_UNSIGNED); - nd->nd_retxid = fxdr_unsigned(u_int32_t, *tl++); - if (*tl++ != nfsrv_rpc_call) { - m_freem(mrep); - return (EBADRPC); - } - } else - tl = nfsm_dissect_nonblock(u_int32_t *, 8 * NFSX_UNSIGNED); - nd->nd_repstat = 0; - nd->nd_flag = 0; - if (*tl++ != nfsrv_rpc_vers) { - nd->nd_repstat = ERPCMISMATCH; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - if (*tl != nfsrv_nfs_prog) { - nd->nd_repstat = EPROGUNAVAIL; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - tl++; - nfsvers = fxdr_unsigned(u_int32_t, *tl++); - if (nfsvers < NFS_VER2 || nfsvers > NFS_VER3) { - nd->nd_repstat = EPROGMISMATCH; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - nd->nd_procnum = fxdr_unsigned(u_int32_t, *tl++); - if (nd->nd_procnum == NFSPROC_NULL) - return (0); - if (nfsvers == NFS_VER3) { - nd->nd_flag = ND_NFSV3; - if (nd->nd_procnum >= NFS_NPROCS) { - nd->nd_repstat = EPROCUNAVAIL; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - } else { - if (nd->nd_procnum > NFSV2PROC_STATFS) { - nd->nd_repstat = EPROCUNAVAIL; - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - /* Map the v2 procedure numbers into v3 ones */ - nd->nd_procnum = nfsrv_nfsv3_procid[nd->nd_procnum]; - } - auth_type = *tl++; - len = fxdr_unsigned(int, *tl++); - if (len < 0 || len > RPCAUTH_MAXSIZ) { - m_freem(mrep); - return (EBADRPC); - } - - /* - * Handle auth_unix; - */ - if (auth_type == nfsrv_rpc_auth_unix) { - len = fxdr_unsigned(int, *++tl); - if (len < 0 || len > NFS_MAXNAMLEN) { - m_freem(mrep); - return (EBADRPC); - } - nfsm_adv(nfsm_rndup(len)); - tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED); - nd->nd_cr->cr_uid = nd->nd_cr->cr_ruid = - nd->nd_cr->cr_svuid = fxdr_unsigned(uid_t, *tl++); - nd->nd_cr->cr_groups[0] = nd->nd_cr->cr_rgid = - nd->nd_cr->cr_svgid = fxdr_unsigned(gid_t, *tl++); -#ifdef MAC - mac_cred_associate_nfsd(nd->nd_cr); -#endif - len = fxdr_unsigned(int, *tl); - if (len < 0 || len > RPCAUTH_UNIXGIDS) { - m_freem(mrep); - return (EBADRPC); - } - tl = nfsm_dissect_nonblock(u_int32_t *, (len + 2) * NFSX_UNSIGNED); - for (i = 1; i <= len; i++) - if (i < XU_NGROUPS) - nd->nd_cr->cr_groups[i] = fxdr_unsigned(gid_t, *tl++); - else - tl++; - nd->nd_cr->cr_ngroups = MIN(XU_NGROUPS, len + 1); - if (nd->nd_cr->cr_ngroups > 1) - nfsrvw_sort(nd->nd_cr->cr_groups, nd->nd_cr->cr_ngroups); - len = fxdr_unsigned(int, *++tl); - if (len < 0 || len > RPCAUTH_MAXSIZ) { - m_freem(mrep); - return (EBADRPC); - } - if (len > 0) - nfsm_adv(nfsm_rndup(len)); - nd->nd_credflavor = RPCAUTH_UNIX; - } else { - nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED); - nd->nd_procnum = NFSPROC_NOOP; - return (0); - } - - nd->nd_md = md; - nd->nd_dpos = dpos; - return (0); -nfsmout: - return (error); -} - -/* - * 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. - */ -int -nfsrv_rcv(struct socket *so, void *arg, int waitflag) -{ - struct nfssvc_sock *slp = (struct nfssvc_sock *)arg; - struct mbuf *m; - struct mbuf *mp; - struct sockaddr *nam; - struct uio auio; - int flags, error; - - NFSD_UNLOCK_ASSERT(); - - /* XXXRW: Unlocked read. */ - if ((slp->ns_flag & SLP_VALID) == 0) - return (SU_OK); - - /* - * We can't do this in the context of a socket callback - * because we're called with locks held. - * XXX: SMP - */ - if (waitflag == M_DONTWAIT) { - NFSD_LOCK(); - slp->ns_flag |= SLP_NEEDQ; - goto dorecs; - } - - - NFSD_LOCK(); - auio.uio_td = 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) != NULL && - waitflag == M_DONTWAIT) { - slp->ns_flag |= SLP_NEEDQ; - goto dorecs; - } - - /* - * Do soreceive(). - */ - auio.uio_resid = 1000000000; - flags = MSG_DONTWAIT; - NFSD_UNLOCK(); - error = soreceive(so, &nam, &auio, &mp, NULL, &flags); - NFSD_LOCK(); - if (error || mp == NULL) { - 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; - NFSD_UNLOCK(); - error = soreceive(so, &nam, &auio, &mp, NULL, &flags); - if (mp) { - struct nfsrv_rec *rec; - rec = malloc(sizeof(struct nfsrv_rec), - M_NFSRVDESC, - waitflag == M_DONTWAIT ? M_NOWAIT : M_WAITOK); - if (!rec) { - if (nam) - free(nam, M_SONAME); - m_freem(mp); - NFSD_LOCK(); - continue; - } - nfs_realign(&mp, 10 * NFSX_UNSIGNED); - NFSD_LOCK(); - rec->nr_address = nam; - rec->nr_packet = mp; - STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); - } else - NFSD_LOCK(); - 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) != NULL || - (slp->ns_flag & (SLP_NEEDQ | SLP_DISCONN)))) - nfsrv_wakenfsd(slp); - NFSD_UNLOCK(); - return (SU_OK); -} - -/* - * 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(struct nfssvc_sock *slp, int waitflag) -{ - struct mbuf *m, **mpp; - char *cp1, *cp2; - int len; - struct mbuf *om, *m2, *recm; - u_int32_t recmark; - - NFSD_LOCK_ASSERT(); - - 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_MAXPACKET || slp->ns_reclen <= 0) { - slp->ns_flag &= ~SLP_GETSTREAM; - return (EPERM); - } - } - - /* - * Now get the record part. - * - * Note that slp->ns_reclen may be 0. Linux sometimes - * generates 0-length RPCs. - */ - recm = NULL; - if (slp->ns_cc == slp->ns_reclen) { - recm = slp->ns_raw; - slp->ns_raw = slp->ns_rawend = NULL; - slp->ns_cc = slp->ns_reclen = 0; - } else if (slp->ns_cc > slp->ns_reclen) { - len = 0; - m = slp->ns_raw; - om = NULL; - - while (len < slp->ns_reclen) { - if ((len + m->m_len) > slp->ns_reclen) { - NFSD_UNLOCK(); - m2 = m_copym(m, 0, slp->ns_reclen - len, - waitflag); - NFSD_LOCK(); - 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 = NULL; - } 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; - NFSD_UNLOCK(); - rec = malloc(sizeof(struct nfsrv_rec), M_NFSRVDESC, - waitflag == M_DONTWAIT ? M_NOWAIT : M_WAITOK); - if (rec) { - nfs_realign(&slp->ns_frag, 10 * NFSX_UNSIGNED); - rec->nr_address = NULL; - rec->nr_packet = slp->ns_frag; - NFSD_LOCK(); - STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link); - } else { - NFSD_LOCK(); - } - if (!rec) { - m_freem(slp->ns_frag); - } - slp->ns_frag = NULL; - } - } -} - -/* - * Parse an RPC header. - */ -int -nfsrv_dorec(struct nfssvc_sock *slp, struct nfsd *nfsd, - struct nfsrv_descript **ndp) -{ - struct nfsrv_rec *rec; - struct mbuf *m; - struct sockaddr *nam; - struct nfsrv_descript *nd; - int error; - - NFSD_LOCK_ASSERT(); - - *ndp = NULL; - if ((slp->ns_flag & SLP_VALID) == 0 || - STAILQ_FIRST(&slp->ns_rec) == NULL) - return (ENOBUFS); - rec = STAILQ_FIRST(&slp->ns_rec); - KASSERT(rec->nr_packet != NULL, ("nfsrv_dorec: missing mbuf")); - STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link); - nam = rec->nr_address; - m = rec->nr_packet; - free(rec, M_NFSRVDESC); - NFSD_UNLOCK(); - nd = malloc(sizeof (struct nfsrv_descript), - M_NFSRVDESC, M_WAITOK); - nd->nd_cr = crget(); - prison_hold(&prison0); - nd->nd_cr->cr_prison = &prison0; - NFSD_LOCK(); - 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) { - if (nam) { - free(nam, M_SONAME); - } - if (nd->nd_cr != NULL) - crfree(nd->nd_cr); - free((caddr_t)nd, M_NFSRVDESC); - return (error); - } - *ndp = nd; - nfsd->nfsd_nd = nd; - return (0); -} - -/* - * Search for a sleeping nfsd and wake it up. - * SIDE EFFECT: If none found, set NFSD_CHECKSLP flag, so that one of the - * running nfsds will go look for the work in the nfssvc_sock list. - */ -void -nfsrv_wakenfsd(struct nfssvc_sock *slp) -{ - struct nfsd *nd; - - NFSD_LOCK_ASSERT(); - - if ((slp->ns_flag & SLP_VALID) == 0) - return; - TAILQ_FOREACH(nd, &nfsd_head, nfsd_chain) { - if (nd->nfsd_flag & NFSD_WAITING) { - nd->nfsd_flag &= ~NFSD_WAITING; - if (nd->nfsd_slp) - panic("nfsd wakeup"); - slp->ns_sref++; - nd->nfsd_slp = slp; - wakeup(nd); - return; - } - } - slp->ns_flag |= SLP_DOREC; - nfsd_head_flag |= NFSD_CHECKSLP; -} - -/* - * This is the nfs send routine. - * For the server side: - * - return EINTR or ERESTART if interrupted by a signal - * - return EPIPE if a connection is lost for connection based sockets (TCP...) - * - do any cleanup required by recoverable socket errors (?) - */ -int -nfsrv_send(struct socket *so, struct sockaddr *nam, struct mbuf *top) -{ - struct sockaddr *sendnam; - int error, soflags, flags; - - NFSD_UNLOCK_ASSERT(); - - soflags = so->so_proto->pr_flags; - if ((soflags & PR_CONNREQUIRED) || (so->so_state & SS_ISCONNECTED)) - sendnam = NULL; - else - sendnam = nam; - if (so->so_type == SOCK_SEQPACKET) - flags = MSG_EOR; - else - flags = 0; - - error = sosend(so, sendnam, 0, top, 0, flags, curthread/*XXX*/); - if (error == ENOBUFS && so->so_type == SOCK_DGRAM) - error = 0; - - if (error) { - log(LOG_INFO, "nfsd send error %d\n", error); - - /* - * Handle any recoverable (soft) socket errors here. (?) - */ - if (error != EINTR && error != ERESTART && - error != EWOULDBLOCK && error != EPIPE) - error = 0; - } - return (error); -} - -/* - * NFS server timer routine. - */ -void -nfsrv_timer(void *arg) -{ - struct nfssvc_sock *slp; - u_quad_t cur_usec; - - NFSD_LOCK(); - /* - * Scan the write gathering queues for writes that need to be - * completed now. - */ - cur_usec = nfs_curusec(); - TAILQ_FOREACH(slp, &nfssvc_sockhead, ns_chain) { - if (LIST_FIRST(&slp->ns_tq) && - LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec) - nfsrv_wakenfsd(slp); - } - NFSD_UNLOCK(); - callout_reset(&nfsrv_callout, nfsrv_ticks, nfsrv_timer, NULL); -} - -#endif /* NFS_LEGACYRPC */ diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c index 87fda28..ee0614b 100644 --- a/sys/nfsserver/nfs_srvsubs.c +++ b/sys/nfsserver/nfs_srvsubs.c @@ -67,7 +67,8 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_extern.h> #include <vm/uma.h> -#include <nfs/rpcv2.h> +#include <rpc/rpc.h> + #include <nfs/nfsproto.h> #include <nfsserver/nfs.h> #include <nfs/xdr_subs.h> @@ -80,10 +81,7 @@ __FBSDID("$FreeBSD$"); * This is kinda hokey, but may save a little time doing byte swaps */ u_int32_t nfsrv_nfs_xdrneg1; -u_int32_t nfsrv_rpc_call, nfsrv_rpc_vers, nfsrv_rpc_reply, - nfsrv_rpc_msgdenied, nfsrv_rpc_autherr, - nfsrv_rpc_mismatch, nfsrv_rpc_auth_unix, nfsrv_rpc_msgaccepted; -u_int32_t nfsrv_nfs_prog, nfsrv_nfs_true, nfsrv_nfs_false; +u_int32_t nfsrv_nfs_true, nfsrv_nfs_false; /* And other global data */ static const nfstype nfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, @@ -93,13 +91,6 @@ static const nfstype nfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, int nfsrv_ticks; -#ifdef NFS_LEGACYRPC -struct nfssvc_sockhead nfssvc_sockhead; -int nfssvc_sockhead_flag; -struct nfsd_head nfsd_head; -int nfsd_head_flag; -#endif - struct mtx nfsd_mtx; /* @@ -528,15 +519,6 @@ nfsrv_modevent(module_t mod, int type, void *data) switch (type) { case MOD_LOAD: mtx_init(&nfsd_mtx, "nfsd_mtx", NULL, MTX_DEF); - nfsrv_rpc_vers = txdr_unsigned(RPC_VER2); - nfsrv_rpc_call = txdr_unsigned(RPC_CALL); - nfsrv_rpc_reply = txdr_unsigned(RPC_REPLY); - nfsrv_rpc_msgdenied = txdr_unsigned(RPC_MSGDENIED); - nfsrv_rpc_msgaccepted = txdr_unsigned(RPC_MSGACCEPTED); - nfsrv_rpc_mismatch = txdr_unsigned(RPC_MISMATCH); - nfsrv_rpc_autherr = txdr_unsigned(RPC_AUTHERR); - nfsrv_rpc_auth_unix = txdr_unsigned(RPCAUTH_UNIX); - nfsrv_nfs_prog = txdr_unsigned(NFS_PROG); nfsrv_nfs_true = txdr_unsigned(TRUE); nfsrv_nfs_false = txdr_unsigned(FALSE); nfsrv_nfs_xdrneg1 = txdr_unsigned(-1); @@ -544,18 +526,9 @@ nfsrv_modevent(module_t mod, int type, void *data) if (nfsrv_ticks < 1) nfsrv_ticks = 1; -#ifdef NFS_LEGACYRPC - nfsrv_initcache(); /* Init the server request cache */ NFSD_LOCK(); nfsrv_init(0); /* Init server data structures */ - callout_init(&nfsrv_callout, CALLOUT_MPSAFE); NFSD_UNLOCK(); - nfsrv_timer(0); -#else - NFSD_LOCK(); - nfsrv_init(0); /* Init server data structures */ - NFSD_UNLOCK(); -#endif nfsd_call_nfsserver = nfssvc_nfsserver; break; @@ -568,9 +541,6 @@ nfsrv_modevent(module_t mod, int type, void *data) nfsd_call_nfsserver = NULL; callout_drain(&nfsrv_callout); -#ifdef NFS_LEGACYRPC - nfsrv_destroycache(); /* Free the server request cache */ -#endif mtx_destroy(&nfsd_mtx); break; default: @@ -589,9 +559,7 @@ DECLARE_MODULE(nfsserver, nfsserver_mod, SI_SUB_VFS, SI_ORDER_ANY); /* So that loader and kldload(2) can find us, wherever we are.. */ MODULE_VERSION(nfsserver, 1); MODULE_DEPEND(nfsserver, nfssvc, 1, 1, 1); -#ifndef NFS_LEGACYRPC MODULE_DEPEND(nfsserver, krpc, 1, 1, 1); -#endif /* * Set up nameidata for a lookup() call and do it. @@ -1128,7 +1096,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp, * old mountd that doesn't pass in a secflavor list. */ numsecflavors = 1; - authsys = RPCAUTH_UNIX; + authsys = AUTH_SYS; secflavors = &authsys; } credflavor = nfsd->nd_credflavor; @@ -1221,52 +1189,6 @@ nfs_ispublicfh(fhandle_t *fhp) return (TRUE); } -#ifdef NFS_LEGACYRPC - -/* - * This function compares two net addresses by family and returns TRUE - * if they are the same host. - * If there is any doubt, return FALSE. - * The AF_INET family is handled as a special case so that address mbufs - * don't need to be saved to store "struct in_addr", which is only 4 bytes. - */ -int -netaddr_match(int family, union nethostaddr *haddr, struct sockaddr *nam) -{ - struct sockaddr_in *inetaddr; - - NFSD_LOCK_DONTCARE(); - - switch (family) { - case AF_INET: - inetaddr = (struct sockaddr_in *)nam; - if (inetaddr->sin_family == AF_INET && - inetaddr->sin_addr.s_addr == haddr->had_inetaddr) - return (1); - break; -#ifdef INET6 - case AF_INET6: - { - register struct sockaddr_in6 *inet6addr1, *inet6addr2; - - inet6addr1 = (struct sockaddr_in6 *)nam; - inet6addr2 = (struct sockaddr_in6 *)haddr->had_nam; - /* XXX - should test sin6_scope_id ? */ - if (inet6addr1->sin6_family == AF_INET6 && - IN6_ARE_ADDR_EQUAL(&inet6addr1->sin6_addr, - &inet6addr2->sin6_addr)) - return (1); - break; - } -#endif - default: - break; - }; - return (0); -} - -#endif - /* * Map errnos to NFS error numbers. For Version 3 also filter out error * numbers not specified for the associated procedure. diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c deleted file mode 100644 index 29c9643..0000000 --- a/sys/nfsserver/nfs_syscalls.c +++ /dev/null @@ -1,723 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_inet6.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/kernel.h> -#include <sys/sysctl.h> -#include <sys/file.h> -#include <sys/filedesc.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/priv.h> -#include <sys/proc.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/domain.h> -#include <sys/protosw.h> -#include <sys/namei.h> -#include <sys/fcntl.h> -#include <sys/lockf.h> - -#include <netinet/in.h> -#include <netinet/tcp.h> -#ifdef INET6 -#include <net/if.h> -#include <netinet6/in6_var.h> -#endif -#include <nfs/xdr_subs.h> -#include <nfs/rpcv2.h> -#include <nfs/nfsproto.h> -#include <nfsserver/nfs.h> -#include <nfsserver/nfsm_subs.h> -#include <nfsserver/nfsrvcache.h> - -#include <security/audit/audit.h> - -#ifdef NFS_LEGACYRPC - -static MALLOC_DEFINE(M_NFSSVC, "nfss_srvsock", "Nfs server structure"); - -MALLOC_DEFINE(M_NFSRVDESC, "nfss_srvdesc", "NFS server socket descriptor"); -MALLOC_DEFINE(M_NFSD, "nfss_daemon", "Nfs server daemon structure"); - -#define TRUE 1 -#define FALSE 0 - -SYSCTL_DECL(_vfs_nfsrv); - -int nfsd_waiting = 0; -int nfsrv_numnfsd = 0; -static int notstarted = 1; - -static int nfs_privport = 0; -SYSCTL_INT(_vfs_nfsrv, NFS_NFSPRIVPORT, nfs_privport, CTLFLAG_RW, - &nfs_privport, 0, - "Only allow clients using a privileged port"); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay, CTLFLAG_RW, - &nfsrvw_procrastinate, 0, - "Delay value for write gathering"); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, - &nfsrvw_procrastinate_v3, 0, - "Delay in seconds for NFSv3 write gathering"); - -static int nfssvc_addsock(struct file *, struct sockaddr *); -static void nfsrv_zapsock(struct nfssvc_sock *slp); -static int nfssvc_nfsd(void); - -extern u_long sb_max_adj; - -/* - * NFS server system calls - */ - -/* - * This is now called from nfssvc() in nfs/nfs_nfssvc.c. - */ -/* - * Nfs server psuedo system call for the nfsd's - * Based on the flag value it either: - * - adds a socket to the selection list - * - remains in the kernel as an nfsd - * - remains in the kernel as an nfsiod - * For INET6 we suppose that nfsd provides only IN6P_IPV6_V6ONLY sockets - * and that mountd provides - * - sockaddr with no IPv4-mapped addresses - * - mask for both INET and INET6 families if there is IPv4-mapped overlap - */ -int -nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap) -{ - struct file *fp; - struct sockaddr *nam; - struct nfsd_addsock_args nfsdarg; - int error; - - NFSD_LOCK(); - while (nfssvc_sockhead_flag & SLP_INIT) { - nfssvc_sockhead_flag |= SLP_WANTINIT; - (void) msleep(&nfssvc_sockhead, &nfsd_mtx, PSOCK, - "nfsd init", 0); - } - NFSD_UNLOCK(); - if (uap->flag & NFSSVC_ADDSOCK) { - error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg)); - if (error) - return (error); - if ((error = fget(td, nfsdarg.sock, &fp)) != 0) - return (error); - if (fp->f_type != DTYPE_SOCKET) { - fdrop(fp, td); - return (error); /* XXXRW: Should be EINVAL? */ - } - /* - * Get the client address for connected sockets. - */ - if (nfsdarg.name == NULL || nfsdarg.namelen == 0) - nam = NULL; - else { - error = getsockaddr(&nam, nfsdarg.name, - nfsdarg.namelen); - if (error) { - fdrop(fp, td); - return (error); - } - } - error = nfssvc_addsock(fp, nam); - fdrop(fp, td); - } else if (uap->flag & NFSSVC_OLDNFSD) { - error = nfssvc_nfsd(); - } else { - error = ENXIO; - } - return (error); -} - -/* - * Adds a socket to the list for servicing by nfsds. - */ -static int -nfssvc_addsock(struct file *fp, struct sockaddr *mynam) -{ - int siz; - struct nfssvc_sock *slp; - struct socket *so; - int error; - - so = fp->f_data; -#if 0 - /* - * XXXRW: If this code is ever enabled, there's a race when running - * MPSAFE. - */ - tslp = NULL; - /* - * Add it to the list, as required. - */ - if (so->so_proto->pr_protocol == IPPROTO_UDP) { - tslp = nfs_udpsock; - if (tslp->ns_flag & SLP_VALID) { - if (mynam != NULL) - free(mynam, M_SONAME); - return (EPERM); - } - } -#endif - siz = sb_max_adj; - error = soreserve(so, siz, siz); - if (error) { - if (mynam != NULL) - free(mynam, M_SONAME); - return (error); - } - - /* - * Set protocol specific options { for now TCP only } and - * reserve some space. For datagram sockets, this can get called - * repeatedly for the same socket, but that isn't harmful. - */ - if (so->so_type == SOCK_STREAM) { - struct sockopt sopt; - int val; - - bzero(&sopt, sizeof sopt); - sopt.sopt_dir = SOPT_SET; - sopt.sopt_level = SOL_SOCKET; - sopt.sopt_name = SO_KEEPALIVE; - sopt.sopt_val = &val; - sopt.sopt_valsize = sizeof val; - val = 1; - sosetopt(so, &sopt); - } - if (so->so_proto->pr_protocol == IPPROTO_TCP) { - struct sockopt sopt; - int val; - - bzero(&sopt, sizeof sopt); - sopt.sopt_dir = SOPT_SET; - sopt.sopt_level = IPPROTO_TCP; - sopt.sopt_name = TCP_NODELAY; - sopt.sopt_val = &val; - sopt.sopt_valsize = sizeof val; - val = 1; - sosetopt(so, &sopt); - } - SOCKBUF_LOCK(&so->so_rcv); - so->so_rcv.sb_flags &= ~SB_NOINTR; - so->so_rcv.sb_timeo = 0; - SOCKBUF_UNLOCK(&so->so_rcv); - SOCKBUF_LOCK(&so->so_snd); - so->so_snd.sb_flags &= ~SB_NOINTR; - so->so_snd.sb_timeo = 0; - SOCKBUF_UNLOCK(&so->so_snd); - - slp = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, - M_WAITOK | M_ZERO); - STAILQ_INIT(&slp->ns_rec); - NFSD_LOCK(); - TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain); - - slp->ns_so = so; - slp->ns_nam = mynam; - fhold(fp); - slp->ns_fp = fp; - NFSD_UNLOCK(); - SOCKBUF_LOCK(&so->so_rcv); - soupcall_set(so, SO_RCV, nfsrv_rcv, slp); - SOCKBUF_UNLOCK(&so->so_rcv); - NFSD_LOCK(); - slp->ns_flag = (SLP_VALID | SLP_NEEDQ); - nfsrv_wakenfsd(slp); - NFSD_UNLOCK(); - return (0); -} - -/* - * Called by nfssvc() for nfsds. Just loops around servicing rpc requests - * until it is killed by a signal. - */ -static int -nfssvc_nfsd() -{ - int siz; - struct nfssvc_sock *slp; - struct nfsd *nfsd; - struct nfsrv_descript *nd = NULL; - struct mbuf *m, *mreq; - int error = 0, cacherep, s, sotype, writes_todo; - int procrastinate; - u_quad_t cur_usec; - -#ifndef nolint - cacherep = RC_DOIT; - writes_todo = 0; -#endif - nfsd = (struct nfsd *) - malloc(sizeof (struct nfsd), M_NFSD, M_WAITOK | M_ZERO); - s = splnet(); - NFSD_LOCK(); - - TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain); - nfsrv_numnfsd++; - - /* - * Loop getting rpc requests until SIGKILL. - */ - for (;;) { - if ((nfsd->nfsd_flag & NFSD_REQINPROG) == 0) { - while (nfsd->nfsd_slp == NULL && - (nfsd_head_flag & NFSD_CHECKSLP) == 0) { - nfsd->nfsd_flag |= NFSD_WAITING; - nfsd_waiting++; - error = msleep(nfsd, &nfsd_mtx, - PSOCK | PCATCH, "-", 0); - nfsd_waiting--; - if (error) - goto done; - } - if (nfsd->nfsd_slp == NULL && - (nfsd_head_flag & NFSD_CHECKSLP) != 0) { - TAILQ_FOREACH(slp, &nfssvc_sockhead, ns_chain) { - if ((slp->ns_flag & (SLP_VALID | SLP_DOREC)) - == (SLP_VALID | SLP_DOREC)) { - slp->ns_flag &= ~SLP_DOREC; - slp->ns_sref++; - nfsd->nfsd_slp = slp; - break; - } - } - if (slp == NULL) - nfsd_head_flag &= ~NFSD_CHECKSLP; - } - if ((slp = nfsd->nfsd_slp) == NULL) - continue; - if (slp->ns_flag & SLP_VALID) { - if (slp->ns_flag & SLP_DISCONN) - nfsrv_zapsock(slp); - else if (slp->ns_flag & SLP_NEEDQ) { - slp->ns_flag &= ~SLP_NEEDQ; - (void) nfs_slplock(slp, 1); - NFSD_UNLOCK(); - nfsrv_rcv(slp->ns_so, (caddr_t)slp, - M_WAIT); - NFSD_LOCK(); - nfs_slpunlock(slp); - } - error = nfsrv_dorec(slp, nfsd, &nd); - cur_usec = nfs_curusec(); - if (error && LIST_FIRST(&slp->ns_tq) && - LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec) { - error = 0; - cacherep = RC_DOIT; - writes_todo = 1; - } else - writes_todo = 0; - nfsd->nfsd_flag |= NFSD_REQINPROG; - } - } else { - error = 0; - slp = nfsd->nfsd_slp; - } - if (error || (slp->ns_flag & SLP_VALID) == 0) { - if (nd) { - if (nd->nd_cr != NULL) - crfree(nd->nd_cr); - free((caddr_t)nd, M_NFSRVDESC); - nd = NULL; - } - nfsd->nfsd_slp = NULL; - nfsd->nfsd_flag &= ~NFSD_REQINPROG; - nfsrv_slpderef(slp); - continue; - } - splx(s); - sotype = slp->ns_so->so_type; - if (nd) { - getmicrotime(&nd->nd_starttime); - if (nd->nd_nam2) - nd->nd_nam = nd->nd_nam2; - else - nd->nd_nam = slp->ns_nam; - - /* - * Check to see if authorization is needed. - */ - cacherep = nfsrv_getcache(nd, &mreq); - - if (nfs_privport) { - /* Check if source port is privileged */ - u_short port; - struct sockaddr *nam = nd->nd_nam; - struct sockaddr_in *sin; - - sin = (struct sockaddr_in *)nam; - /* - * INET/INET6 - same code: - * sin_port and sin6_port are at same offset - */ - port = ntohs(sin->sin_port); - if (port >= IPPORT_RESERVED && - nd->nd_procnum != NFSPROC_NULL) { -#ifdef INET6 - char b6[INET6_ADDRSTRLEN]; -#if defined(KLD_MODULE) - /* Do not use ip6_sprintf: the nfs module should work without INET6. */ -#define ip6_sprintf(buf, a) \ - (sprintf((buf), "%x:%x:%x:%x:%x:%x:%x:%x", \ - (a)->s6_addr16[0], (a)->s6_addr16[1], \ - (a)->s6_addr16[2], (a)->s6_addr16[3], \ - (a)->s6_addr16[4], (a)->s6_addr16[5], \ - (a)->s6_addr16[6], (a)->s6_addr16[7]), \ - (buf)) -#endif -#endif - nd->nd_procnum = NFSPROC_NOOP; - nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK); - cacherep = RC_DOIT; - printf("NFS request from unprivileged port (%s:%d)\n", -#ifdef INET6 - sin->sin_family == AF_INET6 ? - ip6_sprintf(b6, &satosin6(sin)->sin6_addr) : -#if defined(KLD_MODULE) -#undef ip6_sprintf -#endif -#endif - inet_ntoa(sin->sin_addr), port); - } - } - - } - - /* - * Loop to get all the write rpc relies that have been - * gathered together. - */ - do { - switch (cacherep) { - case RC_DOIT: - if (nd && (nd->nd_flag & ND_NFSV3)) - procrastinate = nfsrvw_procrastinate_v3; - else - procrastinate = nfsrvw_procrastinate; - NFSD_UNLOCK(); - if (writes_todo || (!(nd->nd_flag & ND_NFSV3) && - nd->nd_procnum == NFSPROC_WRITE && - procrastinate > 0 && !notstarted)) - error = nfsrv_writegather(&nd, slp, &mreq); - else - error = (*(nfsrv3_procs[nd->nd_procnum]))(nd, - slp, &mreq); - NFSD_LOCK(); - if (mreq == NULL) - break; - if (error != 0 && error != NFSERR_RETVOID) { - nfsrvstats.srv_errs++; - nfsrv_updatecache(nd, FALSE, mreq); - if (nd->nd_nam2) - free(nd->nd_nam2, M_SONAME); - break; - } - nfsrvstats.srvrpccnt[nd->nd_procnum]++; - nfsrv_updatecache(nd, TRUE, mreq); - nd->nd_mrep = NULL; - /* FALLTHROUGH */ - case RC_REPLY: - NFSD_UNLOCK(); - siz = m_length(mreq, NULL); - if (siz <= 0 || siz > NFS_MAXPACKET) { - printf("mbuf siz=%d\n",siz); - panic("Bad nfs svc reply"); - } - m = mreq; - m->m_pkthdr.len = siz; - m->m_pkthdr.rcvif = NULL; - /* - * For stream protocols, prepend a Sun RPC - * Record Mark. - */ - if (sotype == SOCK_STREAM) { - M_PREPEND(m, NFSX_UNSIGNED, M_WAIT); - *mtod(m, u_int32_t *) = htonl(0x80000000 | siz); - } - NFSD_LOCK(); - if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED) - (void) nfs_slplock(slp, 1); - if (slp->ns_flag & SLP_VALID) { - NFSD_UNLOCK(); - error = nfsrv_send(slp->ns_so, nd->nd_nam2, m); - NFSD_LOCK(); - } else { - error = EPIPE; - m_freem(m); - } - if (nd->nd_nam2) - free(nd->nd_nam2, M_SONAME); - if (nd->nd_mrep) - m_freem(nd->nd_mrep); - if (error == EPIPE) - nfsrv_zapsock(slp); - if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED) - nfs_slpunlock(slp); - if (error == EINTR || error == ERESTART) { - if (nd->nd_cr != NULL) - crfree(nd->nd_cr); - free((caddr_t)nd, M_NFSRVDESC); - nfsrv_slpderef(slp); - s = splnet(); - goto done; - } - break; - case RC_DROPIT: - m_freem(nd->nd_mrep); - if (nd->nd_nam2) - free(nd->nd_nam2, M_SONAME); - break; - }; - if (nd) { - if (nd->nd_cr != NULL) - crfree(nd->nd_cr); - free((caddr_t)nd, M_NFSRVDESC); - nd = NULL; - } - - /* - * Check to see if there are outstanding writes that - * need to be serviced. - */ - cur_usec = nfs_curusec(); - s = splsoftclock(); - if (LIST_FIRST(&slp->ns_tq) && - LIST_FIRST(&slp->ns_tq)->nd_time <= cur_usec) { - cacherep = RC_DOIT; - writes_todo = 1; - } else - writes_todo = 0; - splx(s); - } while (writes_todo); - s = splnet(); - if (nfsrv_dorec(slp, nfsd, &nd)) { - nfsd->nfsd_flag &= ~NFSD_REQINPROG; - nfsd->nfsd_slp = NULL; - nfsrv_slpderef(slp); - } - mtx_assert(&Giant, MA_NOTOWNED); - } -done: - mtx_assert(&Giant, MA_NOTOWNED); - TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain); - splx(s); - free((caddr_t)nfsd, M_NFSD); - if (--nfsrv_numnfsd == 0) - nfsrv_init(TRUE); /* Reinitialize everything */ - NFSD_UNLOCK(); - 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(struct nfssvc_sock *slp) -{ - struct nfsrv_descript *nwp, *nnwp; - struct socket *so; - struct file *fp; - struct nfsrv_rec *rec; - int s; - - NFSD_LOCK_ASSERT(); - - /* - * XXXRW: By clearing all flags, other threads/etc should ignore - * this slp and we can safely release nfsd_mtx so we can clean - * up the slp safely. - */ - slp->ns_flag &= ~SLP_ALLFLAGS; - fp = slp->ns_fp; - if (fp) { - NFSD_UNLOCK(); - slp->ns_fp = NULL; - so = slp->ns_so; - SOCKBUF_LOCK(&so->so_rcv); - soupcall_clear(so, SO_RCV); - SOCKBUF_UNLOCK(&so->so_rcv); - soshutdown(so, SHUT_RDWR); - closef(fp, NULL); - NFSD_LOCK(); - if (slp->ns_nam) - free(slp->ns_nam, M_SONAME); - m_freem(slp->ns_raw); - while ((rec = STAILQ_FIRST(&slp->ns_rec)) != NULL) { - 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); - } - s = splsoftclock(); - for (nwp = LIST_FIRST(&slp->ns_tq); nwp; nwp = nnwp) { - nnwp = LIST_NEXT(nwp, nd_tq); - LIST_REMOVE(nwp, nd_tq); - if (nwp->nd_cr != NULL) - crfree(nwp->nd_cr); - 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(struct nfssvc_sock *slp) -{ - - NFSD_LOCK_ASSERT(); - - if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) { - TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); - free((caddr_t)slp, M_NFSSVC); - } -} - -/* - * Lock a socket against others. - * - * XXXRW: Wait argument is always 1 in the caller. Replace with a real - * sleep lock? - */ -int -nfs_slplock(struct nfssvc_sock *slp, int wait) -{ - int *statep = &slp->ns_solock; - - NFSD_LOCK_ASSERT(); - - if (!wait && (*statep & NFSRV_SNDLOCK)) - return(0); /* already locked, fail */ - while (*statep & NFSRV_SNDLOCK) { - *statep |= NFSRV_WANTSND; - (void) msleep(statep, &nfsd_mtx, PZERO - 1, "nfsslplck", 0); - } - *statep |= NFSRV_SNDLOCK; - return (1); -} - -/* - * Unlock the stream socket for others. - */ -void -nfs_slpunlock(struct nfssvc_sock *slp) -{ - int *statep = &slp->ns_solock; - - NFSD_LOCK_ASSERT(); - - if ((*statep & NFSRV_SNDLOCK) == 0) - panic("nfs slpunlock"); - *statep &= ~NFSRV_SNDLOCK; - if (*statep & NFSRV_WANTSND) { - *statep &= ~NFSRV_WANTSND; - wakeup(statep); - } -} - -/* - * Initialize the data structures for the server. - * Handshake with any new nfsds starting up to avoid any chance of - * corruption. - */ -void -nfsrv_init(int terminating) -{ - struct nfssvc_sock *slp, *nslp; - - NFSD_LOCK_ASSERT(); - - if (nfssvc_sockhead_flag & SLP_INIT) - panic("nfsd init"); - nfssvc_sockhead_flag |= SLP_INIT; - if (terminating) { - TAILQ_FOREACH_SAFE(slp, &nfssvc_sockhead, ns_chain, nslp) { - 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(&nfssvc_sockhead); - } - - TAILQ_INIT(&nfsd_head); - nfsd_head_flag &= ~NFSD_CHECKSLP; - -#if 0 - nfs_udpsock = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK | M_ZERO); - STAILQ_INIT(&nfs_udpsock->ns_rec); - TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain); - - nfs_cltpsock = (struct nfssvc_sock *) - malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK | M_ZERO); - STAILQ_INIT(&nfs_cltpsock->ns_rec); - TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain); -#endif -} - -#endif /* NFS_LEGACYRPC */ diff --git a/sys/nfsserver/nfsrvcache.h b/sys/nfsserver/nfsrvcache.h index 9c527e9..d4e31b1 100644 --- a/sys/nfsserver/nfsrvcache.h +++ b/sys/nfsserver/nfsrvcache.h @@ -44,46 +44,4 @@ #define NFSRVCACHE_MAX_SIZE 2048 #define NFSRVCACHE_MIN_SIZE 64 -#ifdef NFS_LEGACYRPC - -struct nfsrvcache { - TAILQ_ENTRY(nfsrvcache) rc_lru; /* LRU chain */ - LIST_ENTRY(nfsrvcache) rc_hash; /* Hash chain */ - u_int32_t rc_xid; /* rpc id number */ - union { - struct mbuf *ru_repmb; /* Reply mbuf list OR */ - int ru_repstat; /* Reply status */ - } rc_un; - union nethostaddr rc_haddr; /* Host address */ - u_int32_t rc_proc; /* rpc proc number */ - u_char rc_state; /* Current state of request */ - u_char rc_flag; /* Flag bits */ -}; - -#define rc_reply rc_un.ru_repmb -#define rc_status rc_un.ru_repstat -#define rc_inetaddr rc_haddr.had_inetaddr -#define rc_nam rc_haddr.had_nam - -/* Cache entry states */ -#define RC_UNUSED 0 -#define RC_INPROG 1 -#define RC_DONE 2 - -/* Return values */ -#define RC_DROPIT 0 -#define RC_REPLY 1 -#define RC_DOIT 2 - -/* Flag bits */ -#define RC_LOCKED 0x01 -#define RC_WANTED 0x02 -#define RC_REPSTATUS 0x04 -#define RC_REPMBUF 0x08 -/* free 0x10 */ -#define RC_INETADDR 0x20 -#define RC_NAM 0x40 - -#endif - #endif |