summaryrefslogtreecommitdiffstats
path: root/sys/nfsserver
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2009-06-30 19:03:27 +0000
committerdfr <dfr@FreeBSD.org>2009-06-30 19:03:27 +0000
commit5d248bb05f33623d905b8b5a72d90e459d23be96 (patch)
treeb34567acfe860cb1978c433954c8376efa8a9fbb /sys/nfsserver
parent92b2f1511851bf5a137742d90131b79d0ff4c1ff (diff)
downloadFreeBSD-src-5d248bb05f33623d905b8b5a72d90e459d23be96.zip
FreeBSD-src-5d248bb05f33623d905b8b5a72d90e459d23be96.tar.gz
Remove the old kernel RPC implementation and the NFS_LEGACYRPC option.
Approved by: re
Diffstat (limited to 'sys/nfsserver')
-rw-r--r--sys/nfsserver/nfs.h133
-rw-r--r--sys/nfsserver/nfs_fha.c5
-rw-r--r--sys/nfsserver/nfs_serv.c424
-rw-r--r--sys/nfsserver/nfs_srvcache.c391
-rw-r--r--sys/nfsserver/nfs_srvkrpc.c5
-rw-r--r--sys/nfsserver/nfs_srvsock.c818
-rw-r--r--sys/nfsserver/nfs_srvsubs.c86
-rw-r--r--sys/nfsserver/nfs_syscalls.c723
-rw-r--r--sys/nfsserver/nfsrvcache.h42
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
OpenPOWER on IntegriCloud