diff options
author | 2009-08-10 09:38:44 +0000 | |
---|---|---|
committer | 2009-08-10 09:38:44 +0000 | |
commit | a57b0483d0bd619fde1f8dc8ae63cd8af79f4254 (patch) | |
tree | fecb595bf04e57bb463c662b58fa260433e73039 | |
parent | The only caller of NFSMSIZ got changed yesterday, so remove it. (diff) | |
download | wireguard-openbsd-a57b0483d0bd619fde1f8dc8ae63cd8af79f4254.tar.xz wireguard-openbsd-a57b0483d0bd619fde1f8dc8ae63cd8af79f4254.zip |
Remove the v2 writegather code. It did help alot back in the 80s
but extensive performance benchmarking done by myself and jasper@
has shown that it doesn't help, at all - even on vaxens and in some
cases it makes things significantly slower.
"this excites me sexually" jetpack@
Tested by jasper@.
OK blambert@
-rw-r--r-- | sys/nfs/nfs.h | 42 | ||||
-rw-r--r-- | sys/nfs/nfs_serv.c | 373 | ||||
-rw-r--r-- | sys/nfs/nfs_socket.c | 21 | ||||
-rw-r--r-- | sys/nfs/nfs_subs.c | 44 | ||||
-rw-r--r-- | sys/nfs/nfs_syscalls.c | 307 | ||||
-rw-r--r-- | sys/nfs/nfs_var.h | 7 |
6 files changed, 136 insertions, 658 deletions
diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h index 0e1b483fd81..187112bf705 100644 --- a/sys/nfs/nfs.h +++ b/sys/nfs/nfs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs.h,v 1.45 2009/07/14 16:40:29 thib Exp $ */ +/* $OpenBSD: nfs.h,v 1.46 2009/08/10 09:38:44 thib Exp $ */ /* $NetBSD: nfs.h,v 1.10.4.1 1996/05/27 11:23:56 fvdl Exp $ */ /* @@ -56,8 +56,6 @@ #define NFS_DEFRAHEAD 1 /* Def. read ahead # blocks */ #define NFS_MAXRAHEAD 4 /* Max. read ahead # blocks */ #define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runable */ -#define NFS_MAXGATHERDELAY 100 /* Max. write gather delay (msec) */ -#define NFS_GATHERDELAY 10 /* Default write gather delay (msec) */ /* * Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with @@ -265,15 +263,6 @@ enum nfs_rto_timers { #define NFS_INITRTT (NFS_HZ << 3) -/* - * A list of nfssvc_sock structures is maintained with all the sockets - * that require service by the nfsd. - */ -#ifndef NFS_WDELAYHASHSIZ -#define NFS_WDELAYHASHSIZ 16 /* and with this */ -#endif -#define NWDELAYHASH(sock, f) \ - (&(sock)->ns_wdelayhashtbl[(*((u_int32_t *)(f))) % NFS_WDELAYHASHSIZ]) #define NFSNOHASH(fhsum) \ (&nfsnodehashtbl[(fhsum) & nfsnodehash]) @@ -300,9 +289,6 @@ struct nfssvc_sock { int ns_cc; /* actual chars queued */ int ns_reclen; /* length of first queued record */ u_int32_t ns_sref; /* # of refs to this struct */ - LIST_HEAD(, nfsrv_descript) ns_tq; /* Write gather lists */ - LIST_HEAD(nfsrvw_delayhash, nfsrv_descript) - ns_wdelayhashtbl[NFS_WDELAYHASHSIZ]; }; /* Bits for "ns_flag" */ @@ -338,53 +324,27 @@ struct nfsd { /* * 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 { - struct timeval nd_time; /* Write deadline */ - 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 mbuf *nd_nam; /* and socket addr */ struct mbuf *nd_nam2; /* return socket addr */ caddr_t nd_dpos; /* Current dissect pos */ unsigned int 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 */ - fhandle_t nd_fh; /* File handle */ struct ucred nd_cr; /* Credentials */ }; /* Bits for "nd_flag" */ #define ND_NFSV3 0x08 -#define ND_KERBNICK 0x20 -#define ND_KERBFULL 0x40 -#define ND_KERBAUTH (ND_KERBNICK | ND_KERBFULL) extern struct pool nfsreqpl; extern TAILQ_HEAD(nfsdhead, 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)) - -#define NFSW_SAMECRED(o, n) \ - (((o)->nd_flag & ND_KERBAUTH) == ((n)->nd_flag & ND_KERBAUTH) && \ - !bcmp((caddr_t)&(o)->nd_cr, (caddr_t)&(n)->nd_cr, \ - sizeof (struct ucred))) - #endif /* _KERNEL */ #endif /* _NFS_NFS_H */ diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c index cffb7abadb4..e689148102d 100644 --- a/sys/nfs/nfs_serv.c +++ b/sys/nfs/nfs_serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_serv.c,v 1.81 2009/08/09 17:35:31 blambert Exp $ */ +/* $OpenBSD: nfs_serv.c,v 1.82 2009/08/10 09:38:44 thib Exp $ */ /* $NetBSD: nfs_serv.c,v 1.34 1997/05/12 23:37:12 fvdl Exp $ */ /* @@ -88,11 +88,6 @@ extern enum vtype nv3tov_type[8]; extern struct nfsstats nfsstats; extern nfstype nfsv2_type[9]; extern nfstype nfsv3_type[9]; -int nfsrvw_procrastinate = NFS_GATHERDELAY * 1000; -struct timeval nfsrvw_procrastinate_tv = { - (NFS_GATHERDELAY * 1000) / 1000000, /* tv_sec */ - (NFS_GATHERDELAY * 1000) % 1000000 /* tv_usec */ -}; /* * nfs v3 access service @@ -867,372 +862,6 @@ bad: } /* - * 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(ndp, slp, procp, mrq) - struct nfsrv_descript **ndp; - struct nfssvc_sock *slp; - struct proc *procp; - struct mbuf **mrq; -{ - struct iovec *ivp; - struct mbuf *mp; - struct nfsrv_descript *wp, *nfsd, *nnfsd, *owp, *swp; - struct nfs_fattr *fp; - struct nfsm_info info; - int i = 0; - struct iovec *iov; - struct nfsrvw_delayhash *wpp; - struct ucred *cred; - struct vattr va, forat; - u_int32_t *tl; - int32_t t1; - int error = 0, rdonly, len = 0, forat_ret = 1; - int ioflags, aftat_ret = 1, s, adjust, zeroing; - char *cp2; - struct vnode *vp; - struct uio io, *uiop = &io; - struct timeval tv; - - *mrq = NULL; - if (*ndp) { - nfsd = *ndp; - *ndp = NULL; - info.nmi_mreq = NULL; - info.nmi_mrep = nfsd->nd_mrep; - info.nmi_md = nfsd->nd_md; - info.nmi_dpos = nfsd->nd_dpos; - cred = &nfsd->nd_cr; - info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); - LIST_INIT(&nfsd->nd_coalesce); - nfsd->nd_mreq = NULL; - nfsd->nd_stable = NFSV3WRITE_FILESYNC; - getmicrotime(&tv); - timeradd(&tv, &nfsrvw_procrastinate_tv, &nfsd->nd_time); - - /* - * Now, get the write header.. - */ - nfsm_srvmtofh(&nfsd->nd_fh); - if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED); - nfsd->nd_off = fxdr_hyper(tl); - tl += 3; - nfsd->nd_stable = fxdr_unsigned(int, *tl++); - } else { - nfsm_dissect(tl, u_int32_t *, 4 * NFSX_UNSIGNED); - nfsd->nd_off = (off_t)fxdr_unsigned(u_int32_t, *++tl); - tl += 2; - } - 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 = info.nmi_mrep; - while (mp) { - if (mp == info.nmi_md) { - zeroing = 0; - adjust = info.nmi_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) { - m_freem(info.nmi_mrep); -nfsmout: - error = EIO; - nfsm_writereply(2 * NFSX_UNSIGNED, info.nmi_v3); - if (info.nmi_v3) - nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, - &info.nmi_mb); - nfsd->nd_mreq = info.nmi_mreq; - nfsd->nd_mrep = NULL; - timerclear(&nfsd->nd_time); - } - - /* - * Add this entry to the hash and time queues. - */ - s = splsoftclock(); - owp = NULL; - wp = LIST_FIRST(&slp->ns_tq); - while (wp && timercmp(&wp->nd_time, &nfsd->nd_time, <)) { - owp = wp; - wp = LIST_NEXT(wp, nd_tq); - } - 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 (NFSW_SAMECRED(owp, nfsd)) - 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: - getmicrotime(&tv); - s = splsoftclock(); - for (nfsd = LIST_FIRST(&slp->ns_tq); nfsd != NULL; nfsd = owp) { - owp = LIST_NEXT(nfsd, nd_tq); - if (timercmp(&nfsd->nd_time, &tv, >)) - break; - if (nfsd->nd_mreq) - continue; - LIST_REMOVE(nfsd, nd_tq); - LIST_REMOVE(nfsd, nd_hash); - splx(s); - info.nmi_mrep = nfsd->nd_mrep; - nfsd->nd_mrep = NULL; - cred = &nfsd->nd_cr; - info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); - forat_ret = aftat_ret = 1; - error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, cred, slp, - nfsd->nd_nam, &rdonly); - if (!error) { - if (info.nmi_v3) - forat_ret = VOP_GETATTR(vp, &forat, cred, procp); - if (vp->v_type != VREG) { - if (info.nmi_v3) - error = EINVAL; - else - error = (vp->v_type == VDIR) ? EISDIR : EACCES; - } - } else - vp = NULL; - if (!error) { - error = nfsrv_access(vp, VWRITE, cred, rdonly, procp, 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_SYNC | IO_NODELOCKED); - uiop->uio_rw = UIO_WRITE; - uiop->uio_segflg = UIO_SYSSPACE; - uiop->uio_procp = NULL; - uiop->uio_offset = nfsd->nd_off; - uiop->uio_resid = nfsd->nd_eoff - nfsd->nd_off; - if (uiop->uio_resid > 0) { - mp = info.nmi_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 = info.nmi_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; - } - if (!error) { - error = VOP_WRITE(vp, uiop, ioflags, cred); - nfsstats.srvvop_writes++; - } - free(iov, M_TEMP); - } - m_freem(info.nmi_mrep); - if (vp) { - aftat_ret = VOP_GETATTR(vp, &va, cred, procp); - vput(vp); - } - - /* - * Loop around generating replies for all write rpcs that have - * now been completed. - */ - swp = nfsd; - do { - if (error) { - nfsm_writereply(NFSX_WCCDATA(info.nmi_v3), info.nmi_v3); - if (info.nmi_v3) { - nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, - &va, &info.nmi_mb); - } - } else { - nfsm_writereply(NFSX_PREOPATTR(info.nmi_v3) + - NFSX_POSTOPORFATTR(info.nmi_v3) + 2 * NFSX_UNSIGNED + - NFSX_WRITEVERF(info.nmi_v3), info.nmi_v3); - if (info.nmi_v3) { - nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, - &va, &info.nmi_mb); - tl = nfsm_build(&info.nmi_mb, 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. - */ - *tl++ = txdr_unsigned(boottime.tv_sec); - *tl = txdr_unsigned(boottime.tv_usec); - } else { - fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR); - nfsm_srvfattr(nfsd, &va, fp); - } - } - nfsd->nd_mreq = info.nmi_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) { - timerclear(&nfsd->nd_time); - 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(); - timerclear(&swp->nd_time); - LIST_INSERT_HEAD(&slp->ns_tq, swp, nd_tq); - splx(s); - goto loop1; - } - splx(s); - - /* - * Search for a reply to return. - */ - s = splsoftclock(); - for (nfsd = LIST_FIRST(&slp->ns_tq); nfsd != NULL; nfsd = nnfsd) { - nnfsd = LIST_NEXT(nfsd, nd_tq); - if (nfsd->nd_mreq) { - 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(). - */ -void -nfsrvw_coalesce(struct nfsrv_descript *owp, struct nfsrv_descript *nfsd) -{ - int overlap; - struct mbuf *mp; - - splsoftassert(IPL_SOFTCLOCK); - - 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); - - /* - * nfsd might hold coalesce elements! Move them to owp. - * Otherwise, requests may be lost and clients will be stuck. - */ - if (LIST_FIRST(&nfsd->nd_coalesce) != NULL) { - struct nfsrv_descript *m; - - while ((m = LIST_FIRST(&nfsd->nd_coalesce)) != NULL) { - LIST_REMOVE(m, nd_tq); - LIST_INSERT_HEAD(&owp->nd_coalesce, m, nd_tq); - } - } -} - -/* * nfs create service * now does a truncate to 0 length via. setattr if it already exists */ diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 85001370b0e..63f4c2c604d 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_socket.c,v 1.93 2009/08/04 17:12:39 thib Exp $ */ +/* $OpenBSD: nfs_socket.c,v 1.94 2009/08/10 09:38:44 thib Exp $ */ /* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */ /* @@ -1151,10 +1151,6 @@ nfs_timer(arg) struct nfsmount *nmp; int timeo; int s, error; -#ifdef NFSSERVER - struct nfssvc_sock *slp; - struct timeval tv; -#endif s = splsoftnet(); TAILQ_FOREACH(rep, &nfs_reqq, r_chain) { @@ -1240,19 +1236,6 @@ nfs_timer(arg) } } } - -#ifdef NFSSERVER - /* - * Scan the write gathering queues for writes that need to be - * completed now. - */ - getmicrotime(&tv); - TAILQ_FOREACH(slp, &nfssvc_sockhead, ns_chain) { - if (LIST_FIRST(&slp->ns_tq) && - timercmp(&LIST_FIRST(&slp->ns_tq)->nd_time, &tv, <=)) - nfsrv_wakenfsd(slp); - } -#endif /* NFSSERVER */ splx(s); timeout_add(to, nfs_ticks); } @@ -1565,8 +1548,6 @@ nfs_getreq(nd, nfsd, has_header) else tl++; nd->nd_cr.cr_ngroups = (len > NGROUPS) ? NGROUPS : len; - 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(info.nmi_mrep); diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index f7384ad0334..4446cf1e3c6 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_subs.c,v 1.99 2009/08/04 17:12:39 thib Exp $ */ +/* $OpenBSD: nfs_subs.c,v 1.100 2009/08/10 09:38:44 thib Exp $ */ /* $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $ */ /* @@ -1790,48 +1790,6 @@ nfsrv_errmap(nd, err) } /* - * Sort the group list in increasing numerical order. - * (Insertion sort by Chris Torek, who was grossed out by the bubble sort - * that used to be here.) - */ -void -nfsrvw_sort(list, num) - gid_t *list; - int num; -{ - int i, j; - gid_t v; - - /* Insertion sort. */ - for (i = 1; i < num; i++) { - v = list[i]; - /* find correct slot for value v, moving others up */ - for (j = i; --j >= 0 && v < list[j];) - list[j + 1] = list[j]; - list[j + 1] = v; - } -} - -/* - * copy credentials making sure that the result can be compared with bcmp(). - */ -void -nfsrv_setcred(incred, outcred) - struct ucred *incred, *outcred; -{ - int i; - - bzero((caddr_t)outcred, sizeof (struct ucred)); - outcred->cr_ref = 1; - outcred->cr_uid = incred->cr_uid; - outcred->cr_gid = incred->cr_gid; - outcred->cr_ngroups = incred->cr_ngroups; - for (i = 0; i < incred->cr_ngroups; i++) - outcred->cr_groups[i] = incred->cr_groups[i]; - nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups); -} - -/* * If full is non zero, set all fields, otherwise just set mode and time fields */ void diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c index 966c0ce2af1..dc0835a1876 100644 --- a/sys/nfs/nfs_syscalls.c +++ b/sys/nfs/nfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_syscalls.c,v 1.84 2009/07/20 16:49:40 thib Exp $ */ +/* $OpenBSD: nfs_syscalls.c,v 1.85 2009/08/10 09:38:44 thib Exp $ */ /* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */ /* @@ -75,8 +75,6 @@ /* Global defs. */ extern int nfs_numasync; extern struct nfsstats nfsstats; -extern int nfsrvw_procrastinate; -extern struct timeval nfsrvw_procrastinate_tv; struct nfssvc_sock *nfs_udpsock; int nfsd_waiting = 0; @@ -305,190 +303,157 @@ nfssvc_nfsd(struct nfsd *nfsd) int *solockp; struct nfsrv_descript *nd = NULL; struct mbuf *mreq; - int error = 0, cacherep, s, sotype, writes_todo; - struct timeval tv; + int error = 0, cacherep, s, sotype; cacherep = RC_DOIT; - writes_todo = 0; s = splsoftnet(); TAILQ_INSERT_TAIL(&nfsd_head, nfsd, nfsd_chain); nfs_numnfsd++; - /* - * Loop getting rpc requests until SIGKILL. - */ - for (;;) { - if ((nfsd->nfsd_flag & NFSD_REQINPROG) == 0) { - - /* attach an nfssvc_sock to nfsd */ - error = nfsrv_getslp(nfsd); - if (error) - goto done; - slp = nfsd->nfsd_slp; - - 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_sndlock(&slp->ns_solock, - NULL); - nfsrv_rcv(slp->ns_so, (caddr_t)slp, - M_WAIT); - nfs_sndunlock(&slp->ns_solock); - } - error = nfsrv_dorec(slp, nfsd, &nd); - getmicrotime(&tv); - if (error && LIST_FIRST(&slp->ns_tq) && - timercmp(&LIST_FIRST(&slp->ns_tq)->nd_time, - &tv, <=)) { - error = 0; - cacherep = RC_DOIT; - writes_todo = 1; - } else - writes_todo = 0; - nfsd->nfsd_flag |= NFSD_REQINPROG; + + /* Loop getting rpc requests until SIGKILL. */ +loop: + if (!ISSET(nfsd->nfsd_flag, NFSD_REQINPROG)) { + + /* attach an nfssvc_sock to nfsd */ + error = nfsrv_getslp(nfsd); + if (error) + goto done; + + slp = nfsd->nfsd_slp; + + if (ISSET(slp->ns_flag, SLP_VALID)) { + if (ISSET(slp->ns_flag, SLP_DISCONN)) { + nfsrv_zapsock(slp); + } else if (ISSET(slp->ns_flag, SLP_NEEDQ)) { + CLR(slp->ns_flag, SLP_NEEDQ); + nfs_sndlock(&slp->ns_solock, NULL); + nfsrv_rcv(slp->ns_so, (caddr_t)slp, M_WAIT); + nfs_sndunlock(&slp->ns_solock); } - } else { - error = 0; - slp = nfsd->nfsd_slp; + + error = nfsrv_dorec(slp, nfsd, &nd); + SET(nfsd->nfsd_flag, NFSD_REQINPROG); } - if (error || (slp->ns_flag & SLP_VALID) == 0) { - if (nd) { - pool_put(&nfsrv_descript_pl, nd); - nd = NULL; - } - nfsd->nfsd_slp = NULL; - nfsd->nfsd_flag &= ~NFSD_REQINPROG; - nfsrv_slpderef(slp); - continue; + } else { + error = 0; + slp = nfsd->nfsd_slp; + } + + if (error || !ISSET(slp->ns_flag, SLP_VALID)) { + if (nd != NULL) { + pool_put(&nfsrv_descript_pl, nd); + nd = NULL; } - splx(s); - so = slp->ns_so; - sotype = so->so_type; - if (so->so_proto->pr_flags & PR_CONNREQUIRED) - solockp = &slp->ns_solock; - else - solockp = NULL; - if (nd) { - if (nd->nd_nam2) + nfsd->nfsd_slp = NULL; + CLR(nfsd->nfsd_flag, NFSD_REQINPROG); + nfsrv_slpderef(slp); + goto loop; + } + + splx(s); + + so = slp->ns_so; + sotype = so->so_type; + if (ISSET(so->so_proto->pr_flags, PR_CONNREQUIRED)) + solockp = &slp->ns_solock; + else + solockp = NULL; + + if (nd) { + if (nd->nd_nam2) nd->nd_nam = nd->nd_nam2; - else + else nd->nd_nam = slp->ns_nam; + } - cacherep = nfsrv_getcache(nd, slp, &mreq); - } - - /* - * Loop to get all the write rpc relies that have been - * gathered together. - */ - do { - switch (cacherep) { - case RC_DOIT: - if (writes_todo || (!(nd->nd_flag & ND_NFSV3) && - nd->nd_procnum == NFSPROC_WRITE && - nfsrvw_procrastinate > 0)) - error = nfsrv_writegather(&nd, slp, - nfsd->nfsd_procp, &mreq); - else - error = (*(nfsrv3_procs[nd->nd_procnum]))(nd, - slp, nfsd->nfsd_procp, &mreq); - if (mreq == NULL) { - if (nd != NULL) { - m_freem(nd->nd_nam2); - m_freem(nd->nd_mrep); - } - break; - } - if (error) { - nfsstats.srv_errs++; - nfsrv_updatecache(nd, 0, mreq); - if (nd->nd_nam2) - m_freem(nd->nd_nam2); - break; - } - nfsstats.srvrpccnt[nd->nd_procnum]++; - nfsrv_updatecache(nd, 1, mreq); - nd->nd_mrep = NULL; - - /* FALLTHROUGH */ - case RC_REPLY: - m = mreq; - siz = 0; - while (m) { - siz += m->m_len; - m = m->m_next; - } - 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); - } - if (solockp) - (void) nfs_sndlock(solockp, NULL); - if (slp->ns_flag & SLP_VALID) - error = nfs_send(so, nd->nd_nam2, m, NULL); - else { - error = EPIPE; - m_freem(m); - } - if (nd->nd_nam2) + cacherep = nfsrv_getcache(nd, slp, &mreq); + switch (cacherep) { + case RC_DOIT: + error = (*(nfsrv3_procs[nd->nd_procnum]))(nd, slp, nfsd->nfsd_procp, &mreq); + if (mreq == NULL) { + if (nd != NULL) { m_freem(nd->nd_nam2); - if (nd->nd_mrep) m_freem(nd->nd_mrep); - if (error == EPIPE) - nfsrv_zapsock(slp); - if (solockp) - nfs_sndunlock(solockp); - if (error == EINTR || error == ERESTART) { - pool_put(&nfsrv_descript_pl, nd); - nfsrv_slpderef(slp); - s = splsoftnet(); - goto done; } break; - case RC_DROPIT: - m_freem(nd->nd_mrep); - m_freem(nd->nd_nam2); + } + if (error) { + nfsstats.srv_errs++; + nfsrv_updatecache(nd, 0, mreq); + if (nd->nd_nam2) + m_freem(nd->nd_nam2); break; - }; - if (nd) { - pool_put(&nfsrv_descript_pl, nd); - nd = NULL; - } + } + nfsstats.srvrpccnt[nd->nd_procnum]++; + nfsrv_updatecache(nd, 1, mreq); + nd->nd_mrep = NULL; + + /* FALLTHROUGH */ + case RC_REPLY: + m = mreq; + siz = 0; + while (m) { + siz += m->m_len; + m = m->m_next; + } - /* - * Check to see if there are outstanding writes that - * need to be serviced. - */ - getmicrotime(&tv); - s = splsoftclock(); - if (LIST_FIRST(&slp->ns_tq) && - timercmp(&LIST_FIRST(&slp->ns_tq)->nd_time, &tv, <=)) { - cacherep = RC_DOIT; - writes_todo = 1; - } else - writes_todo = 0; - splx(s); - } while (writes_todo); - s = splsoftnet(); - if (nfsrv_dorec(slp, nfsd, &nd)) { - nfsd->nfsd_flag &= ~NFSD_REQINPROG; - nfsd->nfsd_slp = NULL; + if (siz <= 0 || siz > NFS_MAXPACKET) + panic("bad nfs svc reply, siz = %i\n", siz); + + 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); + } + + if (solockp) + nfs_sndlock(solockp, NULL); + + if (ISSET(slp->ns_flag, SLP_VALID)) + error = nfs_send(so, nd->nd_nam2, m, NULL); + else { + error = EPIPE; + m_freem(m); + } + if (nd->nd_nam2) + m_freem(nd->nd_nam2); + if (nd->nd_mrep) + m_freem(nd->nd_mrep); + if (error == EPIPE) + nfsrv_zapsock(slp); + if (solockp) + nfs_sndunlock(solockp); + if (error == EINTR || error == ERESTART) { + pool_put(&nfsrv_descript_pl, nd); nfsrv_slpderef(slp); + s = splsoftnet(); + goto done; } + break; + case RC_DROPIT: + m_freem(nd->nd_mrep); + m_freem(nd->nd_nam2); + break; + }; + + if (nd) { + pool_put(&nfsrv_descript_pl, nd); + nd = NULL; } + + s = splsoftnet(); + if (nfsrv_dorec(slp, nfsd, &nd)) { + nfsd->nfsd_flag &= ~NFSD_REQINPROG; + nfsd->nfsd_slp = NULL; + nfsrv_slpderef(slp); + } + goto loop; + done: TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain); splx(s); @@ -509,11 +474,9 @@ void nfsrv_zapsock(slp) struct nfssvc_sock *slp; { - struct nfsrv_descript *nwp, *nnwp; struct socket *so; struct file *fp; struct mbuf *m, *n; - int s; slp->ns_flag &= ~SLP_ALLFLAGS; fp = slp->ns_fp; @@ -533,14 +496,6 @@ nfsrv_zapsock(slp) m_freem(m); m = n; } - s = splsoftclock(); - for (nwp = LIST_FIRST(&slp->ns_tq); nwp != NULL; nwp = nnwp) { - nnwp = LIST_NEXT(nwp, nd_tq); - LIST_REMOVE(nwp, nd_tq); - pool_put(&nfsrv_descript_pl, nwp); - } - LIST_INIT(&slp->ns_tq); - splx(s); } } diff --git a/sys/nfs/nfs_var.h b/sys/nfs/nfs_var.h index 71d9e46ac2f..3b050439731 100644 --- a/sys/nfs/nfs_var.h +++ b/sys/nfs/nfs_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_var.h,v 1.52 2009/08/04 17:12:39 thib Exp $ */ +/* $OpenBSD: nfs_var.h,v 1.53 2009/08/10 09:38:44 thib Exp $ */ /* $NetBSD: nfs_var.h,v 1.3 1996/02/18 11:53:54 fvdl Exp $ */ /* @@ -139,9 +139,6 @@ int nfsrv_read(struct nfsrv_descript *, struct nfssvc_sock *, struct proc *, struct mbuf **); int nfsrv_write(struct nfsrv_descript *, struct nfssvc_sock *, struct proc *, struct mbuf **); -int nfsrv_writegather(struct nfsrv_descript **, struct nfssvc_sock *, - struct proc *, struct mbuf **); -void nfsrvw_coalesce(struct nfsrv_descript *, struct nfsrv_descript *); int nfsrv_create(struct nfsrv_descript *, struct nfssvc_sock *, struct proc *, struct mbuf **); int nfsrv_mknod(struct nfsrv_descript *, struct nfssvc_sock *, @@ -249,8 +246,6 @@ void nfs_add_tobecommitted_range(struct vnode *, struct buf *); void nfs_del_tobecommitted_range(struct vnode *, struct buf *); void nfs_merge_commit_ranges(struct vnode *); int nfsrv_errmap(struct nfsrv_descript *, int); -void nfsrvw_sort(gid_t *, int); -void nfsrv_setcred(struct ucred *, struct ucred *); int nfsm_srvsattr(struct mbuf **, struct vattr *, struct mbuf *, caddr_t *); void nfsm_fhtom(struct mbuf **, struct vnode *, int); void nfsm_srvfhtom(struct mbuf **, fhandle_t *, int); |