diff options
author | phk <phk@FreeBSD.org> | 1994-10-17 17:47:45 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1994-10-17 17:47:45 +0000 |
commit | 071d10f334b2e0094018c4b2027c8e3e73833bc1 (patch) | |
tree | c5905f4096b68df87a3f00435bec4fcc08408b18 | |
parent | 24ec594f4ae8189490a0087923fc655e16dde331 (diff) | |
download | FreeBSD-src-071d10f334b2e0094018c4b2027c8e3e73833bc1.zip FreeBSD-src-071d10f334b2e0094018c4b2027c8e3e73833bc1.tar.gz |
This is a bunch of changes from NetBSD. There are a couple of bug-fixes.
But mostly it is changes to use the list-maintenance macros instead of
doing the pointer-gymnastics by hand.
Obtained from: NetBSD
38 files changed, 871 insertions, 957 deletions
diff --git a/sys/nfs/nfs.h b/sys/nfs/nfs.h index 844acdc..c79eefb 100644 --- a/sys/nfs/nfs.h +++ b/sys/nfs/nfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.1 (Berkeley) 6/10/93 - * $Id: nfs.h,v 1.4 1994/08/21 06:50:08 paul Exp $ + * $Id: nfs.h,v 1.5 1994/10/02 17:26:54 phk Exp $ */ #ifndef _NFS_NFS_H_ @@ -179,8 +179,7 @@ struct nfsstats { * Nfs outstanding request list element */ struct nfsreq { - struct nfsreq *r_next; - struct nfsreq *r_prev; + TAILQ_ENTRY(nfsreq) r_chain; struct mbuf *r_mreq; struct mbuf *r_mrep; struct mbuf *r_md; @@ -197,6 +196,11 @@ struct nfsreq { struct proc *r_procp; /* Proc that did I/O system call */ }; +/* + * Queue head for nfsreq's + */ +TAILQ_HEAD(, nfsreq) nfs_reqq; + /* Flag values for r_flags */ #define R_TIMING 0x01 /* timing request (in mntp) */ #define R_SENT 0x02 /* request has been sent */ @@ -216,7 +220,8 @@ struct nfsstats nfsstats; * and uid hash lists. */ #define NUIDHASHSIZ 32 -#define NUIDHASH(uid) ((uid) & (NUIDHASHSIZ - 1)) +#define NUIDHASH(sock, uid) \ + (&(sock)->ns_uidhashtbl[(uid) & (sock)->ns_uidhash]) /* * Network address hash list element @@ -227,10 +232,8 @@ union nethostaddr { }; struct nfsuid { - struct nfsuid *nu_lrunext; /* MUST be first */ - struct nfsuid *nu_lruprev; - struct nfsuid *nu_hnext; - struct nfsuid *nu_hprev; + TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ + LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ int nu_flag; /* Flags */ uid_t nu_uid; /* Uid mapped by this entry */ union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ @@ -243,10 +246,11 @@ struct nfsuid { #define NU_INETADDR 0x1 struct nfssvc_sock { - struct nfsuid *ns_lrunext; /* MUST be first */ - struct nfsuid *ns_lruprev; - struct nfssvc_sock *ns_next; - struct nfssvc_sock *ns_prev; + TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ + TAILQ_HEAD(, nfsuid) ns_uidlruhead; + LIST_HEAD(, nfsuid) *ns_uidhashtbl; + u_long ns_uidhash; + int ns_flag; u_long ns_sref; struct file *ns_fp; @@ -260,7 +264,6 @@ struct nfssvc_sock { struct mbuf *ns_rec; struct mbuf *ns_recend; int ns_numuids; - struct nfsuid *ns_uidh[NUIDHASHSIZ]; }; /* Bits for "ns_flag" */ @@ -269,17 +272,18 @@ struct nfssvc_sock { #define SLP_NEEDQ 0x04 #define SLP_DISCONN 0x08 #define SLP_GETSTREAM 0x10 -#define SLP_INIT 0x20 -#define SLP_WANTINIT 0x40 - #define SLP_ALLFLAGS 0xff +TAILQ_HEAD(, nfssvc_sock) nfssvc_sockhead; +int nfssvc_sockhead_flag; +#define SLP_INIT 0x01 +#define SLP_WANTINIT 0x02 + /* * One of these structures is allocated for each nfsd. */ struct nfsd { - struct nfsd *nd_next; /* Must be first */ - struct nfsd *nd_prev; + TAILQ_ENTRY(nfsd) nd_chain; /* List of all nfsd's */ int nd_flag; /* NFSD_ flags */ struct nfssvc_sock *nd_slp; /* Current socket */ struct mbuf *nd_nam; /* Client addr for datagram req. */ @@ -297,11 +301,15 @@ struct nfsd { struct proc *nd_procp; /* Proc ptr */ }; +/* Bits for "nd_flag" */ #define NFSD_WAITING 0x01 -#define NFSD_CHECKSLP 0x02 -#define NFSD_REQINPROG 0x04 -#define NFSD_NEEDAUTH 0x08 -#define NFSD_AUTHFAIL 0x10 +#define NFSD_REQINPROG 0x02 +#define NFSD_NEEDAUTH 0x04 +#define NFSD_AUTHFAIL 0x08 + +TAILQ_HEAD(, nfsd) nfsd_head; +int nfsd_head_flag; +#define NFSD_CHECKSLP 0x01 int nfs_reply __P((struct nfsreq *)); int nfs_getreq __P((struct nfsd *,int)); @@ -335,7 +343,7 @@ int nfs_adv __P((struct mbuf **,caddr_t *,int,int)); int nfsrv_getstream __P((struct nfssvc_sock *,int)); void nfs_nhinit __P((void)); void nfs_timer __P((void*)); -struct nfsnode ** nfs_hash __P((nfsv2fh_t *)); +struct nfsnodehashhead * nfs_hash __P((nfsv2fh_t *)); int nfssvc_iod __P((struct proc *)); int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t,struct proc *)); int nfssvc_addsock __P((struct file *,struct mbuf *)); diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c index deede73..4d75cf8 100644 --- a/sys/nfs/nfs_bio.c +++ b/sys/nfs/nfs_bio.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.5 (Berkeley) 1/4/94 - * $Id: nfs_bio.c,v 1.5 1994/08/18 22:35:35 wollman Exp $ + * $Id: nfs_bio.c,v 1.6 1994/10/02 17:26:55 phk Exp $ */ #include <sys/param.h> @@ -438,6 +438,11 @@ nfs_write(ap) do { /* + * XXX make sure we aren't cached in the VM page cache + */ + (void)vnode_pager_uncache(vp); + + /* * Check for a valid write lease. * If non-cachable, just do the rpc */ @@ -715,9 +720,28 @@ nfs_doio(bp, cr, p) /* * Historically, paging was done with physio, but no more. */ - if (bp->b_flags & B_PHYS) - panic("doio phys"); - if (bp->b_flags & B_READ) { + if (bp->b_flags & B_PHYS) { + /* + * ...though reading /dev/drum still gets us here. + */ + io.iov_len = uiop->uio_resid = bp->b_bcount; + /* mapping was done by vmapbuf() */ + io.iov_base = bp->b_data; + uiop->uio_offset = bp->b_blkno * DEV_BSIZE; + if (bp->b_flags & B_READ) { + uiop->uio_rw = UIO_READ; + nfsstats.read_physios++; + error = nfs_readrpc(vp, uiop, cr); + } else { + uiop->uio_rw = UIO_WRITE; + nfsstats.write_physios++; + error = nfs_writerpc(vp, uiop, cr,0); + } + if (error) { + bp->b_flags |= B_ERROR; + bp->b_error = error; + } + } else if (bp->b_flags & B_READ) { io.iov_len = uiop->uio_resid = bp->b_bcount; io.iov_base = bp->b_data; uiop->uio_rw = UIO_READ; @@ -749,6 +773,7 @@ nfs_doio(bp, cr, p) } if (p && (vp->v_flag & VTEXT) && (((nmp->nm_flag & NFSMNT_NQNFS) && + NQNFS_CKINVALID(vp, np, NQL_READ) && np->n_lrev != np->n_brev) || (!(nmp->nm_flag & NFSMNT_NQNFS) && np->n_mtime != np->n_vattr.va_mtime.ts_sec))) { diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c index ee8200c..9b2ef80 100644 --- a/sys/nfs/nfs_common.c +++ b/sys/nfs/nfs_common.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_subs.c,v 1.5 1994/09/22 22:10:44 wollman Exp $ + * $Id: nfs_subs.c,v 1.6 1994/10/02 17:27:01 phk Exp $ */ /* @@ -94,7 +94,6 @@ u_long nfs_vers, nfs_prog, nfs_true, nfs_false; static u_long nfs_xid = 0; enum vtype ntov_type[7] = { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON }; extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; -extern struct nfsreq nfsreqh; extern int nqnfs_piggy[NFS_NPROCS]; extern struct nfsrtt nfsrtt; extern time_t nqnfsstarttime; @@ -110,6 +109,8 @@ struct nfssvc_args; extern int nfssvc(struct proc *, struct nfssvc_args *, int *); #endif +LIST_HEAD(nfsnodehashhead, nfsnode); + /* * Create the header for an rpc request packet * The hsiz is the size of the rest of the nfs request header. @@ -615,6 +616,7 @@ nfs_init() nfs_prog = txdr_unsigned(NFS_PROG); nfs_true = txdr_unsigned(TRUE); nfs_false = txdr_unsigned(FALSE); + nfs_xdrneg1 = txdr_unsigned(-1); /* Loop thru nfs procids */ for (i = 0; i < NFS_NPROCS; i++) nfs_procids[i] = txdr_unsigned(i); @@ -622,7 +624,6 @@ nfs_init() for (i = 0; i < NFS_MAXASYNCDAEMON; i++) nfs_iodwant[i] = (struct proc *)0; TAILQ_INIT(&nfs_bufq); - nfs_xdrneg1 = txdr_unsigned(-1); nfs_nhinit(); /* Init the nfsnode table */ nfsrv_init(0); /* Init server data structures */ nfsrv_initcache(); /* Init the server request cache */ @@ -636,15 +637,14 @@ nfs_init() NQLOADNOVRAM(nqnfsstarttime); nqnfs_prog = txdr_unsigned(NQNFS_PROG); nqnfs_vers = txdr_unsigned(NQNFS_VER1); - nqthead.th_head[0] = &nqthead; - nqthead.th_head[1] = &nqthead; - nqfhead = hashinit(NQLCHSZ, M_NQLEASE, &nqfheadhash); + CIRCLEQ_INIT(&nqtimerhead); + nqfhhashtbl = hashinit(NQLCHSZ, M_NQLEASE, &nqfhhash); } /* * Initialize reply list and start timer */ - nfsreqh.r_prev = nfsreqh.r_next = &nfsreqh; + TAILQ_INIT(&nfs_reqq); nfs_timer(0); /* @@ -689,7 +689,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) register struct vattr *vap; register struct nfsv2_fattr *fp; extern int (**spec_nfsv2nodeop_p)(); - register struct nfsnode *np, *nq, **nhpp; + register struct nfsnode *np; + register struct nfsnodehashhead *nhpp; register long t1; caddr_t dpos, cp2; int error = 0, isnq; @@ -743,10 +744,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) /* * Discard unneeded vnode, but save its nfsnode. */ - nq = np->n_forw; - if (nq) - nq->n_back = np->n_back; - *np->n_back = nq; + LIST_REMOVE(np, n_hash); nvp->v_data = vp->v_data; vp->v_data = NULL; vp->v_op = spec_vnodeop_p; @@ -756,13 +754,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) * Reinitialize aliased node. */ np->n_vnode = nvp; - nhpp = (struct nfsnode **)nfs_hash(&np->n_fh); - nq = *nhpp; - if (nq) - nq->n_back = &np->n_forw; - np->n_forw = nq; - np->n_back = nhpp; - *nhpp = np; + nhpp = nfs_hash(&np->n_fh); + LIST_INSERT_HEAD(nhpp, np, n_hash); *vpp = vp = nvp; } } @@ -794,9 +787,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) vap->va_fileid = fxdr_unsigned(long, fp->fa_nfsfileid); fxdr_nfstime(&fp->fa_nfsatime, &vap->va_atime); vap->va_flags = 0; - vap->va_ctime.ts_sec = fxdr_unsigned(long, fp->fa_nfsctime.nfs_sec); - vap->va_ctime.ts_nsec = 0; - vap->va_gen = fxdr_unsigned(u_long, fp->fa_nfsctime.nfs_usec); + fxdr_nfstime(&fp->fa_nfsctime, &vap->va_ctime); + vap->va_gen = 0; vap->va_filerev = 0; } if (vap->va_size != np->n_size) { @@ -1106,24 +1098,24 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp) * Check/setup credentials. */ if (exflags & MNT_EXKERB) { - uidp = slp->ns_uidh[NUIDHASH(cred->cr_uid)]; - while (uidp) { + for (uidp = NUIDHASH(slp, cred->cr_uid)->lh_first; uidp != 0; + uidp = uidp->nu_hash.le_next) { if (uidp->nu_uid == cred->cr_uid) break; - uidp = uidp->nu_hnext; } - if (uidp) { - cred->cr_uid = uidp->nu_cr.cr_uid; - for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) - cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; - } else { + if (uidp == 0) { vput(*vpp); return (NQNFS_AUTHERR); } + cred->cr_uid = uidp->nu_cr.cr_uid; + for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) + cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; + cred->cr_ngroups = i; } else if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { cred->cr_uid = credanon->cr_uid; for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++) cred->cr_groups[i] = credanon->cr_groups[i]; + cred->cr_ngroups = i; } if (exflags & MNT_EXRDONLY) *rdonlyp = 1; diff --git a/sys/nfs/nfs_common.h b/sys/nfs/nfs_common.h index 954a92f..994c0b6 100644 --- a/sys/nfs/nfs_common.h +++ b/sys/nfs/nfs_common.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsm_subs.h 8.1 (Berkeley) 6/16/93 - * $Id: nfsm_subs.h,v 1.3 1994/08/21 06:50:10 paul Exp $ + * $Id: nfsm_subs.h,v 1.4 1994/10/02 17:27:05 phk Exp $ */ #ifndef _NFS_NFSM_SUBS_H_ @@ -264,8 +264,7 @@ extern struct mbuf *nfsm_reqh(); fp->fa_nfsblocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \ txdr_nfstime(&vap->va_atime, &fp->fa_nfsatime); \ txdr_nfstime(&vap->va_mtime, &fp->fa_nfsmtime); \ - fp->fa_nfsctime.nfs_sec = txdr_unsigned(vap->va_ctime.ts_sec); \ - fp->fa_nfsctime.nfs_usec = txdr_unsigned(vap->va_gen); \ + txdr_nfstime(&vap->va_ctime, &fp->fa_nfsctime); \ } else { \ fp->fa_nqblocksize = txdr_unsigned(vap->va_blocksize); \ if (vap->va_type == VFIFO) \ diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c index c5804d5..909f9e0 100644 --- a/sys/nfs/nfs_node.c +++ b/sys/nfs/nfs_node.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_node.c 8.2 (Berkeley) 12/30/93 - * $Id: nfs_node.c,v 1.5 1994/10/02 17:26:56 phk Exp $ + * $Id: nfs_node.c,v 1.6 1994/10/06 21:06:56 davidg Exp $ */ #include <sys/param.h> @@ -53,9 +53,10 @@ #include <nfs/nfsmount.h> #include <nfs/nqnfs.h> -struct nfsnode **nheadhashtbl; -u_long nheadhash; -#define NFSNOHASH(fhsum) ((fhsum)&nheadhash) +#define NFSNOHASH(fhsum) \ + (&nfsnodehashtbl[(fhsum) & nfsnodehash]) +LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl; +u_long nfsnodehash; #define TRUE 1 #define FALSE 0 @@ -72,13 +73,13 @@ nfs_nhinit() if ((sizeof(struct nfsnode) - 1) & sizeof(struct nfsnode)) printf("nfs_nhinit: bad size %d\n", sizeof(struct nfsnode)); #endif /* not lint */ - nheadhashtbl = hashinit(desiredvnodes, M_NFSNODE, &nheadhash); + nfsnodehashtbl = hashinit(desiredvnodes, M_NFSNODE, &nfsnodehash); } /* * Compute an entry in the NFS hash table structure */ -struct nfsnode ** +struct nfsnodehashhead * nfs_hash(fhp) register nfsv2fh_t *fhp; { @@ -90,7 +91,7 @@ nfs_hash(fhp) fhsum = 0; for (i = 0; i < NFSX_FH; i++) fhsum += *fhpp++; - return (&nheadhashtbl[NFSNOHASH(fhsum)]); + return (NFSNOHASH(fhsum)); } /* @@ -105,7 +106,8 @@ nfs_nget(mntp, fhp, npp) register nfsv2fh_t *fhp; struct nfsnode **npp; { - register struct nfsnode *np, *nq, **nhpp; + register struct nfsnode *np; + struct nfsnodehashhead *nhpp; register struct vnode *vp; extern int (**nfsv2_vnodeop_p)(); struct vnode *nvp; @@ -113,7 +115,7 @@ nfs_nget(mntp, fhp, npp) nhpp = nfs_hash(fhp); loop: - for (np = *nhpp; np; np = np->n_forw) { + for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) { if (mntp != NFSTOV(np)->v_mount || bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH)) continue; @@ -136,12 +138,7 @@ loop: * Insert the nfsnode in the hash queue for its new file handle */ np->n_flag = 0; - nq = *nhpp; - if (nq) - nq->n_back = &np->n_forw; - np->n_forw = nq; - np->n_back = nhpp; - *nhpp = np; + LIST_INSERT_HEAD(nhpp, np, n_hash); bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH); np->n_attrstamp = 0; np->n_direofoffset = 0; @@ -153,7 +150,7 @@ loop: np->n_brev = 0; np->n_lrev = 0; np->n_expiry = (time_t)0; - np->n_tnext = (struct nfsnode *)0; + np->n_timer.cqe_next = (struct nfsnode *)0; } *npp = np; return (0); @@ -204,31 +201,18 @@ nfs_reclaim(ap) register struct vnode *vp = ap->a_vp; register struct nfsnode *np = VTONFS(vp); register struct nfsmount *nmp = VFSTONFS(vp->v_mount); - register struct nfsnode *nq; extern int prtactive; if (prtactive && vp->v_usecount != 0) vprint("nfs_reclaim: pushing active", vp); - /* - * Remove the nfsnode from its hash chain. - */ - nq = np->n_forw; - if (nq) - nq->n_back = np->n_back; - *np->n_back = nq; + + LIST_REMOVE(np, n_hash); /* * For nqnfs, take it off the timer queue as required. */ - if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_tnext) { - if (np->n_tnext == (struct nfsnode *)nmp) - nmp->nm_tprev = np->n_tprev; - else - np->n_tnext->n_tprev = np->n_tprev; - if (np->n_tprev == (struct nfsnode *)nmp) - nmp->nm_tnext = np->n_tnext; - else - np->n_tprev->n_tnext = np->n_tnext; + if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_timer.cqe_next != 0) { + CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer); } cache_purge(vp); FREE(vp->v_data, M_NFSNODE); diff --git a/sys/nfs/nfs_nqlease.c b/sys/nfs/nfs_nqlease.c index 1575163..1946764 100644 --- a/sys/nfs/nfs_nqlease.c +++ b/sys/nfs/nfs_nqlease.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_nqlease.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_nqlease.c,v 1.5 1994/09/23 17:49:44 wollman Exp $ + * $Id: nfs_nqlease.c,v 1.6 1994/10/02 17:26:57 phk Exp $ */ /* @@ -74,15 +74,6 @@ #include <nfs/nfsnode.h> #include <nfs/nfsmount.h> -/* - * List head for the lease queue and other global data. - * At any time a lease is linked into a list ordered by increasing expiry time. - */ -#define NQFHHASH(f) ((*((u_long *)(f)))&nqfheadhash) - -union nqsrvthead nqthead; -struct nqlease **nqfhead; -u_long nqfheadhash; time_t nqnfsstarttime = (time_t)0; u_long nqnfs_prog, nqnfs_vers; int nqsrv_clockskew = NQ_CLOCKSKEW; @@ -124,13 +115,9 @@ int nqnfs_piggy[NFS_NPROCS] = { 0, }; -int nnnnnn = sizeof (struct nqlease); -int oooooo = sizeof (struct nfsnode); extern nfstype nfs_type[9]; extern struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock; -extern struct nfsd nfsd_head; extern int nfsd_waiting; -extern struct nfsreq nfsreqh; #define TRUE 1 #define FALSE 0 @@ -169,7 +156,8 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred) u_quad_t *frev; struct ucred *cred; { - register struct nqlease *lp, *lq, **lpp = 0; + register struct nqlease *lp; + register struct nqfhhashhead *lpp = 0; register struct nqhost *lph = 0; struct nqlease *tlp; struct nqm **lphp; @@ -200,8 +188,8 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred) splx(s); return (error); } - lpp = &nqfhead[NQFHHASH(fh.fh_fid.fid_data)]; - for (lp = *lpp; lp; lp = lp->lc_fhnext) + lpp = NQFHHASH(fh.fh_fid.fid_data); + for (lp = lpp->lh_first; lp != 0; lp = lp->lc_hash.le_next) if (fh.fh_fsid.val[0] == lp->lc_fsid.val[0] && fh.fh_fsid.val[1] == lp->lc_fsid.val[1] && !bcmp(fh.fh_fid.fid_data, lp->lc_fiddata, @@ -212,14 +200,14 @@ nqsrv_getlease(vp, duration, flags, nd, nam, cachablep, frev, cred) tlp = lp; break; } - } - lp = tlp; + } else + lp = tlp; if (lp) { if ((lp->lc_flag & LC_NONCACHABLE) || (lp->lc_morehosts == (struct nqm *)0 && nqsrv_cmpnam(nd->nd_slp, nam, &lp->lc_host))) goto doreply; - if ((flags & NQL_READ) && (lp->lc_flag & LC_WRITE)==0) { + if ((flags & NQL_READ) && (lp->lc_flag & LC_WRITE) == 0) { if (flags & NQL_CHECK) goto doreply; if (nqsrv_cmpnam(nd->nd_slp, nam, &lp->lc_host)) @@ -302,13 +290,11 @@ doreply: nqsrv_addhost(&lp->lc_host, nd->nd_slp, nam); lp->lc_vp = vp; lp->lc_fsid = fh.fh_fsid; - bcopy(fh.fh_fid.fid_data, lp->lc_fiddata, fh.fh_fid.fid_len - sizeof (long)); - lq = *lpp; - if (lq) - lq->lc_fhprev = &lp->lc_fhnext; - lp->lc_fhnext = lq; - lp->lc_fhprev = lpp; - *lpp = lp; + bcopy(fh.fh_fid.fid_data, lp->lc_fiddata, + fh.fh_fid.fid_len - sizeof (long)); + if(!lpp) + panic("nfs_nqlease.c: Phoney lpp"); + LIST_INSERT_HEAD(lpp, lp, lc_hash); vp->v_lease = lp; s = splsoftclock(); nqsrv_instimeq(lp, *duration); @@ -383,20 +369,26 @@ nqsrv_instimeq(lp, duration) newexpiry = time.tv_sec + duration + nqsrv_clockskew; if (lp->lc_expiry == newexpiry) return; - if (lp->lc_chain1[0]) - remque(lp); + if (lp->lc_timer.cqe_next != 0) { + CIRCLEQ_REMOVE(&nqtimerhead, lp, lc_timer); + } lp->lc_expiry = newexpiry; /* * Find where in the queue it should be. */ - tlp = nqthead.th_chain[1]; - while (tlp->lc_expiry > newexpiry && tlp != (struct nqlease *)&nqthead) - tlp = tlp->lc_chain1[1]; - if (tlp == nqthead.th_chain[1]) { + tlp = nqtimerhead.cqh_last; + while (tlp != (void *)&nqtimerhead && tlp->lc_expiry > newexpiry) + tlp = tlp->lc_timer.cqe_prev; +#ifdef HASNVRAM + if (tlp == nqtimerhead.cqh_last) NQSTORENOVRAM(newexpiry); +#endif /* HASNVRAM */ + if (tlp == (void *)&nqtimerhead) { + CIRCLEQ_INSERT_HEAD(&nqtimerhead, lp, lc_timer); + } else { + CIRCLEQ_INSERT_AFTER(&nqtimerhead, tlp, lp, lc_timer); } - insque(lp, tlp); } /* @@ -602,18 +594,18 @@ tryagain: void nqnfs_serverd() { - register struct nqlease *lp, *lq; + register struct nqlease *lp; register struct nqhost *lph; struct nqlease *nextlp; struct nqm *lphnext, *olphnext; struct mbuf *n; int i, len, ok; - lp = nqthead.th_chain[0]; - while (lp != (struct nqlease *)&nqthead) { + for (lp = nqtimerhead.cqh_first; lp != (void *)&nqtimerhead; + lp = nextlp) { if (lp->lc_expiry >= time.tv_sec) break; - nextlp = lp->lc_chain1[0]; + nextlp = lp->lc_timer.cqe_next; if (lp->lc_flag & LC_EXPIREDWANTED) { lp->lc_flag &= ~LC_EXPIREDWANTED; wakeup((caddr_t)&lp->lc_flag); @@ -634,11 +626,8 @@ nqnfs_serverd() lp->lc_flag &= ~LC_WRITTEN; nqsrv_instimeq(lp, nqsrv_writeslack); } else { - remque(lp); - lq = lp->lc_fhnext; - if (lq) - lq->lc_fhprev = lp->lc_fhprev; - *lp->lc_fhprev = lq; + CIRCLEQ_REMOVE(&nqtimerhead, lp, lc_timer); + LIST_REMOVE(lp, lc_hash); /* * This soft reference may no longer be valid, but * no harm done. The worst case is if the vnode was @@ -679,7 +668,6 @@ nqnfs_serverd() nfsstats.srvnqnfs_leases--; } } - lp = nextlp; } } @@ -767,8 +755,8 @@ nqnfsrv_vacated(nfsd, mrep, md, dpos, cred, nam, mrq) /* * Find the lease by searching the hash list. */ - for (lp = nqfhead[NQFHHASH(fhp->fh_fid.fid_data)]; lp; - lp = lp->lc_fhnext) + for (lp = NQFHHASH(fhp->fh_fid.fid_data)->lh_first; lp != 0; + lp = lp->lc_hash.le_next) if (fhp->fh_fsid.val[0] == lp->lc_fsid.val[0] && fhp->fh_fsid.val[1] == lp->lc_fsid.val[1] && !bcmp(fhp->fh_fid.fid_data, lp->lc_fiddata, @@ -940,22 +928,12 @@ nqnfs_callback(nmp, mrep, md, dpos) if (error) return (error); vp = NFSTOV(np); - if (np->n_tnext) { + if (np->n_timer.cqe_next != 0) { np->n_expiry = 0; np->n_flag |= NQNFSEVICTED; - if (np->n_tprev != (struct nfsnode *)nmp) { - if (np->n_tnext == (struct nfsnode *)nmp) - nmp->nm_tprev = np->n_tprev; - else - np->n_tnext->n_tprev = np->n_tprev; - np->n_tprev->n_tnext = np->n_tnext; - np->n_tnext = nmp->nm_tnext; - nmp->nm_tnext = np; - np->n_tprev = (struct nfsnode *)nmp; - if (np->n_tnext == (struct nfsnode *)nmp) - nmp->nm_tprev = np; - else - np->n_tnext->n_tprev = np; + if (nmp->nm_timerhead.cqh_first != np) { + CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer); + CIRCLEQ_INSERT_HEAD(&nmp->nm_timerhead, np, n_timer); } } vrele(vp); @@ -1021,7 +999,7 @@ nqnfs_clientd(nmp, cred, ncd, flag, argp, p) * processes in nfs_reply) and there is data in the receive * queue, poke for callbacks. */ - if (nfsreqh.r_next == &nfsreqh && nmp->nm_so && + if (nfs_reqq.tqh_first == 0 && nmp->nm_so && nmp->nm_so->so_rcv.sb_cc > 0) { myrep.r_flags = R_GETONEREP; myrep.r_nmp = nmp; @@ -1033,8 +1011,8 @@ nqnfs_clientd(nmp, cred, ncd, flag, argp, p) /* * Loop through the leases, updating as required. */ - np = nmp->nm_tnext; - while (np != (struct nfsnode *)nmp && + np = nmp->nm_timerhead.cqh_first; + while (np != (void *)&nmp->nm_timerhead && (nmp->nm_flag & NFSMNT_DISMINPROG) == 0) { vp = NFSTOV(np); if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash2"); @@ -1044,15 +1022,8 @@ if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash2"); nmp->nm_inprog = vp; if (vpid == vp->v_id) { if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash3"); - if (np->n_tnext == (struct nfsnode *)nmp) - nmp->nm_tprev = np->n_tprev; - else - np->n_tnext->n_tprev = np->n_tprev; - if (np->n_tprev == (struct nfsnode *)nmp) - nmp->nm_tnext = np->n_tnext; - else - np->n_tprev->n_tnext = np->n_tnext; - np->n_tnext = (struct nfsnode *)0; + CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer); + np->n_timer.cqe_next = 0; if ((np->n_flag & (NMODIFIED | NQNFSEVICTED)) && vp->v_type == VREG) { if (np->n_flag & NQNFSEVICTED) { @@ -1070,10 +1041,6 @@ if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash3"); vrele(vp); nmp->nm_inprog = NULLVP; } - if (np != nmp->nm_tnext) - np = nmp->nm_tnext; - else - break; } else if ((np->n_expiry - NQ_RENEWAL) < time.tv_sec) { if ((np->n_flag & (NQNFSWRITE | NQNFSNONCACHE)) == NQNFSWRITE && vp->v_dirtyblkhd.lh_first && @@ -1086,12 +1053,11 @@ if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash4"); vrele(vp); nmp->nm_inprog = NULLVP; } - if (np != nmp->nm_tnext) - np = nmp->nm_tnext; - else - break; } else break; + if (np == nmp->nm_timerhead.cqh_first) + break; + np = nmp->nm_timerhead.cqh_first; } } @@ -1140,11 +1106,9 @@ nfs_lease_updatetime(deltat) if (nqnfsstarttime != 0) nqnfsstarttime += deltat; s = splsoftclock(); - lp = nqthead.th_chain[0]; - while (lp != (struct nqlease *)&nqthead) { + for (lp = nqtimerhead.cqh_first; lp != (void *)&nqtimerhead; + lp = lp->lc_timer.cqe_next) lp->lc_expiry += deltat; - lp = lp->lc_chain1[0]; - } splx(s); /* @@ -1155,10 +1119,10 @@ nfs_lease_updatetime(deltat) if (mp->mnt_stat.f_fsid.val[1] == MOUNT_NFS) { nmp = VFSTONFS(mp); if (nmp->nm_flag & NFSMNT_NQNFS) { - np = nmp->nm_tnext; - while (np != (struct nfsnode *)nmp) { + for (np = nmp->nm_timerhead.cqh_first; + np != (void *)&nmp->nm_timerhead; + np = np->n_timer.cqe_next) { np->n_expiry += deltat; - np = np->n_tnext; } } } @@ -1207,15 +1171,8 @@ nqnfs_clientlease(nmp, np, rwflag, cachable, expiry, frev) { register struct nfsnode *tp; - if (np->n_tnext) { - if (np->n_tnext == (struct nfsnode *)nmp) - nmp->nm_tprev = np->n_tprev; - else - np->n_tnext->n_tprev = np->n_tprev; - if (np->n_tprev == (struct nfsnode *)nmp) - nmp->nm_tnext = np->n_tnext; - else - np->n_tprev->n_tnext = np->n_tnext; + if (np->n_timer.cqe_next != 0) { + CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer); if (rwflag == NQL_WRITE) np->n_flag |= NQNFSWRITE; } else if (rwflag == NQL_READ) @@ -1228,19 +1185,12 @@ nqnfs_clientlease(nmp, np, rwflag, cachable, expiry, frev) np->n_flag |= NQNFSNONCACHE; np->n_expiry = expiry; np->n_lrev = frev; - tp = nmp->nm_tprev; - while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry) - tp = tp->n_tprev; - if (tp == (struct nfsnode *)nmp) { - np->n_tnext = nmp->nm_tnext; - nmp->nm_tnext = np; + tp = nmp->nm_timerhead.cqh_last; + while (tp != (void *)&nmp->nm_timerhead && tp->n_expiry > np->n_expiry) + tp = tp->n_timer.cqe_prev; + if (tp == (void *)&nmp->nm_timerhead) { + CIRCLEQ_INSERT_HEAD(&nmp->nm_timerhead, np, n_timer); } else { - np->n_tnext = tp->n_tnext; - tp->n_tnext = np; + CIRCLEQ_INSERT_AFTER(&nmp->nm_timerhead, tp, np, n_timer); } - np->n_tprev = tp; - if (np->n_tnext == (struct nfsnode *)nmp) - nmp->nm_tprev = np; - else - np->n_tnext->n_tprev = np; } diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 4cc719f..27c4561 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94 - * $Id: nfs_socket.c,v 1.3 1994/08/02 07:52:11 davidg Exp $ + * $Id: nfs_socket.c,v 1.4 1994/10/02 17:26:59 phk Exp $ */ /* @@ -57,6 +57,7 @@ #include <netinet/in.h> #include <netinet/tcp.h> + #include <nfs/rpcv2.h> #include <nfs/nfsv2.h> #include <nfs/nfs.h> @@ -67,6 +68,8 @@ #include <nfs/nfsrtt.h> #include <nfs/nqnfs.h> +#include <machine/clock.h> /* for inittodr */ + #define TRUE 1 #define FALSE 0 @@ -158,7 +161,6 @@ void nfs_rcvunlock(), nqnfs_serverd(), nqnfs_clientlease(); struct mbuf *nfsm_rpchead(); int nfsrtton = 0; struct nfsrtt nfsrtt; -struct nfsd nfsd_head; int nfsrv_null(), nfsrv_getattr(), @@ -208,8 +210,6 @@ int (*nfsrv_procs[NFS_NPROCS])() = { nqnfsrv_access, }; -struct nfsreq nfsreqh; - /* * Initialize sockets and congestion for a new NFS connection. * We do not free the sockaddr if error. @@ -375,11 +375,9 @@ nfs_reconnect(rep) * Loop through outstanding request list and fix up all requests * on old socket. */ - rp = nfsreqh.r_next; - while (rp != &nfsreqh) { + for (rp = nfs_reqq.tqh_first; rp != 0; rp = rp->r_chain.tqe_next) { if (rp->r_nmp == nmp) rp->r_flags |= R_MUSTRESEND; - rp = rp->r_next; } return (0); } @@ -769,8 +767,8 @@ nfsmout: * Loop through the request list to match up the reply * Iff no match, just drop the datagram */ - rep = nfsreqh.r_next; - while (rep != &nfsreqh) { + for (rep = nfs_reqq.tqh_first; rep != 0; + rep = rep->r_chain.tqe_next) { if (rep->r_mrep == NULL && rxid == rep->r_xid) { /* Found it.. */ rep->r_mrep = mrep; @@ -832,13 +830,12 @@ nfsmout: nmp->nm_timeouts = 0; break; } - rep = rep->r_next; } /* * If not matched to a request, drop it. * If it's mine, get out. */ - if (rep == &nfsreqh) { + if (rep == 0) { nfsstats.rpcunexpected++; m_freem(mrep); } else if (rep == myrep) { @@ -878,7 +875,6 @@ nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp) register int i; struct nfsmount *nmp; struct mbuf *md, *mheadend; - struct nfsreq *reph; struct nfsnode *np; time_t reqtime, waituntil; caddr_t dpos, cp2; @@ -964,11 +960,7 @@ tryagain: * to put it LAST so timer finds oldest requests first. */ s = splsoftclock(); - reph = &nfsreqh; - reph->r_prev->r_next = rep; - rep->r_prev = reph->r_prev; - reph->r_prev = rep; - rep->r_next = reph; + TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain); /* Get send time for nqnfs */ reqtime = time.tv_sec; @@ -1009,8 +1001,7 @@ tryagain: * RPC done, unlink the request. */ s = splsoftclock(); - rep->r_prev->r_next = rep->r_next; - rep->r_next->r_prev = rep->r_prev; + TAILQ_REMOVE(&nfs_reqq, rep, r_chain); splx(s); /* @@ -1167,7 +1158,7 @@ nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp) tl = mtod(mreq, u_long *); mreq->m_len = 6*NFSX_UNSIGNED; bpos = ((caddr_t)tl)+mreq->m_len; - *tl++ = nd->nd_retxid; + *tl++ = txdr_unsigned(nd->nd_retxid); *tl++ = rpc_reply; if (err == ERPCMISMATCH || err == NQNFS_AUTHERR) { *tl++ = rpc_msgdenied; @@ -1255,7 +1246,7 @@ nfs_timer(arg) int s, error; s = splnet(); - for (rep = nfsreqh.r_next; rep != &nfsreqh; rep = rep->r_next) { + for (rep = nfs_reqq.tqh_first; rep != 0; rep = rep->r_chain.tqe_next) { nmp = rep->r_nmp; if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) continue; @@ -1842,7 +1833,7 @@ nfs_getreq(nd, has_header) dpos = nd->nd_dpos; if (has_header) { nfsm_dissect(tl, u_long *, 10*NFSX_UNSIGNED); - nd->nd_retxid = *tl++; + nd->nd_retxid = fxdr_unsigned(u_long, *tl++); if (*tl++ != rpc_call) { m_freem(mrep); return (EBADRPC); @@ -1980,11 +1971,11 @@ void nfsrv_wakenfsd(slp) struct nfssvc_sock *slp; { - register struct nfsd *nd = nfsd_head.nd_next; + register struct nfsd *nd; if ((slp->ns_flag & SLP_VALID) == 0) return; - while (nd != (struct nfsd *)&nfsd_head) { + for (nd = nfsd_head.tqh_first; nd != 0; nd = nd->nd_chain.tqe_next) { if (nd->nd_flag & NFSD_WAITING) { nd->nd_flag &= ~NFSD_WAITING; if (nd->nd_slp) @@ -1994,10 +1985,9 @@ nfsrv_wakenfsd(slp) wakeup((caddr_t)nd); return; } - nd = nd->nd_next; } slp->ns_flag |= SLP_DOREC; - nfsd_head.nd_flag |= NFSD_CHECKSLP; + nfsd_head_flag |= NFSD_CHECKSLP; } int diff --git a/sys/nfs/nfs_srvcache.c b/sys/nfs/nfs_srvcache.c index f496ea1..0f31ae0 100644 --- a/sys/nfs/nfs_srvcache.c +++ b/sys/nfs/nfs_srvcache.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_srvcache.c 8.1 (Berkeley) 6/10/93 - * $Id: nfs_srvcache.c,v 1.3 1994/08/02 07:52:12 davidg Exp $ + * $Id: nfs_srvcache.c,v 1.4 1994/10/02 17:27:00 phk Exp $ */ /* @@ -66,10 +66,11 @@ long numnfsrvcache, desirednfsrvcache = NFSRVCACHESIZ; -#define NFSRCHASH(xid) (((xid) + ((xid) >> 24)) & rheadhash) -static struct nfsrvcache *nfsrvlruhead, **nfsrvlrutail = &nfsrvlruhead; -static struct nfsrvcache **rheadhtbl; -static u_long rheadhash; +#define NFSRCHASH(xid) \ + (&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash]) +LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl; +TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead; +u_long nfsrvhash; #define TRUE 1 #define FALSE 0 @@ -140,7 +141,8 @@ void nfsrv_initcache() { - rheadhtbl = hashinit(desirednfsrvcache, M_NFSD, &rheadhash); + nfsrvhashtbl = hashinit(desirednfsrvcache, M_NFSD, &nfsrvhash); + TAILQ_INIT(&nfsrvlruhead); } /* @@ -163,7 +165,7 @@ nfsrv_getcache(nam, nd, repp) register struct nfsd *nd; struct mbuf **repp; { - register struct nfsrvcache *rp, *rq, **rpp; + register struct nfsrvcache *rp; struct mbuf *mb; struct sockaddr_in *saddr; caddr_t bpos; @@ -171,9 +173,9 @@ nfsrv_getcache(nam, nd, repp) if (nd->nd_nqlflag != NQL_NOVAL) return (RC_DOIT); - rpp = &rheadhtbl[NFSRCHASH(nd->nd_retxid)]; loop: - for (rp = *rpp; rp; rp = rp->rc_forw) { + for (rp = NFSRCHASH(nd->nd_retxid)->lh_first; rp != 0; + rp = rp->rc_hash.le_next) { if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc && netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nam)) { if ((rp->rc_flag & RC_LOCKED) != 0) { @@ -183,15 +185,9 @@ loop: } rp->rc_flag |= RC_LOCKED; /* If not at end of LRU chain, move it there */ - if (rp->rc_next) { - /* remove from LRU chain */ - *rp->rc_prev = rp->rc_next; - rp->rc_next->rc_prev = rp->rc_prev; - /* and replace at end of it */ - rp->rc_next = NULL; - rp->rc_prev = nfsrvlrutail; - *nfsrvlrutail = rp; - nfsrvlrutail = &rp->rc_next; + if (rp->rc_lru.tqe_next) { + TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru); + TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru); } if (rp->rc_state == RC_UNUSED) panic("nfsrv cache"); @@ -229,32 +225,22 @@ loop: numnfsrvcache++; rp->rc_flag = RC_LOCKED; } else { - rp = nfsrvlruhead; + rp = nfsrvlruhead.tqh_first; while ((rp->rc_flag & RC_LOCKED) != 0) { rp->rc_flag |= RC_WANTED; (void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0); - rp = nfsrvlruhead; + rp = nfsrvlruhead.tqh_first; } rp->rc_flag |= RC_LOCKED; - /* remove from hash chain */ - rq = rp->rc_forw; - if (rq) - rq->rc_back = rp->rc_back; - *rp->rc_back = rq; - /* remove from LRU chain */ - *rp->rc_prev = rp->rc_next; - rp->rc_next->rc_prev = rp->rc_prev; + 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) MFREE(rp->rc_nam, mb); rp->rc_flag &= (RC_LOCKED | RC_WANTED); } - /* place at end of LRU list */ - rp->rc_next = NULL; - rp->rc_prev = nfsrvlrutail; - *nfsrvlrutail = rp; - nfsrvlrutail = &rp->rc_next; + TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru); rp->rc_state = RC_INPROG; rp->rc_xid = nd->nd_retxid; saddr = mtod(nam, struct sockaddr_in *); @@ -270,13 +256,7 @@ loop: break; }; rp->rc_proc = nd->nd_procnum; - /* insert into hash chain */ - rq = *rpp; - if (rq) - rq->rc_back = &rp->rc_forw; - rp->rc_forw = rq; - rp->rc_back = rpp; - *rpp = rp; + 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; @@ -300,7 +280,8 @@ nfsrv_updatecache(nam, nd, repvalid, repmbuf) if (nd->nd_nqlflag != NQL_NOVAL) return; loop: - for (rp = rheadhtbl[NFSRCHASH(nd->nd_retxid)]; rp; rp = rp->rc_forw) { + for (rp = NFSRCHASH(nd->nd_retxid)->lh_first; rp != 0; + rp = rp->rc_hash.le_next) { if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc && netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nam)) { if ((rp->rc_flag & RC_LOCKED) != 0) { @@ -342,12 +323,11 @@ nfsrv_cleancache() { register struct nfsrvcache *rp, *nextrp; - for (rp = nfsrvlruhead; rp; rp = nextrp) { - nextrp = rp->rc_next; + for (rp = nfsrvlruhead.tqh_first; rp != 0; rp = nextrp) { + nextrp = rp->rc_lru.tqe_next; + LIST_REMOVE(rp, rc_hash); + TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru); free(rp, M_NFSD); } - bzero((char *)rheadhtbl, (rheadhash + 1) * sizeof(void *)); - nfsrvlruhead = NULL; - nfsrvlrutail = &nfsrvlruhead; numnfsrvcache = 0; } diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index ee8200c..9b2ef80 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_subs.c,v 1.5 1994/09/22 22:10:44 wollman Exp $ + * $Id: nfs_subs.c,v 1.6 1994/10/02 17:27:01 phk Exp $ */ /* @@ -94,7 +94,6 @@ u_long nfs_vers, nfs_prog, nfs_true, nfs_false; static u_long nfs_xid = 0; enum vtype ntov_type[7] = { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON }; extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; -extern struct nfsreq nfsreqh; extern int nqnfs_piggy[NFS_NPROCS]; extern struct nfsrtt nfsrtt; extern time_t nqnfsstarttime; @@ -110,6 +109,8 @@ struct nfssvc_args; extern int nfssvc(struct proc *, struct nfssvc_args *, int *); #endif +LIST_HEAD(nfsnodehashhead, nfsnode); + /* * Create the header for an rpc request packet * The hsiz is the size of the rest of the nfs request header. @@ -615,6 +616,7 @@ nfs_init() nfs_prog = txdr_unsigned(NFS_PROG); nfs_true = txdr_unsigned(TRUE); nfs_false = txdr_unsigned(FALSE); + nfs_xdrneg1 = txdr_unsigned(-1); /* Loop thru nfs procids */ for (i = 0; i < NFS_NPROCS; i++) nfs_procids[i] = txdr_unsigned(i); @@ -622,7 +624,6 @@ nfs_init() for (i = 0; i < NFS_MAXASYNCDAEMON; i++) nfs_iodwant[i] = (struct proc *)0; TAILQ_INIT(&nfs_bufq); - nfs_xdrneg1 = txdr_unsigned(-1); nfs_nhinit(); /* Init the nfsnode table */ nfsrv_init(0); /* Init server data structures */ nfsrv_initcache(); /* Init the server request cache */ @@ -636,15 +637,14 @@ nfs_init() NQLOADNOVRAM(nqnfsstarttime); nqnfs_prog = txdr_unsigned(NQNFS_PROG); nqnfs_vers = txdr_unsigned(NQNFS_VER1); - nqthead.th_head[0] = &nqthead; - nqthead.th_head[1] = &nqthead; - nqfhead = hashinit(NQLCHSZ, M_NQLEASE, &nqfheadhash); + CIRCLEQ_INIT(&nqtimerhead); + nqfhhashtbl = hashinit(NQLCHSZ, M_NQLEASE, &nqfhhash); } /* * Initialize reply list and start timer */ - nfsreqh.r_prev = nfsreqh.r_next = &nfsreqh; + TAILQ_INIT(&nfs_reqq); nfs_timer(0); /* @@ -689,7 +689,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) register struct vattr *vap; register struct nfsv2_fattr *fp; extern int (**spec_nfsv2nodeop_p)(); - register struct nfsnode *np, *nq, **nhpp; + register struct nfsnode *np; + register struct nfsnodehashhead *nhpp; register long t1; caddr_t dpos, cp2; int error = 0, isnq; @@ -743,10 +744,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) /* * Discard unneeded vnode, but save its nfsnode. */ - nq = np->n_forw; - if (nq) - nq->n_back = np->n_back; - *np->n_back = nq; + LIST_REMOVE(np, n_hash); nvp->v_data = vp->v_data; vp->v_data = NULL; vp->v_op = spec_vnodeop_p; @@ -756,13 +754,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) * Reinitialize aliased node. */ np->n_vnode = nvp; - nhpp = (struct nfsnode **)nfs_hash(&np->n_fh); - nq = *nhpp; - if (nq) - nq->n_back = &np->n_forw; - np->n_forw = nq; - np->n_back = nhpp; - *nhpp = np; + nhpp = nfs_hash(&np->n_fh); + LIST_INSERT_HEAD(nhpp, np, n_hash); *vpp = vp = nvp; } } @@ -794,9 +787,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) vap->va_fileid = fxdr_unsigned(long, fp->fa_nfsfileid); fxdr_nfstime(&fp->fa_nfsatime, &vap->va_atime); vap->va_flags = 0; - vap->va_ctime.ts_sec = fxdr_unsigned(long, fp->fa_nfsctime.nfs_sec); - vap->va_ctime.ts_nsec = 0; - vap->va_gen = fxdr_unsigned(u_long, fp->fa_nfsctime.nfs_usec); + fxdr_nfstime(&fp->fa_nfsctime, &vap->va_ctime); + vap->va_gen = 0; vap->va_filerev = 0; } if (vap->va_size != np->n_size) { @@ -1106,24 +1098,24 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp) * Check/setup credentials. */ if (exflags & MNT_EXKERB) { - uidp = slp->ns_uidh[NUIDHASH(cred->cr_uid)]; - while (uidp) { + for (uidp = NUIDHASH(slp, cred->cr_uid)->lh_first; uidp != 0; + uidp = uidp->nu_hash.le_next) { if (uidp->nu_uid == cred->cr_uid) break; - uidp = uidp->nu_hnext; } - if (uidp) { - cred->cr_uid = uidp->nu_cr.cr_uid; - for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) - cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; - } else { + if (uidp == 0) { vput(*vpp); return (NQNFS_AUTHERR); } + cred->cr_uid = uidp->nu_cr.cr_uid; + for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) + cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; + cred->cr_ngroups = i; } else if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { cred->cr_uid = credanon->cr_uid; for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++) cred->cr_groups[i] = credanon->cr_groups[i]; + cred->cr_ngroups = i; } if (exflags & MNT_EXRDONLY) *rdonlyp = 1; diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c index 5645e45..8cdbfe7 100644 --- a/sys/nfs/nfs_syscalls.c +++ b/sys/nfs/nfs_syscalls.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_syscalls.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_syscalls.c,v 1.3 1994/08/02 07:52:15 davidg Exp $ + * $Id: nfs_syscalls.c,v 1.4 1994/10/02 17:27:02 phk Exp $ */ #include <sys/param.h> @@ -78,8 +78,6 @@ extern int (*nfsrv_procs[NFS_NPROCS])(); extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; extern int nfs_numasync; extern time_t nqnfsstarttime; -extern struct nfsrv_req nsrvq_head; -extern struct nfsd nfsd_head; extern int nqsrv_writeslack; extern int nfsrtton; struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock; @@ -91,7 +89,7 @@ static int modify_flag = 0; static struct nfsdrt nfsdrt; void nfsrv_cleancache(), nfsrv_rcv(), nfsrv_wakenfsd(), nfs_sndunlock(); static void nfsd_rt(); -void nfsrv_slpderef(), nfsrv_init(); +void nfsrv_slpderef(); #define TRUE 1 #define FALSE 0 @@ -141,8 +139,6 @@ getfh(p, uap, retval) return (error); } -static struct nfssvc_sock nfssvc_sockhead; - /* * Nfs server psuedo system call for the nfsd's * Based on the flag value it either: @@ -168,7 +164,7 @@ nfssvc(p, uap, retval) struct nfsd_cargs ncd; struct nfsd *nfsd; struct nfssvc_sock *slp; - struct nfsuid *nuidp, **nuh; + struct nfsuid *nuidp; struct nfsmount *nmp; int error; @@ -178,8 +174,8 @@ nfssvc(p, uap, retval) error = suser(p->p_ucred, &p->p_acflag); if(error) return (error); - while (nfssvc_sockhead.ns_flag & SLP_INIT) { - nfssvc_sockhead.ns_flag |= SLP_WANTINIT; + while (nfssvc_sockhead_flag & SLP_INIT) { + nfssvc_sockhead_flag |= SLP_WANTINIT; (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); } if (uap->flag & NFSSVC_BIOD) @@ -236,11 +232,10 @@ nfssvc(p, uap, retval) * First check to see if another nfsd has already * added this credential. */ - nuidp = slp->ns_uidh[NUIDHASH(nsd->nsd_uid)]; - while (nuidp) { + for (nuidp = NUIDHASH(slp, nsd->nsd_uid)->lh_first; + nuidp != 0; nuidp = nuidp->nu_hash.le_next) { if (nuidp->nu_uid == nsd->nsd_uid) break; - nuidp = nuidp->nu_hnext; } if (!nuidp) { /* @@ -258,27 +253,21 @@ nfssvc(p, uap, retval) free((caddr_t)nuidp, M_NFSUID); } else { if (nuidp == (struct nfsuid *)0) { - nuidp = slp->ns_lruprev; - remque(nuidp); - if (nuidp->nu_hprev) - nuidp->nu_hprev->nu_hnext = - nuidp->nu_hnext; - if (nuidp->nu_hnext) - nuidp->nu_hnext->nu_hprev = - nuidp->nu_hprev; + nuidp = slp->ns_uidlruhead.tqh_first; + LIST_REMOVE(nuidp, nu_hash); + TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, + nu_lru); } nuidp->nu_cr = nsd->nsd_cr; if (nuidp->nu_cr.cr_ngroups > NGROUPS) nuidp->nu_cr.cr_ngroups = NGROUPS; nuidp->nu_cr.cr_ref = 1; nuidp->nu_uid = nsd->nsd_uid; - insque(nuidp, (struct nfsuid *)slp); - nuh = &slp->ns_uidh[NUIDHASH(nsd->nsd_uid)]; - nuidp->nu_hnext = *nuh; - if (nuidp->nu_hnext) - nuidp->nu_hnext->nu_hprev = nuidp; - nuidp->nu_hprev = (struct nfsuid *)0; - *nuh = nuidp; + TAILQ_INSERT_TAIL(&slp->ns_uidlruhead, nuidp, + nu_lru); + LIST_INSERT_HEAD(NUIDHASH(slp, nsd->nsd_uid), + nuidp, nu_hash); + } } } @@ -364,11 +353,10 @@ nfssvc_addsock(fp, mynam) slp = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)slp, sizeof (struct nfssvc_sock)); - slp->ns_prev = nfssvc_sockhead.ns_prev; - slp->ns_prev->ns_next = slp; - slp->ns_next = &nfssvc_sockhead; - nfssvc_sockhead.ns_prev = slp; - slp->ns_lrunext = slp->ns_lruprev = (struct nfsuid *)slp; + slp->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &slp->ns_uidhash); + TAILQ_INIT(&slp->ns_uidlruhead); + TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain); } slp->ns_so = so; slp->ns_nam = mynam; @@ -412,7 +400,7 @@ nfssvc_nfsd(nsd, argp, p) bzero((caddr_t)nd, sizeof (struct nfsd)); nd->nd_procp = p; nd->nd_cr.cr_ref = 1; - insque(nd, &nfsd_head); + TAILQ_INSERT_TAIL(&nfsd_head, nd, nd_chain); nd->nd_nqlflag = NQL_NOVAL; nfs_numnfsd++; } @@ -422,7 +410,7 @@ nfssvc_nfsd(nsd, argp, p) for (;;) { if ((nd->nd_flag & NFSD_REQINPROG) == 0) { while (nd->nd_slp == (struct nfssvc_sock *)0 && - (nfsd_head.nd_flag & NFSD_CHECKSLP) == 0) { + (nfsd_head_flag & NFSD_CHECKSLP) == 0) { nd->nd_flag |= NFSD_WAITING; nfsd_waiting++; error = tsleep((caddr_t)nd, PSOCK | PCATCH, "nfsd", 0); @@ -431,9 +419,9 @@ nfssvc_nfsd(nsd, argp, p) goto done; } if (nd->nd_slp == (struct nfssvc_sock *)0 && - (nfsd_head.nd_flag & NFSD_CHECKSLP)) { - slp = nfssvc_sockhead.ns_next; - while (slp != &nfssvc_sockhead) { + (nfsd_head_flag & NFSD_CHECKSLP) != 0) { + for (slp = nfssvc_sockhead.tqh_first; slp != 0; + slp = slp->ns_chain.tqe_next) { if ((slp->ns_flag & (SLP_VALID | SLP_DOREC)) == (SLP_VALID | SLP_DOREC)) { slp->ns_flag &= ~SLP_DOREC; @@ -441,10 +429,9 @@ nfssvc_nfsd(nsd, argp, p) nd->nd_slp = slp; break; } - slp = slp->ns_next; } - if (slp == &nfssvc_sockhead) - nfsd_head.nd_flag &= ~NFSD_CHECKSLP; + if (slp == 0) + nfsd_head_flag &= ~NFSD_CHECKSLP; } if ((slp = nd->nd_slp) == (struct nfssvc_sock *)0) continue; @@ -504,11 +491,10 @@ nfssvc_nfsd(nsd, argp, p) /* * Check for a mapping already installed. */ - uidp = slp->ns_uidh[NUIDHASH(nd->nd_cr.cr_uid)]; - while (uidp) { + for (uidp = NUIDHASH(slp, nd->nd_cr.cr_uid)->lh_first; + uidp != 0; uidp = uidp->nu_hash.le_next) { if (uidp->nu_uid == nd->nd_cr.cr_uid) break; - uidp = uidp->nu_hnext; } if (!uidp) { nsd->nsd_uid = nd->nd_cr.cr_uid; @@ -637,7 +623,7 @@ nfssvc_nfsd(nsd, argp, p) } } done: - remque(nd); + TAILQ_REMOVE(&nfsd_head, nd, nd_chain); splx(s); free((caddr_t)nd, M_NFSD); nsd->nsd_nfsd = (struct nfsd *)0; @@ -708,8 +694,7 @@ void nfsrv_zapsock(slp) register struct nfssvc_sock *slp; { - register struct nfsuid *nuidp, *onuidp; - register int i; + register struct nfsuid *nuidp, *nnuidp; struct socket *so; struct file *fp; struct mbuf *m; @@ -726,15 +711,13 @@ nfsrv_zapsock(slp) MFREE(slp->ns_nam, m); m_freem(slp->ns_raw); m_freem(slp->ns_rec); - nuidp = slp->ns_lrunext; - while (nuidp != (struct nfsuid *)slp) { - onuidp = nuidp; - nuidp = nuidp->nu_lrunext; - free((caddr_t)onuidp, M_NFSUID); + for (nuidp = slp->ns_uidlruhead.tqh_first; nuidp != 0; + nuidp = nnuidp) { + nnuidp = nuidp->nu_lru.tqe_next; + LIST_REMOVE(nuidp, nu_hash); + TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, nu_lru); + free((caddr_t)nuidp, M_NFSUID); } - slp->ns_lrunext = slp->ns_lruprev = (struct nfsuid *)slp; - for (i = 0; i < NUIDHASHSIZ; i++) - slp->ns_uidh[i] = (struct nfsuid *)0; } } @@ -804,8 +787,7 @@ nfsrv_slpderef(slp) register struct nfssvc_sock *slp; { if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) { - slp->ns_prev->ns_next = slp->ns_next; - slp->ns_next->ns_prev = slp->ns_prev; + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); free((caddr_t)slp, M_NFSSVC); } } @@ -819,48 +801,47 @@ void nfsrv_init(terminating) int terminating; { - register struct nfssvc_sock *slp; - struct nfssvc_sock *oslp; + register struct nfssvc_sock *slp, *nslp; - if (nfssvc_sockhead.ns_flag & SLP_INIT) + if (nfssvc_sockhead_flag & SLP_INIT) panic("nfsd init"); - nfssvc_sockhead.ns_flag |= SLP_INIT; + nfssvc_sockhead_flag |= SLP_INIT; if (terminating) { - slp = nfssvc_sockhead.ns_next; - while (slp != &nfssvc_sockhead) { + for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) { + nslp = slp->ns_chain.tqe_next; if (slp->ns_flag & SLP_VALID) nfsrv_zapsock(slp); - slp->ns_next->ns_prev = slp->ns_prev; - slp->ns_prev->ns_next = slp->ns_next; - oslp = slp; - slp = slp->ns_next; - free((caddr_t)oslp, M_NFSSVC); + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); + free((caddr_t)slp, M_NFSSVC); } nfsrv_cleancache(); /* And clear out server cache */ } + + TAILQ_INIT(&nfssvc_sockhead); + nfssvc_sockhead_flag &= ~SLP_INIT; + if (nfssvc_sockhead_flag & SLP_WANTINIT) { + nfssvc_sockhead_flag &= ~SLP_WANTINIT; + wakeup((caddr_t)&nfssvc_sockhead); + } + + TAILQ_INIT(&nfsd_head); + nfsd_head_flag &= ~NFSD_CHECKSLP; + nfs_udpsock = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock)); + nfs_udpsock->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &nfs_udpsock->ns_uidhash); + TAILQ_INIT(&nfs_udpsock->ns_uidlruhead); + TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain); + nfs_cltpsock = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock)); - nfssvc_sockhead.ns_next = nfs_udpsock; - nfs_udpsock->ns_next = nfs_cltpsock; - nfs_cltpsock->ns_next = &nfssvc_sockhead; - nfssvc_sockhead.ns_prev = nfs_cltpsock; - nfs_cltpsock->ns_prev = nfs_udpsock; - nfs_udpsock->ns_prev = &nfssvc_sockhead; - nfs_udpsock->ns_lrunext = nfs_udpsock->ns_lruprev = - (struct nfsuid *)nfs_udpsock; - nfs_cltpsock->ns_lrunext = nfs_cltpsock->ns_lruprev = - (struct nfsuid *)nfs_cltpsock; - nfsd_head.nd_next = nfsd_head.nd_prev = &nfsd_head; - nfsd_head.nd_flag = 0; - nfssvc_sockhead.ns_flag &= ~SLP_INIT; - if (nfssvc_sockhead.ns_flag & SLP_WANTINIT) { - nfssvc_sockhead.ns_flag &= ~SLP_WANTINIT; - wakeup((caddr_t)&nfssvc_sockhead); - } + nfs_cltpsock->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &nfs_cltpsock->ns_uidhash); + TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead); + TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain); } /* diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c index 375cfc5..9507793 100644 --- a/sys/nfs/nfs_vfsops.c +++ b/sys/nfs/nfs_vfsops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_vfsops.c,v 1.4 1994/09/21 03:47:22 wollman Exp $ + * $Id: nfs_vfsops.c,v 1.5 1994/10/02 17:27:03 phk Exp $ */ #include <sys/param.h> @@ -440,8 +440,7 @@ mountnfs(argp, mp, nam, pth, hst, vpp) nmp->nm_readahead = NFS_DEFRAHEAD; nmp->nm_leaseterm = NQ_DEFLEASE; nmp->nm_deadthresh = NQ_DEADTHRESH; - nmp->nm_tnext = (struct nfsnode *)nmp; - nmp->nm_tprev = (struct nfsnode *)nmp; + CIRCLEQ_INIT(&nmp->nm_timerhead); nmp->nm_inprog = NULLVP; bcopy((caddr_t)argp->fh, (caddr_t)&nmp->nm_fh, sizeof(nfsv2fh_t)); mp->mnt_stat.f_type = MOUNT_NFS; diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index 9bbab54..7032a5a 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94 - * $Id: nfs_vnops.c,v 1.8 1994/10/02 17:27:04 phk Exp $ + * $Id: nfs_vnops.c,v 1.9 1994/10/09 07:35:06 davidg Exp $ */ /* @@ -236,7 +236,6 @@ void nqnfs_clientlease(); */ extern u_long nfs_procids[NFS_NPROCS]; extern u_long nfs_prog, nfs_vers, nfs_true, nfs_false; -extern char nfsiobuf[MAXPHYS+NBPG]; struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; int nfs_numasync = 0; #define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) @@ -482,25 +481,36 @@ nfs_setattr(ap) register struct vattr *vap = ap->a_vap; u_quad_t frev, tsize = 0; - if (vap->va_size != VNOVAL || vap->va_mtime.ts_sec != VNOVAL || - vap->va_atime.ts_sec != VNOVAL) { - if (vap->va_size != VNOVAL) { + if (vap->va_size != VNOVAL) { + switch (vp->v_type) { + case VDIR: + return (EISDIR); + case VCHR: + case VBLK: + if (vap->va_mtime.ts_sec == VNOVAL && + vap->va_atime.ts_sec == VNOVAL && + vap->va_mode == (u_short)VNOVAL && + vap->va_uid == VNOVAL && + vap->va_gid == VNOVAL) + return (0); + vap->va_size = VNOVAL; + break; + default: if (np->n_flag & NMODIFIED) { - if (vap->va_size == 0) - error = nfs_vinvalbuf(vp, 0, ap->a_cred, - ap->a_p, 1); - else - error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, - ap->a_p, 1); - if (error) - return (error); + error = nfs_vinvalbuf(vp, + vap->va_size ? V_SAVE : 0, + ap->a_cred, ap->a_p, 1); + if (error) + return (error); } tsize = np->n_size; np->n_size = np->n_vattr.va_size = vap->va_size; vnode_pager_setsize(vp, (u_long)np->n_size); - } else if ((np->n_flag & NMODIFIED) && - (error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, - ap->a_p, 1)) == EINTR) + } + } else if ((vap->va_mtime.ts_sec != VNOVAL || + vap->va_atime.ts_sec != VNOVAL) && (np->n_flag & NMODIFIED)) { + error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 1); + if (error == EINTR) return (error); } nfsstats.rpccnt[NFSPROC_SETATTR]++; @@ -904,9 +914,11 @@ nfs_writerpc(vp, uiop, cred, ioflags) if (nmp->nm_flag & NFSMNT_NQNFS) { txdr_hyper(&uiop->uio_offset, tl); tl += 2; +#ifdef notyet if (ioflags & IO_APPEND) *tl++ = txdr_unsigned(1); else +#endif *tl++ = 0; } else { *++tl = txdr_unsigned(uiop->uio_offset); @@ -980,6 +992,7 @@ nfs_mknod(ap) vput(dvp); return (error); } + newvp = NULLVP; nfsstats.rpccnt[NFSPROC_CREATE]++; nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)+NFSX_SATTR(isnq)); @@ -1008,6 +1021,8 @@ nfs_mknod(ap) VTONFS(dvp)->n_flag |= NMODIFIED; VTONFS(dvp)->n_attrstamp = 0; vrele(dvp); + if (newvp != NULLVP) + vrele(newvp); return (error); } @@ -1106,11 +1121,23 @@ nfs_remove(ap) caddr_t bpos, dpos; int error = 0; struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct vattr vattr; if (vp->v_usecount > 1) { if (!np->n_sillyrename) error = nfs_sillyrename(dvp, vp, cnp); + else if (VOP_GETATTR(vp, &vattr, cnp->cn_cred, cnp->cn_proc) + == 0 && vattr.va_nlink > 1) + /* + * If we already have a silly name but there are more + * than one links, just proceed with the NFS remove + * request, as the bits will remain available (modulo + * network races). This avoids silently ignoring the + * attempted removal of a non-silly entry. + */ + goto doit; } else { + doit: /* * Purge the name cache so that the chance of a lookup for * the name succeeding while the remove is in progress is @@ -1311,6 +1338,13 @@ nfs_link(ap) return (EXDEV); } + /* + * Push all writes to the server, so that the attribute cache + * doesn't get "out of sync" with the server. + * XXX There should be a better way! + */ + VOP_FSYNC(tdvp, cnp->cn_cred, MNT_WAIT, cnp->cn_proc); + nfsstats.rpccnt[NFSPROC_LINK]++; nfsm_reqhead(tdvp, NFSPROC_LINK, NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); @@ -1321,7 +1355,7 @@ nfs_link(ap) nfsm_reqdone; FREE(cnp->cn_pnbuf, M_NAMEI); VTONFS(tdvp)->n_attrstamp = 0; - VTONFS(tdvp)->n_flag |= NMODIFIED; + VTONFS(vp)->n_flag |= NMODIFIED; VTONFS(vp)->n_attrstamp = 0; vrele(vp); /* @@ -2052,8 +2086,8 @@ nfs_strategy(ap) struct proc *p; int error = 0; - if (bp->b_flags & B_PHYS) - panic("nfs physio"); + if ((bp->b_flags & (B_PHYS|B_ASYNC)) == (B_PHYS|B_ASYNC)) + panic("nfs physio/async"); if (bp->b_flags & B_ASYNC) p = (struct proc *)0; else diff --git a/sys/nfs/nfsm_subs.h b/sys/nfs/nfsm_subs.h index 954a92f..994c0b6 100644 --- a/sys/nfs/nfsm_subs.h +++ b/sys/nfs/nfsm_subs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsm_subs.h 8.1 (Berkeley) 6/16/93 - * $Id: nfsm_subs.h,v 1.3 1994/08/21 06:50:10 paul Exp $ + * $Id: nfsm_subs.h,v 1.4 1994/10/02 17:27:05 phk Exp $ */ #ifndef _NFS_NFSM_SUBS_H_ @@ -264,8 +264,7 @@ extern struct mbuf *nfsm_reqh(); fp->fa_nfsblocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \ txdr_nfstime(&vap->va_atime, &fp->fa_nfsatime); \ txdr_nfstime(&vap->va_mtime, &fp->fa_nfsmtime); \ - fp->fa_nfsctime.nfs_sec = txdr_unsigned(vap->va_ctime.ts_sec); \ - fp->fa_nfsctime.nfs_usec = txdr_unsigned(vap->va_gen); \ + txdr_nfstime(&vap->va_ctime, &fp->fa_nfsctime); \ } else { \ fp->fa_nqblocksize = txdr_unsigned(vap->va_blocksize); \ if (vap->va_type == VFIFO) \ diff --git a/sys/nfs/nfsmount.h b/sys/nfs/nfsmount.h index 78ba00b..99a1b48 100644 --- a/sys/nfs/nfsmount.h +++ b/sys/nfs/nfsmount.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsmount.h 8.1 (Berkeley) 6/10/93 - * $Id: nfsmount.h,v 1.2 1994/08/02 07:52:21 davidg Exp $ + * $Id: nfsmount.h,v 1.3 1994/08/21 06:50:10 paul Exp $ */ #ifndef _NFS_NFSMOUNT_H_ @@ -67,8 +67,7 @@ struct nfsmount { int nm_wsize; /* Max size of write rpc */ int nm_readahead; /* Num. of blocks to readahead */ int nm_leaseterm; /* Term (sec) for NQNFS lease */ - struct nfsnode *nm_tnext; /* Head of lease timer queue */ - struct nfsnode *nm_tprev; + CIRCLEQ_HEAD(, nfsnode) nm_timerhead; /* Head of lease timer queue */ struct vnode *nm_inprog; /* Vnode in prog by nqnfs_clientd() */ uid_t nm_authuid; /* Uid for authenticator */ int nm_authtype; /* Authenticator type */ diff --git a/sys/nfs/nfsnode.h b/sys/nfs/nfsnode.h index 5bb170b..01d0969 100644 --- a/sys/nfs/nfsnode.h +++ b/sys/nfs/nfsnode.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsnode.h 8.4 (Berkeley) 2/13/94 - * $Id: nfsnode.h,v 1.6 1994/09/22 19:38:29 wollman Exp $ + * $Id: nfsnode.h,v 1.7 1994/10/02 17:27:06 phk Exp $ */ #ifndef _NFS_NFSNODE_H_ @@ -60,8 +60,8 @@ struct sillyrename { */ struct nfsnode { - struct nfsnode *n_forw; /* hash, forward */ - struct nfsnode **n_back; /* hash, backward */ + LIST_ENTRY(nfsnode) n_hash; /* Hash chain */ + CIRCLEQ_ENTRY(nfsnode) n_timer; /* Nqnfs timer chain */ nfsv2fh_t n_fh; /* NFS File Handle */ long n_flag; /* Flag for locking.. */ struct vnode *n_vnode; /* vnode associated with this node */ @@ -77,8 +77,6 @@ struct nfsnode { u_quad_t n_brev; /* Modify rev when cached */ u_quad_t n_lrev; /* Modify rev for lease */ time_t n_expiry; /* Lease expiry time */ - struct nfsnode *n_tnext; /* Nqnfs timer chain */ - struct nfsnode *n_tprev; struct sillyrename n_silly; /* Silly rename struct */ struct timeval n_atim; /* Special file times */ struct timeval n_mtim; @@ -107,7 +105,7 @@ struct nfsnode { /* * Queue head for nfsiod's */ -TAILQ_HEAD(nfsbufs, buf) nfs_bufq; +TAILQ_HEAD(, buf) nfs_bufq; #ifdef KERNEL /* diff --git a/sys/nfs/nfsrvcache.h b/sys/nfs/nfsrvcache.h index 00eac6a..b367b9f 100644 --- a/sys/nfs/nfsrvcache.h +++ b/sys/nfs/nfsrvcache.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsrvcache.h 8.1 (Berkeley) 6/10/93 - * $Id: nfsrvcache.h,v 1.2 1994/08/02 07:52:25 davidg Exp $ + * $Id: nfsrvcache.h,v 1.3 1994/08/21 06:50:13 paul Exp $ */ #ifndef _NFS_NFSRVCACHE_H_ @@ -47,10 +47,8 @@ #define NFSRVCACHESIZ 256 struct nfsrvcache { - struct nfsrvcache *rc_forw; /* Hash chain links */ - struct nfsrvcache **rc_back; /* Hash chain links */ - struct nfsrvcache *rc_next; /* Lru list */ - struct nfsrvcache **rc_prev; /* Lru list */ + TAILQ_ENTRY(nfsrvcache) rc_lru; /* LRU chain */ + LIST_ENTRY(nfsrvcache) rc_hash; /* Hash chain */ u_long rc_xid; /* rpc id number */ union { struct mbuf *ru_repmb; /* Reply mbuf list OR */ diff --git a/sys/nfs/nqnfs.h b/sys/nfs/nqnfs.h index 18f242a..0f8f12b 100644 --- a/sys/nfs/nqnfs.h +++ b/sys/nfs/nqnfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nqnfs.h 8.1 (Berkeley) 6/10/93 - * $Id: nqnfs.h,v 1.4 1994/09/22 22:10:45 wollman Exp $ + * $Id: nqnfs.h,v 1.5 1994/10/02 17:27:07 phk Exp $ */ #ifndef _NFS_NQNFS_H_ @@ -66,6 +66,9 @@ * RAM on the server. The default definitions below assume that NOVRAM is not * available. */ +#ifdef HASNVRAM +# undef HASNVRAM +#endif #define NQSTORENOVRAM(t) #define NQLOADNOVRAM(t) @@ -109,9 +112,8 @@ struct nqhost { #define lph_slp lph_un.un_conn.conn_slp struct nqlease { - struct nqlease *lc_chain1[2]; /* Timer queue list (must be first) */ - struct nqlease *lc_fhnext; /* Fhandle hash list */ - struct nqlease **lc_fhprev; + LIST_ENTRY(nqlease) lc_hash; /* Fhandle hash list */ + CIRCLEQ_ENTRY(nqlease) lc_timer; /* Timer queue list */ time_t lc_expiry; /* Expiry time (sec) */ struct nqhost lc_host; /* Host that got lease */ struct nqm *lc_morehosts; /* Other hosts that share read lease */ @@ -187,12 +189,15 @@ struct nqm { /* * List head for timer queue. */ -extern union nqsrvthead { - union nqsrvthead *th_head[2]; - struct nqlease *th_chain[2]; -} nqthead; -extern struct nqlease **nqfhead; -extern u_long nqfheadhash; +CIRCLEQ_HEAD(, nqlease) nqtimerhead; + +/* + * List head for the file handle hash table. + */ +#define NQFHHASH(f) \ + (&nqfhhashtbl[(*((u_long *)(f))) & nqfhhash]) +LIST_HEAD(nqfhhashhead, nqlease) *nqfhhashtbl; +u_long nqfhhash; /* * Nqnfs return status numbers. diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index 844acdc..c79eefb 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.1 (Berkeley) 6/10/93 - * $Id: nfs.h,v 1.4 1994/08/21 06:50:08 paul Exp $ + * $Id: nfs.h,v 1.5 1994/10/02 17:26:54 phk Exp $ */ #ifndef _NFS_NFS_H_ @@ -179,8 +179,7 @@ struct nfsstats { * Nfs outstanding request list element */ struct nfsreq { - struct nfsreq *r_next; - struct nfsreq *r_prev; + TAILQ_ENTRY(nfsreq) r_chain; struct mbuf *r_mreq; struct mbuf *r_mrep; struct mbuf *r_md; @@ -197,6 +196,11 @@ struct nfsreq { struct proc *r_procp; /* Proc that did I/O system call */ }; +/* + * Queue head for nfsreq's + */ +TAILQ_HEAD(, nfsreq) nfs_reqq; + /* Flag values for r_flags */ #define R_TIMING 0x01 /* timing request (in mntp) */ #define R_SENT 0x02 /* request has been sent */ @@ -216,7 +220,8 @@ struct nfsstats nfsstats; * and uid hash lists. */ #define NUIDHASHSIZ 32 -#define NUIDHASH(uid) ((uid) & (NUIDHASHSIZ - 1)) +#define NUIDHASH(sock, uid) \ + (&(sock)->ns_uidhashtbl[(uid) & (sock)->ns_uidhash]) /* * Network address hash list element @@ -227,10 +232,8 @@ union nethostaddr { }; struct nfsuid { - struct nfsuid *nu_lrunext; /* MUST be first */ - struct nfsuid *nu_lruprev; - struct nfsuid *nu_hnext; - struct nfsuid *nu_hprev; + TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ + LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ int nu_flag; /* Flags */ uid_t nu_uid; /* Uid mapped by this entry */ union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ @@ -243,10 +246,11 @@ struct nfsuid { #define NU_INETADDR 0x1 struct nfssvc_sock { - struct nfsuid *ns_lrunext; /* MUST be first */ - struct nfsuid *ns_lruprev; - struct nfssvc_sock *ns_next; - struct nfssvc_sock *ns_prev; + TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ + TAILQ_HEAD(, nfsuid) ns_uidlruhead; + LIST_HEAD(, nfsuid) *ns_uidhashtbl; + u_long ns_uidhash; + int ns_flag; u_long ns_sref; struct file *ns_fp; @@ -260,7 +264,6 @@ struct nfssvc_sock { struct mbuf *ns_rec; struct mbuf *ns_recend; int ns_numuids; - struct nfsuid *ns_uidh[NUIDHASHSIZ]; }; /* Bits for "ns_flag" */ @@ -269,17 +272,18 @@ struct nfssvc_sock { #define SLP_NEEDQ 0x04 #define SLP_DISCONN 0x08 #define SLP_GETSTREAM 0x10 -#define SLP_INIT 0x20 -#define SLP_WANTINIT 0x40 - #define SLP_ALLFLAGS 0xff +TAILQ_HEAD(, nfssvc_sock) nfssvc_sockhead; +int nfssvc_sockhead_flag; +#define SLP_INIT 0x01 +#define SLP_WANTINIT 0x02 + /* * One of these structures is allocated for each nfsd. */ struct nfsd { - struct nfsd *nd_next; /* Must be first */ - struct nfsd *nd_prev; + TAILQ_ENTRY(nfsd) nd_chain; /* List of all nfsd's */ int nd_flag; /* NFSD_ flags */ struct nfssvc_sock *nd_slp; /* Current socket */ struct mbuf *nd_nam; /* Client addr for datagram req. */ @@ -297,11 +301,15 @@ struct nfsd { struct proc *nd_procp; /* Proc ptr */ }; +/* Bits for "nd_flag" */ #define NFSD_WAITING 0x01 -#define NFSD_CHECKSLP 0x02 -#define NFSD_REQINPROG 0x04 -#define NFSD_NEEDAUTH 0x08 -#define NFSD_AUTHFAIL 0x10 +#define NFSD_REQINPROG 0x02 +#define NFSD_NEEDAUTH 0x04 +#define NFSD_AUTHFAIL 0x08 + +TAILQ_HEAD(, nfsd) nfsd_head; +int nfsd_head_flag; +#define NFSD_CHECKSLP 0x01 int nfs_reply __P((struct nfsreq *)); int nfs_getreq __P((struct nfsd *,int)); @@ -335,7 +343,7 @@ int nfs_adv __P((struct mbuf **,caddr_t *,int,int)); int nfsrv_getstream __P((struct nfssvc_sock *,int)); void nfs_nhinit __P((void)); void nfs_timer __P((void*)); -struct nfsnode ** nfs_hash __P((nfsv2fh_t *)); +struct nfsnodehashhead * nfs_hash __P((nfsv2fh_t *)); int nfssvc_iod __P((struct proc *)); int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t,struct proc *)); int nfssvc_addsock __P((struct file *,struct mbuf *)); diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index deede73..4d75cf8 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.5 (Berkeley) 1/4/94 - * $Id: nfs_bio.c,v 1.5 1994/08/18 22:35:35 wollman Exp $ + * $Id: nfs_bio.c,v 1.6 1994/10/02 17:26:55 phk Exp $ */ #include <sys/param.h> @@ -438,6 +438,11 @@ nfs_write(ap) do { /* + * XXX make sure we aren't cached in the VM page cache + */ + (void)vnode_pager_uncache(vp); + + /* * Check for a valid write lease. * If non-cachable, just do the rpc */ @@ -715,9 +720,28 @@ nfs_doio(bp, cr, p) /* * Historically, paging was done with physio, but no more. */ - if (bp->b_flags & B_PHYS) - panic("doio phys"); - if (bp->b_flags & B_READ) { + if (bp->b_flags & B_PHYS) { + /* + * ...though reading /dev/drum still gets us here. + */ + io.iov_len = uiop->uio_resid = bp->b_bcount; + /* mapping was done by vmapbuf() */ + io.iov_base = bp->b_data; + uiop->uio_offset = bp->b_blkno * DEV_BSIZE; + if (bp->b_flags & B_READ) { + uiop->uio_rw = UIO_READ; + nfsstats.read_physios++; + error = nfs_readrpc(vp, uiop, cr); + } else { + uiop->uio_rw = UIO_WRITE; + nfsstats.write_physios++; + error = nfs_writerpc(vp, uiop, cr,0); + } + if (error) { + bp->b_flags |= B_ERROR; + bp->b_error = error; + } + } else if (bp->b_flags & B_READ) { io.iov_len = uiop->uio_resid = bp->b_bcount; io.iov_base = bp->b_data; uiop->uio_rw = UIO_READ; @@ -749,6 +773,7 @@ nfs_doio(bp, cr, p) } if (p && (vp->v_flag & VTEXT) && (((nmp->nm_flag & NFSMNT_NQNFS) && + NQNFS_CKINVALID(vp, np, NQL_READ) && np->n_lrev != np->n_brev) || (!(nmp->nm_flag & NFSMNT_NQNFS) && np->n_mtime != np->n_vattr.va_mtime.ts_sec))) { diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index 5645e45..8cdbfe7 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_syscalls.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_syscalls.c,v 1.3 1994/08/02 07:52:15 davidg Exp $ + * $Id: nfs_syscalls.c,v 1.4 1994/10/02 17:27:02 phk Exp $ */ #include <sys/param.h> @@ -78,8 +78,6 @@ extern int (*nfsrv_procs[NFS_NPROCS])(); extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; extern int nfs_numasync; extern time_t nqnfsstarttime; -extern struct nfsrv_req nsrvq_head; -extern struct nfsd nfsd_head; extern int nqsrv_writeslack; extern int nfsrtton; struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock; @@ -91,7 +89,7 @@ static int modify_flag = 0; static struct nfsdrt nfsdrt; void nfsrv_cleancache(), nfsrv_rcv(), nfsrv_wakenfsd(), nfs_sndunlock(); static void nfsd_rt(); -void nfsrv_slpderef(), nfsrv_init(); +void nfsrv_slpderef(); #define TRUE 1 #define FALSE 0 @@ -141,8 +139,6 @@ getfh(p, uap, retval) return (error); } -static struct nfssvc_sock nfssvc_sockhead; - /* * Nfs server psuedo system call for the nfsd's * Based on the flag value it either: @@ -168,7 +164,7 @@ nfssvc(p, uap, retval) struct nfsd_cargs ncd; struct nfsd *nfsd; struct nfssvc_sock *slp; - struct nfsuid *nuidp, **nuh; + struct nfsuid *nuidp; struct nfsmount *nmp; int error; @@ -178,8 +174,8 @@ nfssvc(p, uap, retval) error = suser(p->p_ucred, &p->p_acflag); if(error) return (error); - while (nfssvc_sockhead.ns_flag & SLP_INIT) { - nfssvc_sockhead.ns_flag |= SLP_WANTINIT; + while (nfssvc_sockhead_flag & SLP_INIT) { + nfssvc_sockhead_flag |= SLP_WANTINIT; (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); } if (uap->flag & NFSSVC_BIOD) @@ -236,11 +232,10 @@ nfssvc(p, uap, retval) * First check to see if another nfsd has already * added this credential. */ - nuidp = slp->ns_uidh[NUIDHASH(nsd->nsd_uid)]; - while (nuidp) { + for (nuidp = NUIDHASH(slp, nsd->nsd_uid)->lh_first; + nuidp != 0; nuidp = nuidp->nu_hash.le_next) { if (nuidp->nu_uid == nsd->nsd_uid) break; - nuidp = nuidp->nu_hnext; } if (!nuidp) { /* @@ -258,27 +253,21 @@ nfssvc(p, uap, retval) free((caddr_t)nuidp, M_NFSUID); } else { if (nuidp == (struct nfsuid *)0) { - nuidp = slp->ns_lruprev; - remque(nuidp); - if (nuidp->nu_hprev) - nuidp->nu_hprev->nu_hnext = - nuidp->nu_hnext; - if (nuidp->nu_hnext) - nuidp->nu_hnext->nu_hprev = - nuidp->nu_hprev; + nuidp = slp->ns_uidlruhead.tqh_first; + LIST_REMOVE(nuidp, nu_hash); + TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, + nu_lru); } nuidp->nu_cr = nsd->nsd_cr; if (nuidp->nu_cr.cr_ngroups > NGROUPS) nuidp->nu_cr.cr_ngroups = NGROUPS; nuidp->nu_cr.cr_ref = 1; nuidp->nu_uid = nsd->nsd_uid; - insque(nuidp, (struct nfsuid *)slp); - nuh = &slp->ns_uidh[NUIDHASH(nsd->nsd_uid)]; - nuidp->nu_hnext = *nuh; - if (nuidp->nu_hnext) - nuidp->nu_hnext->nu_hprev = nuidp; - nuidp->nu_hprev = (struct nfsuid *)0; - *nuh = nuidp; + TAILQ_INSERT_TAIL(&slp->ns_uidlruhead, nuidp, + nu_lru); + LIST_INSERT_HEAD(NUIDHASH(slp, nsd->nsd_uid), + nuidp, nu_hash); + } } } @@ -364,11 +353,10 @@ nfssvc_addsock(fp, mynam) slp = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)slp, sizeof (struct nfssvc_sock)); - slp->ns_prev = nfssvc_sockhead.ns_prev; - slp->ns_prev->ns_next = slp; - slp->ns_next = &nfssvc_sockhead; - nfssvc_sockhead.ns_prev = slp; - slp->ns_lrunext = slp->ns_lruprev = (struct nfsuid *)slp; + slp->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &slp->ns_uidhash); + TAILQ_INIT(&slp->ns_uidlruhead); + TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain); } slp->ns_so = so; slp->ns_nam = mynam; @@ -412,7 +400,7 @@ nfssvc_nfsd(nsd, argp, p) bzero((caddr_t)nd, sizeof (struct nfsd)); nd->nd_procp = p; nd->nd_cr.cr_ref = 1; - insque(nd, &nfsd_head); + TAILQ_INSERT_TAIL(&nfsd_head, nd, nd_chain); nd->nd_nqlflag = NQL_NOVAL; nfs_numnfsd++; } @@ -422,7 +410,7 @@ nfssvc_nfsd(nsd, argp, p) for (;;) { if ((nd->nd_flag & NFSD_REQINPROG) == 0) { while (nd->nd_slp == (struct nfssvc_sock *)0 && - (nfsd_head.nd_flag & NFSD_CHECKSLP) == 0) { + (nfsd_head_flag & NFSD_CHECKSLP) == 0) { nd->nd_flag |= NFSD_WAITING; nfsd_waiting++; error = tsleep((caddr_t)nd, PSOCK | PCATCH, "nfsd", 0); @@ -431,9 +419,9 @@ nfssvc_nfsd(nsd, argp, p) goto done; } if (nd->nd_slp == (struct nfssvc_sock *)0 && - (nfsd_head.nd_flag & NFSD_CHECKSLP)) { - slp = nfssvc_sockhead.ns_next; - while (slp != &nfssvc_sockhead) { + (nfsd_head_flag & NFSD_CHECKSLP) != 0) { + for (slp = nfssvc_sockhead.tqh_first; slp != 0; + slp = slp->ns_chain.tqe_next) { if ((slp->ns_flag & (SLP_VALID | SLP_DOREC)) == (SLP_VALID | SLP_DOREC)) { slp->ns_flag &= ~SLP_DOREC; @@ -441,10 +429,9 @@ nfssvc_nfsd(nsd, argp, p) nd->nd_slp = slp; break; } - slp = slp->ns_next; } - if (slp == &nfssvc_sockhead) - nfsd_head.nd_flag &= ~NFSD_CHECKSLP; + if (slp == 0) + nfsd_head_flag &= ~NFSD_CHECKSLP; } if ((slp = nd->nd_slp) == (struct nfssvc_sock *)0) continue; @@ -504,11 +491,10 @@ nfssvc_nfsd(nsd, argp, p) /* * Check for a mapping already installed. */ - uidp = slp->ns_uidh[NUIDHASH(nd->nd_cr.cr_uid)]; - while (uidp) { + for (uidp = NUIDHASH(slp, nd->nd_cr.cr_uid)->lh_first; + uidp != 0; uidp = uidp->nu_hash.le_next) { if (uidp->nu_uid == nd->nd_cr.cr_uid) break; - uidp = uidp->nu_hnext; } if (!uidp) { nsd->nsd_uid = nd->nd_cr.cr_uid; @@ -637,7 +623,7 @@ nfssvc_nfsd(nsd, argp, p) } } done: - remque(nd); + TAILQ_REMOVE(&nfsd_head, nd, nd_chain); splx(s); free((caddr_t)nd, M_NFSD); nsd->nsd_nfsd = (struct nfsd *)0; @@ -708,8 +694,7 @@ void nfsrv_zapsock(slp) register struct nfssvc_sock *slp; { - register struct nfsuid *nuidp, *onuidp; - register int i; + register struct nfsuid *nuidp, *nnuidp; struct socket *so; struct file *fp; struct mbuf *m; @@ -726,15 +711,13 @@ nfsrv_zapsock(slp) MFREE(slp->ns_nam, m); m_freem(slp->ns_raw); m_freem(slp->ns_rec); - nuidp = slp->ns_lrunext; - while (nuidp != (struct nfsuid *)slp) { - onuidp = nuidp; - nuidp = nuidp->nu_lrunext; - free((caddr_t)onuidp, M_NFSUID); + for (nuidp = slp->ns_uidlruhead.tqh_first; nuidp != 0; + nuidp = nnuidp) { + nnuidp = nuidp->nu_lru.tqe_next; + LIST_REMOVE(nuidp, nu_hash); + TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, nu_lru); + free((caddr_t)nuidp, M_NFSUID); } - slp->ns_lrunext = slp->ns_lruprev = (struct nfsuid *)slp; - for (i = 0; i < NUIDHASHSIZ; i++) - slp->ns_uidh[i] = (struct nfsuid *)0; } } @@ -804,8 +787,7 @@ nfsrv_slpderef(slp) register struct nfssvc_sock *slp; { if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) { - slp->ns_prev->ns_next = slp->ns_next; - slp->ns_next->ns_prev = slp->ns_prev; + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); free((caddr_t)slp, M_NFSSVC); } } @@ -819,48 +801,47 @@ void nfsrv_init(terminating) int terminating; { - register struct nfssvc_sock *slp; - struct nfssvc_sock *oslp; + register struct nfssvc_sock *slp, *nslp; - if (nfssvc_sockhead.ns_flag & SLP_INIT) + if (nfssvc_sockhead_flag & SLP_INIT) panic("nfsd init"); - nfssvc_sockhead.ns_flag |= SLP_INIT; + nfssvc_sockhead_flag |= SLP_INIT; if (terminating) { - slp = nfssvc_sockhead.ns_next; - while (slp != &nfssvc_sockhead) { + for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) { + nslp = slp->ns_chain.tqe_next; if (slp->ns_flag & SLP_VALID) nfsrv_zapsock(slp); - slp->ns_next->ns_prev = slp->ns_prev; - slp->ns_prev->ns_next = slp->ns_next; - oslp = slp; - slp = slp->ns_next; - free((caddr_t)oslp, M_NFSSVC); + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); + free((caddr_t)slp, M_NFSSVC); } nfsrv_cleancache(); /* And clear out server cache */ } + + TAILQ_INIT(&nfssvc_sockhead); + nfssvc_sockhead_flag &= ~SLP_INIT; + if (nfssvc_sockhead_flag & SLP_WANTINIT) { + nfssvc_sockhead_flag &= ~SLP_WANTINIT; + wakeup((caddr_t)&nfssvc_sockhead); + } + + TAILQ_INIT(&nfsd_head); + nfsd_head_flag &= ~NFSD_CHECKSLP; + nfs_udpsock = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock)); + nfs_udpsock->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &nfs_udpsock->ns_uidhash); + TAILQ_INIT(&nfs_udpsock->ns_uidlruhead); + TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain); + nfs_cltpsock = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock)); - nfssvc_sockhead.ns_next = nfs_udpsock; - nfs_udpsock->ns_next = nfs_cltpsock; - nfs_cltpsock->ns_next = &nfssvc_sockhead; - nfssvc_sockhead.ns_prev = nfs_cltpsock; - nfs_cltpsock->ns_prev = nfs_udpsock; - nfs_udpsock->ns_prev = &nfssvc_sockhead; - nfs_udpsock->ns_lrunext = nfs_udpsock->ns_lruprev = - (struct nfsuid *)nfs_udpsock; - nfs_cltpsock->ns_lrunext = nfs_cltpsock->ns_lruprev = - (struct nfsuid *)nfs_cltpsock; - nfsd_head.nd_next = nfsd_head.nd_prev = &nfsd_head; - nfsd_head.nd_flag = 0; - nfssvc_sockhead.ns_flag &= ~SLP_INIT; - if (nfssvc_sockhead.ns_flag & SLP_WANTINIT) { - nfssvc_sockhead.ns_flag &= ~SLP_WANTINIT; - wakeup((caddr_t)&nfssvc_sockhead); - } + nfs_cltpsock->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &nfs_cltpsock->ns_uidhash); + TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead); + TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain); } /* diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c index c5804d5..909f9e0 100644 --- a/sys/nfsclient/nfs_node.c +++ b/sys/nfsclient/nfs_node.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_node.c 8.2 (Berkeley) 12/30/93 - * $Id: nfs_node.c,v 1.5 1994/10/02 17:26:56 phk Exp $ + * $Id: nfs_node.c,v 1.6 1994/10/06 21:06:56 davidg Exp $ */ #include <sys/param.h> @@ -53,9 +53,10 @@ #include <nfs/nfsmount.h> #include <nfs/nqnfs.h> -struct nfsnode **nheadhashtbl; -u_long nheadhash; -#define NFSNOHASH(fhsum) ((fhsum)&nheadhash) +#define NFSNOHASH(fhsum) \ + (&nfsnodehashtbl[(fhsum) & nfsnodehash]) +LIST_HEAD(nfsnodehashhead, nfsnode) *nfsnodehashtbl; +u_long nfsnodehash; #define TRUE 1 #define FALSE 0 @@ -72,13 +73,13 @@ nfs_nhinit() if ((sizeof(struct nfsnode) - 1) & sizeof(struct nfsnode)) printf("nfs_nhinit: bad size %d\n", sizeof(struct nfsnode)); #endif /* not lint */ - nheadhashtbl = hashinit(desiredvnodes, M_NFSNODE, &nheadhash); + nfsnodehashtbl = hashinit(desiredvnodes, M_NFSNODE, &nfsnodehash); } /* * Compute an entry in the NFS hash table structure */ -struct nfsnode ** +struct nfsnodehashhead * nfs_hash(fhp) register nfsv2fh_t *fhp; { @@ -90,7 +91,7 @@ nfs_hash(fhp) fhsum = 0; for (i = 0; i < NFSX_FH; i++) fhsum += *fhpp++; - return (&nheadhashtbl[NFSNOHASH(fhsum)]); + return (NFSNOHASH(fhsum)); } /* @@ -105,7 +106,8 @@ nfs_nget(mntp, fhp, npp) register nfsv2fh_t *fhp; struct nfsnode **npp; { - register struct nfsnode *np, *nq, **nhpp; + register struct nfsnode *np; + struct nfsnodehashhead *nhpp; register struct vnode *vp; extern int (**nfsv2_vnodeop_p)(); struct vnode *nvp; @@ -113,7 +115,7 @@ nfs_nget(mntp, fhp, npp) nhpp = nfs_hash(fhp); loop: - for (np = *nhpp; np; np = np->n_forw) { + for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) { if (mntp != NFSTOV(np)->v_mount || bcmp((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH)) continue; @@ -136,12 +138,7 @@ loop: * Insert the nfsnode in the hash queue for its new file handle */ np->n_flag = 0; - nq = *nhpp; - if (nq) - nq->n_back = &np->n_forw; - np->n_forw = nq; - np->n_back = nhpp; - *nhpp = np; + LIST_INSERT_HEAD(nhpp, np, n_hash); bcopy((caddr_t)fhp, (caddr_t)&np->n_fh, NFSX_FH); np->n_attrstamp = 0; np->n_direofoffset = 0; @@ -153,7 +150,7 @@ loop: np->n_brev = 0; np->n_lrev = 0; np->n_expiry = (time_t)0; - np->n_tnext = (struct nfsnode *)0; + np->n_timer.cqe_next = (struct nfsnode *)0; } *npp = np; return (0); @@ -204,31 +201,18 @@ nfs_reclaim(ap) register struct vnode *vp = ap->a_vp; register struct nfsnode *np = VTONFS(vp); register struct nfsmount *nmp = VFSTONFS(vp->v_mount); - register struct nfsnode *nq; extern int prtactive; if (prtactive && vp->v_usecount != 0) vprint("nfs_reclaim: pushing active", vp); - /* - * Remove the nfsnode from its hash chain. - */ - nq = np->n_forw; - if (nq) - nq->n_back = np->n_back; - *np->n_back = nq; + + LIST_REMOVE(np, n_hash); /* * For nqnfs, take it off the timer queue as required. */ - if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_tnext) { - if (np->n_tnext == (struct nfsnode *)nmp) - nmp->nm_tprev = np->n_tprev; - else - np->n_tnext->n_tprev = np->n_tprev; - if (np->n_tprev == (struct nfsnode *)nmp) - nmp->nm_tnext = np->n_tnext; - else - np->n_tprev->n_tnext = np->n_tnext; + if ((nmp->nm_flag & NFSMNT_NQNFS) && np->n_timer.cqe_next != 0) { + CIRCLEQ_REMOVE(&nmp->nm_timerhead, np, n_timer); } cache_purge(vp); FREE(vp->v_data, M_NFSNODE); diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 4cc719f..27c4561 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94 - * $Id: nfs_socket.c,v 1.3 1994/08/02 07:52:11 davidg Exp $ + * $Id: nfs_socket.c,v 1.4 1994/10/02 17:26:59 phk Exp $ */ /* @@ -57,6 +57,7 @@ #include <netinet/in.h> #include <netinet/tcp.h> + #include <nfs/rpcv2.h> #include <nfs/nfsv2.h> #include <nfs/nfs.h> @@ -67,6 +68,8 @@ #include <nfs/nfsrtt.h> #include <nfs/nqnfs.h> +#include <machine/clock.h> /* for inittodr */ + #define TRUE 1 #define FALSE 0 @@ -158,7 +161,6 @@ void nfs_rcvunlock(), nqnfs_serverd(), nqnfs_clientlease(); struct mbuf *nfsm_rpchead(); int nfsrtton = 0; struct nfsrtt nfsrtt; -struct nfsd nfsd_head; int nfsrv_null(), nfsrv_getattr(), @@ -208,8 +210,6 @@ int (*nfsrv_procs[NFS_NPROCS])() = { nqnfsrv_access, }; -struct nfsreq nfsreqh; - /* * Initialize sockets and congestion for a new NFS connection. * We do not free the sockaddr if error. @@ -375,11 +375,9 @@ nfs_reconnect(rep) * Loop through outstanding request list and fix up all requests * on old socket. */ - rp = nfsreqh.r_next; - while (rp != &nfsreqh) { + for (rp = nfs_reqq.tqh_first; rp != 0; rp = rp->r_chain.tqe_next) { if (rp->r_nmp == nmp) rp->r_flags |= R_MUSTRESEND; - rp = rp->r_next; } return (0); } @@ -769,8 +767,8 @@ nfsmout: * Loop through the request list to match up the reply * Iff no match, just drop the datagram */ - rep = nfsreqh.r_next; - while (rep != &nfsreqh) { + for (rep = nfs_reqq.tqh_first; rep != 0; + rep = rep->r_chain.tqe_next) { if (rep->r_mrep == NULL && rxid == rep->r_xid) { /* Found it.. */ rep->r_mrep = mrep; @@ -832,13 +830,12 @@ nfsmout: nmp->nm_timeouts = 0; break; } - rep = rep->r_next; } /* * If not matched to a request, drop it. * If it's mine, get out. */ - if (rep == &nfsreqh) { + if (rep == 0) { nfsstats.rpcunexpected++; m_freem(mrep); } else if (rep == myrep) { @@ -878,7 +875,6 @@ nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp) register int i; struct nfsmount *nmp; struct mbuf *md, *mheadend; - struct nfsreq *reph; struct nfsnode *np; time_t reqtime, waituntil; caddr_t dpos, cp2; @@ -964,11 +960,7 @@ tryagain: * to put it LAST so timer finds oldest requests first. */ s = splsoftclock(); - reph = &nfsreqh; - reph->r_prev->r_next = rep; - rep->r_prev = reph->r_prev; - reph->r_prev = rep; - rep->r_next = reph; + TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain); /* Get send time for nqnfs */ reqtime = time.tv_sec; @@ -1009,8 +1001,7 @@ tryagain: * RPC done, unlink the request. */ s = splsoftclock(); - rep->r_prev->r_next = rep->r_next; - rep->r_next->r_prev = rep->r_prev; + TAILQ_REMOVE(&nfs_reqq, rep, r_chain); splx(s); /* @@ -1167,7 +1158,7 @@ nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp) tl = mtod(mreq, u_long *); mreq->m_len = 6*NFSX_UNSIGNED; bpos = ((caddr_t)tl)+mreq->m_len; - *tl++ = nd->nd_retxid; + *tl++ = txdr_unsigned(nd->nd_retxid); *tl++ = rpc_reply; if (err == ERPCMISMATCH || err == NQNFS_AUTHERR) { *tl++ = rpc_msgdenied; @@ -1255,7 +1246,7 @@ nfs_timer(arg) int s, error; s = splnet(); - for (rep = nfsreqh.r_next; rep != &nfsreqh; rep = rep->r_next) { + for (rep = nfs_reqq.tqh_first; rep != 0; rep = rep->r_chain.tqe_next) { nmp = rep->r_nmp; if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) continue; @@ -1842,7 +1833,7 @@ nfs_getreq(nd, has_header) dpos = nd->nd_dpos; if (has_header) { nfsm_dissect(tl, u_long *, 10*NFSX_UNSIGNED); - nd->nd_retxid = *tl++; + nd->nd_retxid = fxdr_unsigned(u_long, *tl++); if (*tl++ != rpc_call) { m_freem(mrep); return (EBADRPC); @@ -1980,11 +1971,11 @@ void nfsrv_wakenfsd(slp) struct nfssvc_sock *slp; { - register struct nfsd *nd = nfsd_head.nd_next; + register struct nfsd *nd; if ((slp->ns_flag & SLP_VALID) == 0) return; - while (nd != (struct nfsd *)&nfsd_head) { + for (nd = nfsd_head.tqh_first; nd != 0; nd = nd->nd_chain.tqe_next) { if (nd->nd_flag & NFSD_WAITING) { nd->nd_flag &= ~NFSD_WAITING; if (nd->nd_slp) @@ -1994,10 +1985,9 @@ nfsrv_wakenfsd(slp) wakeup((caddr_t)nd); return; } - nd = nd->nd_next; } slp->ns_flag |= SLP_DOREC; - nfsd_head.nd_flag |= NFSD_CHECKSLP; + nfsd_head_flag |= NFSD_CHECKSLP; } int diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index ee8200c..9b2ef80 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_subs.c,v 1.5 1994/09/22 22:10:44 wollman Exp $ + * $Id: nfs_subs.c,v 1.6 1994/10/02 17:27:01 phk Exp $ */ /* @@ -94,7 +94,6 @@ u_long nfs_vers, nfs_prog, nfs_true, nfs_false; static u_long nfs_xid = 0; enum vtype ntov_type[7] = { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON }; extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; -extern struct nfsreq nfsreqh; extern int nqnfs_piggy[NFS_NPROCS]; extern struct nfsrtt nfsrtt; extern time_t nqnfsstarttime; @@ -110,6 +109,8 @@ struct nfssvc_args; extern int nfssvc(struct proc *, struct nfssvc_args *, int *); #endif +LIST_HEAD(nfsnodehashhead, nfsnode); + /* * Create the header for an rpc request packet * The hsiz is the size of the rest of the nfs request header. @@ -615,6 +616,7 @@ nfs_init() nfs_prog = txdr_unsigned(NFS_PROG); nfs_true = txdr_unsigned(TRUE); nfs_false = txdr_unsigned(FALSE); + nfs_xdrneg1 = txdr_unsigned(-1); /* Loop thru nfs procids */ for (i = 0; i < NFS_NPROCS; i++) nfs_procids[i] = txdr_unsigned(i); @@ -622,7 +624,6 @@ nfs_init() for (i = 0; i < NFS_MAXASYNCDAEMON; i++) nfs_iodwant[i] = (struct proc *)0; TAILQ_INIT(&nfs_bufq); - nfs_xdrneg1 = txdr_unsigned(-1); nfs_nhinit(); /* Init the nfsnode table */ nfsrv_init(0); /* Init server data structures */ nfsrv_initcache(); /* Init the server request cache */ @@ -636,15 +637,14 @@ nfs_init() NQLOADNOVRAM(nqnfsstarttime); nqnfs_prog = txdr_unsigned(NQNFS_PROG); nqnfs_vers = txdr_unsigned(NQNFS_VER1); - nqthead.th_head[0] = &nqthead; - nqthead.th_head[1] = &nqthead; - nqfhead = hashinit(NQLCHSZ, M_NQLEASE, &nqfheadhash); + CIRCLEQ_INIT(&nqtimerhead); + nqfhhashtbl = hashinit(NQLCHSZ, M_NQLEASE, &nqfhhash); } /* * Initialize reply list and start timer */ - nfsreqh.r_prev = nfsreqh.r_next = &nfsreqh; + TAILQ_INIT(&nfs_reqq); nfs_timer(0); /* @@ -689,7 +689,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) register struct vattr *vap; register struct nfsv2_fattr *fp; extern int (**spec_nfsv2nodeop_p)(); - register struct nfsnode *np, *nq, **nhpp; + register struct nfsnode *np; + register struct nfsnodehashhead *nhpp; register long t1; caddr_t dpos, cp2; int error = 0, isnq; @@ -743,10 +744,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) /* * Discard unneeded vnode, but save its nfsnode. */ - nq = np->n_forw; - if (nq) - nq->n_back = np->n_back; - *np->n_back = nq; + LIST_REMOVE(np, n_hash); nvp->v_data = vp->v_data; vp->v_data = NULL; vp->v_op = spec_vnodeop_p; @@ -756,13 +754,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) * Reinitialize aliased node. */ np->n_vnode = nvp; - nhpp = (struct nfsnode **)nfs_hash(&np->n_fh); - nq = *nhpp; - if (nq) - nq->n_back = &np->n_forw; - np->n_forw = nq; - np->n_back = nhpp; - *nhpp = np; + nhpp = nfs_hash(&np->n_fh); + LIST_INSERT_HEAD(nhpp, np, n_hash); *vpp = vp = nvp; } } @@ -794,9 +787,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) vap->va_fileid = fxdr_unsigned(long, fp->fa_nfsfileid); fxdr_nfstime(&fp->fa_nfsatime, &vap->va_atime); vap->va_flags = 0; - vap->va_ctime.ts_sec = fxdr_unsigned(long, fp->fa_nfsctime.nfs_sec); - vap->va_ctime.ts_nsec = 0; - vap->va_gen = fxdr_unsigned(u_long, fp->fa_nfsctime.nfs_usec); + fxdr_nfstime(&fp->fa_nfsctime, &vap->va_ctime); + vap->va_gen = 0; vap->va_filerev = 0; } if (vap->va_size != np->n_size) { @@ -1106,24 +1098,24 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp) * Check/setup credentials. */ if (exflags & MNT_EXKERB) { - uidp = slp->ns_uidh[NUIDHASH(cred->cr_uid)]; - while (uidp) { + for (uidp = NUIDHASH(slp, cred->cr_uid)->lh_first; uidp != 0; + uidp = uidp->nu_hash.le_next) { if (uidp->nu_uid == cred->cr_uid) break; - uidp = uidp->nu_hnext; } - if (uidp) { - cred->cr_uid = uidp->nu_cr.cr_uid; - for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) - cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; - } else { + if (uidp == 0) { vput(*vpp); return (NQNFS_AUTHERR); } + cred->cr_uid = uidp->nu_cr.cr_uid; + for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) + cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; + cred->cr_ngroups = i; } else if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { cred->cr_uid = credanon->cr_uid; for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++) cred->cr_groups[i] = credanon->cr_groups[i]; + cred->cr_ngroups = i; } if (exflags & MNT_EXRDONLY) *rdonlyp = 1; diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 375cfc5..9507793 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vfsops.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_vfsops.c,v 1.4 1994/09/21 03:47:22 wollman Exp $ + * $Id: nfs_vfsops.c,v 1.5 1994/10/02 17:27:03 phk Exp $ */ #include <sys/param.h> @@ -440,8 +440,7 @@ mountnfs(argp, mp, nam, pth, hst, vpp) nmp->nm_readahead = NFS_DEFRAHEAD; nmp->nm_leaseterm = NQ_DEFLEASE; nmp->nm_deadthresh = NQ_DEADTHRESH; - nmp->nm_tnext = (struct nfsnode *)nmp; - nmp->nm_tprev = (struct nfsnode *)nmp; + CIRCLEQ_INIT(&nmp->nm_timerhead); nmp->nm_inprog = NULLVP; bcopy((caddr_t)argp->fh, (caddr_t)&nmp->nm_fh, sizeof(nfsv2fh_t)); mp->mnt_stat.f_type = MOUNT_NFS; diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 9bbab54..7032a5a 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94 - * $Id: nfs_vnops.c,v 1.8 1994/10/02 17:27:04 phk Exp $ + * $Id: nfs_vnops.c,v 1.9 1994/10/09 07:35:06 davidg Exp $ */ /* @@ -236,7 +236,6 @@ void nqnfs_clientlease(); */ extern u_long nfs_procids[NFS_NPROCS]; extern u_long nfs_prog, nfs_vers, nfs_true, nfs_false; -extern char nfsiobuf[MAXPHYS+NBPG]; struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; int nfs_numasync = 0; #define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) @@ -482,25 +481,36 @@ nfs_setattr(ap) register struct vattr *vap = ap->a_vap; u_quad_t frev, tsize = 0; - if (vap->va_size != VNOVAL || vap->va_mtime.ts_sec != VNOVAL || - vap->va_atime.ts_sec != VNOVAL) { - if (vap->va_size != VNOVAL) { + if (vap->va_size != VNOVAL) { + switch (vp->v_type) { + case VDIR: + return (EISDIR); + case VCHR: + case VBLK: + if (vap->va_mtime.ts_sec == VNOVAL && + vap->va_atime.ts_sec == VNOVAL && + vap->va_mode == (u_short)VNOVAL && + vap->va_uid == VNOVAL && + vap->va_gid == VNOVAL) + return (0); + vap->va_size = VNOVAL; + break; + default: if (np->n_flag & NMODIFIED) { - if (vap->va_size == 0) - error = nfs_vinvalbuf(vp, 0, ap->a_cred, - ap->a_p, 1); - else - error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, - ap->a_p, 1); - if (error) - return (error); + error = nfs_vinvalbuf(vp, + vap->va_size ? V_SAVE : 0, + ap->a_cred, ap->a_p, 1); + if (error) + return (error); } tsize = np->n_size; np->n_size = np->n_vattr.va_size = vap->va_size; vnode_pager_setsize(vp, (u_long)np->n_size); - } else if ((np->n_flag & NMODIFIED) && - (error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, - ap->a_p, 1)) == EINTR) + } + } else if ((vap->va_mtime.ts_sec != VNOVAL || + vap->va_atime.ts_sec != VNOVAL) && (np->n_flag & NMODIFIED)) { + error = nfs_vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 1); + if (error == EINTR) return (error); } nfsstats.rpccnt[NFSPROC_SETATTR]++; @@ -904,9 +914,11 @@ nfs_writerpc(vp, uiop, cred, ioflags) if (nmp->nm_flag & NFSMNT_NQNFS) { txdr_hyper(&uiop->uio_offset, tl); tl += 2; +#ifdef notyet if (ioflags & IO_APPEND) *tl++ = txdr_unsigned(1); else +#endif *tl++ = 0; } else { *++tl = txdr_unsigned(uiop->uio_offset); @@ -980,6 +992,7 @@ nfs_mknod(ap) vput(dvp); return (error); } + newvp = NULLVP; nfsstats.rpccnt[NFSPROC_CREATE]++; nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)+NFSX_SATTR(isnq)); @@ -1008,6 +1021,8 @@ nfs_mknod(ap) VTONFS(dvp)->n_flag |= NMODIFIED; VTONFS(dvp)->n_attrstamp = 0; vrele(dvp); + if (newvp != NULLVP) + vrele(newvp); return (error); } @@ -1106,11 +1121,23 @@ nfs_remove(ap) caddr_t bpos, dpos; int error = 0; struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct vattr vattr; if (vp->v_usecount > 1) { if (!np->n_sillyrename) error = nfs_sillyrename(dvp, vp, cnp); + else if (VOP_GETATTR(vp, &vattr, cnp->cn_cred, cnp->cn_proc) + == 0 && vattr.va_nlink > 1) + /* + * If we already have a silly name but there are more + * than one links, just proceed with the NFS remove + * request, as the bits will remain available (modulo + * network races). This avoids silently ignoring the + * attempted removal of a non-silly entry. + */ + goto doit; } else { + doit: /* * Purge the name cache so that the chance of a lookup for * the name succeeding while the remove is in progress is @@ -1311,6 +1338,13 @@ nfs_link(ap) return (EXDEV); } + /* + * Push all writes to the server, so that the attribute cache + * doesn't get "out of sync" with the server. + * XXX There should be a better way! + */ + VOP_FSYNC(tdvp, cnp->cn_cred, MNT_WAIT, cnp->cn_proc); + nfsstats.rpccnt[NFSPROC_LINK]++; nfsm_reqhead(tdvp, NFSPROC_LINK, NFSX_FH*2+NFSX_UNSIGNED+nfsm_rndup(cnp->cn_namelen)); @@ -1321,7 +1355,7 @@ nfs_link(ap) nfsm_reqdone; FREE(cnp->cn_pnbuf, M_NAMEI); VTONFS(tdvp)->n_attrstamp = 0; - VTONFS(tdvp)->n_flag |= NMODIFIED; + VTONFS(vp)->n_flag |= NMODIFIED; VTONFS(vp)->n_attrstamp = 0; vrele(vp); /* @@ -2052,8 +2086,8 @@ nfs_strategy(ap) struct proc *p; int error = 0; - if (bp->b_flags & B_PHYS) - panic("nfs physio"); + if ((bp->b_flags & (B_PHYS|B_ASYNC)) == (B_PHYS|B_ASYNC)) + panic("nfs physio/async"); if (bp->b_flags & B_ASYNC) p = (struct proc *)0; else diff --git a/sys/nfsclient/nfsargs.h b/sys/nfsclient/nfsargs.h index 844acdc..c79eefb 100644 --- a/sys/nfsclient/nfsargs.h +++ b/sys/nfsclient/nfsargs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.1 (Berkeley) 6/10/93 - * $Id: nfs.h,v 1.4 1994/08/21 06:50:08 paul Exp $ + * $Id: nfs.h,v 1.5 1994/10/02 17:26:54 phk Exp $ */ #ifndef _NFS_NFS_H_ @@ -179,8 +179,7 @@ struct nfsstats { * Nfs outstanding request list element */ struct nfsreq { - struct nfsreq *r_next; - struct nfsreq *r_prev; + TAILQ_ENTRY(nfsreq) r_chain; struct mbuf *r_mreq; struct mbuf *r_mrep; struct mbuf *r_md; @@ -197,6 +196,11 @@ struct nfsreq { struct proc *r_procp; /* Proc that did I/O system call */ }; +/* + * Queue head for nfsreq's + */ +TAILQ_HEAD(, nfsreq) nfs_reqq; + /* Flag values for r_flags */ #define R_TIMING 0x01 /* timing request (in mntp) */ #define R_SENT 0x02 /* request has been sent */ @@ -216,7 +220,8 @@ struct nfsstats nfsstats; * and uid hash lists. */ #define NUIDHASHSIZ 32 -#define NUIDHASH(uid) ((uid) & (NUIDHASHSIZ - 1)) +#define NUIDHASH(sock, uid) \ + (&(sock)->ns_uidhashtbl[(uid) & (sock)->ns_uidhash]) /* * Network address hash list element @@ -227,10 +232,8 @@ union nethostaddr { }; struct nfsuid { - struct nfsuid *nu_lrunext; /* MUST be first */ - struct nfsuid *nu_lruprev; - struct nfsuid *nu_hnext; - struct nfsuid *nu_hprev; + TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ + LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ int nu_flag; /* Flags */ uid_t nu_uid; /* Uid mapped by this entry */ union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ @@ -243,10 +246,11 @@ struct nfsuid { #define NU_INETADDR 0x1 struct nfssvc_sock { - struct nfsuid *ns_lrunext; /* MUST be first */ - struct nfsuid *ns_lruprev; - struct nfssvc_sock *ns_next; - struct nfssvc_sock *ns_prev; + TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ + TAILQ_HEAD(, nfsuid) ns_uidlruhead; + LIST_HEAD(, nfsuid) *ns_uidhashtbl; + u_long ns_uidhash; + int ns_flag; u_long ns_sref; struct file *ns_fp; @@ -260,7 +264,6 @@ struct nfssvc_sock { struct mbuf *ns_rec; struct mbuf *ns_recend; int ns_numuids; - struct nfsuid *ns_uidh[NUIDHASHSIZ]; }; /* Bits for "ns_flag" */ @@ -269,17 +272,18 @@ struct nfssvc_sock { #define SLP_NEEDQ 0x04 #define SLP_DISCONN 0x08 #define SLP_GETSTREAM 0x10 -#define SLP_INIT 0x20 -#define SLP_WANTINIT 0x40 - #define SLP_ALLFLAGS 0xff +TAILQ_HEAD(, nfssvc_sock) nfssvc_sockhead; +int nfssvc_sockhead_flag; +#define SLP_INIT 0x01 +#define SLP_WANTINIT 0x02 + /* * One of these structures is allocated for each nfsd. */ struct nfsd { - struct nfsd *nd_next; /* Must be first */ - struct nfsd *nd_prev; + TAILQ_ENTRY(nfsd) nd_chain; /* List of all nfsd's */ int nd_flag; /* NFSD_ flags */ struct nfssvc_sock *nd_slp; /* Current socket */ struct mbuf *nd_nam; /* Client addr for datagram req. */ @@ -297,11 +301,15 @@ struct nfsd { struct proc *nd_procp; /* Proc ptr */ }; +/* Bits for "nd_flag" */ #define NFSD_WAITING 0x01 -#define NFSD_CHECKSLP 0x02 -#define NFSD_REQINPROG 0x04 -#define NFSD_NEEDAUTH 0x08 -#define NFSD_AUTHFAIL 0x10 +#define NFSD_REQINPROG 0x02 +#define NFSD_NEEDAUTH 0x04 +#define NFSD_AUTHFAIL 0x08 + +TAILQ_HEAD(, nfsd) nfsd_head; +int nfsd_head_flag; +#define NFSD_CHECKSLP 0x01 int nfs_reply __P((struct nfsreq *)); int nfs_getreq __P((struct nfsd *,int)); @@ -335,7 +343,7 @@ int nfs_adv __P((struct mbuf **,caddr_t *,int,int)); int nfsrv_getstream __P((struct nfssvc_sock *,int)); void nfs_nhinit __P((void)); void nfs_timer __P((void*)); -struct nfsnode ** nfs_hash __P((nfsv2fh_t *)); +struct nfsnodehashhead * nfs_hash __P((nfsv2fh_t *)); int nfssvc_iod __P((struct proc *)); int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t,struct proc *)); int nfssvc_addsock __P((struct file *,struct mbuf *)); diff --git a/sys/nfsclient/nfsm_subs.h b/sys/nfsclient/nfsm_subs.h index 954a92f..994c0b6 100644 --- a/sys/nfsclient/nfsm_subs.h +++ b/sys/nfsclient/nfsm_subs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsm_subs.h 8.1 (Berkeley) 6/16/93 - * $Id: nfsm_subs.h,v 1.3 1994/08/21 06:50:10 paul Exp $ + * $Id: nfsm_subs.h,v 1.4 1994/10/02 17:27:05 phk Exp $ */ #ifndef _NFS_NFSM_SUBS_H_ @@ -264,8 +264,7 @@ extern struct mbuf *nfsm_reqh(); fp->fa_nfsblocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \ txdr_nfstime(&vap->va_atime, &fp->fa_nfsatime); \ txdr_nfstime(&vap->va_mtime, &fp->fa_nfsmtime); \ - fp->fa_nfsctime.nfs_sec = txdr_unsigned(vap->va_ctime.ts_sec); \ - fp->fa_nfsctime.nfs_usec = txdr_unsigned(vap->va_gen); \ + txdr_nfstime(&vap->va_ctime, &fp->fa_nfsctime); \ } else { \ fp->fa_nqblocksize = txdr_unsigned(vap->va_blocksize); \ if (vap->va_type == VFIFO) \ diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h index 78ba00b..99a1b48 100644 --- a/sys/nfsclient/nfsmount.h +++ b/sys/nfsclient/nfsmount.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsmount.h 8.1 (Berkeley) 6/10/93 - * $Id: nfsmount.h,v 1.2 1994/08/02 07:52:21 davidg Exp $ + * $Id: nfsmount.h,v 1.3 1994/08/21 06:50:10 paul Exp $ */ #ifndef _NFS_NFSMOUNT_H_ @@ -67,8 +67,7 @@ struct nfsmount { int nm_wsize; /* Max size of write rpc */ int nm_readahead; /* Num. of blocks to readahead */ int nm_leaseterm; /* Term (sec) for NQNFS lease */ - struct nfsnode *nm_tnext; /* Head of lease timer queue */ - struct nfsnode *nm_tprev; + CIRCLEQ_HEAD(, nfsnode) nm_timerhead; /* Head of lease timer queue */ struct vnode *nm_inprog; /* Vnode in prog by nqnfs_clientd() */ uid_t nm_authuid; /* Uid for authenticator */ int nm_authtype; /* Authenticator type */ diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index 5bb170b..01d0969 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsnode.h 8.4 (Berkeley) 2/13/94 - * $Id: nfsnode.h,v 1.6 1994/09/22 19:38:29 wollman Exp $ + * $Id: nfsnode.h,v 1.7 1994/10/02 17:27:06 phk Exp $ */ #ifndef _NFS_NFSNODE_H_ @@ -60,8 +60,8 @@ struct sillyrename { */ struct nfsnode { - struct nfsnode *n_forw; /* hash, forward */ - struct nfsnode **n_back; /* hash, backward */ + LIST_ENTRY(nfsnode) n_hash; /* Hash chain */ + CIRCLEQ_ENTRY(nfsnode) n_timer; /* Nqnfs timer chain */ nfsv2fh_t n_fh; /* NFS File Handle */ long n_flag; /* Flag for locking.. */ struct vnode *n_vnode; /* vnode associated with this node */ @@ -77,8 +77,6 @@ struct nfsnode { u_quad_t n_brev; /* Modify rev when cached */ u_quad_t n_lrev; /* Modify rev for lease */ time_t n_expiry; /* Lease expiry time */ - struct nfsnode *n_tnext; /* Nqnfs timer chain */ - struct nfsnode *n_tprev; struct sillyrename n_silly; /* Silly rename struct */ struct timeval n_atim; /* Special file times */ struct timeval n_mtim; @@ -107,7 +105,7 @@ struct nfsnode { /* * Queue head for nfsiod's */ -TAILQ_HEAD(nfsbufs, buf) nfs_bufq; +TAILQ_HEAD(, buf) nfs_bufq; #ifdef KERNEL /* diff --git a/sys/nfsclient/nfsstats.h b/sys/nfsclient/nfsstats.h index 844acdc..c79eefb 100644 --- a/sys/nfsclient/nfsstats.h +++ b/sys/nfsclient/nfsstats.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.1 (Berkeley) 6/10/93 - * $Id: nfs.h,v 1.4 1994/08/21 06:50:08 paul Exp $ + * $Id: nfs.h,v 1.5 1994/10/02 17:26:54 phk Exp $ */ #ifndef _NFS_NFS_H_ @@ -179,8 +179,7 @@ struct nfsstats { * Nfs outstanding request list element */ struct nfsreq { - struct nfsreq *r_next; - struct nfsreq *r_prev; + TAILQ_ENTRY(nfsreq) r_chain; struct mbuf *r_mreq; struct mbuf *r_mrep; struct mbuf *r_md; @@ -197,6 +196,11 @@ struct nfsreq { struct proc *r_procp; /* Proc that did I/O system call */ }; +/* + * Queue head for nfsreq's + */ +TAILQ_HEAD(, nfsreq) nfs_reqq; + /* Flag values for r_flags */ #define R_TIMING 0x01 /* timing request (in mntp) */ #define R_SENT 0x02 /* request has been sent */ @@ -216,7 +220,8 @@ struct nfsstats nfsstats; * and uid hash lists. */ #define NUIDHASHSIZ 32 -#define NUIDHASH(uid) ((uid) & (NUIDHASHSIZ - 1)) +#define NUIDHASH(sock, uid) \ + (&(sock)->ns_uidhashtbl[(uid) & (sock)->ns_uidhash]) /* * Network address hash list element @@ -227,10 +232,8 @@ union nethostaddr { }; struct nfsuid { - struct nfsuid *nu_lrunext; /* MUST be first */ - struct nfsuid *nu_lruprev; - struct nfsuid *nu_hnext; - struct nfsuid *nu_hprev; + TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ + LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ int nu_flag; /* Flags */ uid_t nu_uid; /* Uid mapped by this entry */ union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ @@ -243,10 +246,11 @@ struct nfsuid { #define NU_INETADDR 0x1 struct nfssvc_sock { - struct nfsuid *ns_lrunext; /* MUST be first */ - struct nfsuid *ns_lruprev; - struct nfssvc_sock *ns_next; - struct nfssvc_sock *ns_prev; + TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ + TAILQ_HEAD(, nfsuid) ns_uidlruhead; + LIST_HEAD(, nfsuid) *ns_uidhashtbl; + u_long ns_uidhash; + int ns_flag; u_long ns_sref; struct file *ns_fp; @@ -260,7 +264,6 @@ struct nfssvc_sock { struct mbuf *ns_rec; struct mbuf *ns_recend; int ns_numuids; - struct nfsuid *ns_uidh[NUIDHASHSIZ]; }; /* Bits for "ns_flag" */ @@ -269,17 +272,18 @@ struct nfssvc_sock { #define SLP_NEEDQ 0x04 #define SLP_DISCONN 0x08 #define SLP_GETSTREAM 0x10 -#define SLP_INIT 0x20 -#define SLP_WANTINIT 0x40 - #define SLP_ALLFLAGS 0xff +TAILQ_HEAD(, nfssvc_sock) nfssvc_sockhead; +int nfssvc_sockhead_flag; +#define SLP_INIT 0x01 +#define SLP_WANTINIT 0x02 + /* * One of these structures is allocated for each nfsd. */ struct nfsd { - struct nfsd *nd_next; /* Must be first */ - struct nfsd *nd_prev; + TAILQ_ENTRY(nfsd) nd_chain; /* List of all nfsd's */ int nd_flag; /* NFSD_ flags */ struct nfssvc_sock *nd_slp; /* Current socket */ struct mbuf *nd_nam; /* Client addr for datagram req. */ @@ -297,11 +301,15 @@ struct nfsd { struct proc *nd_procp; /* Proc ptr */ }; +/* Bits for "nd_flag" */ #define NFSD_WAITING 0x01 -#define NFSD_CHECKSLP 0x02 -#define NFSD_REQINPROG 0x04 -#define NFSD_NEEDAUTH 0x08 -#define NFSD_AUTHFAIL 0x10 +#define NFSD_REQINPROG 0x02 +#define NFSD_NEEDAUTH 0x04 +#define NFSD_AUTHFAIL 0x08 + +TAILQ_HEAD(, nfsd) nfsd_head; +int nfsd_head_flag; +#define NFSD_CHECKSLP 0x01 int nfs_reply __P((struct nfsreq *)); int nfs_getreq __P((struct nfsd *,int)); @@ -335,7 +343,7 @@ int nfs_adv __P((struct mbuf **,caddr_t *,int,int)); int nfsrv_getstream __P((struct nfssvc_sock *,int)); void nfs_nhinit __P((void)); void nfs_timer __P((void*)); -struct nfsnode ** nfs_hash __P((nfsv2fh_t *)); +struct nfsnodehashhead * nfs_hash __P((nfsv2fh_t *)); int nfssvc_iod __P((struct proc *)); int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t,struct proc *)); int nfssvc_addsock __P((struct file *,struct mbuf *)); diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h index 844acdc..c79eefb 100644 --- a/sys/nfsserver/nfs.h +++ b/sys/nfsserver/nfs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.1 (Berkeley) 6/10/93 - * $Id: nfs.h,v 1.4 1994/08/21 06:50:08 paul Exp $ + * $Id: nfs.h,v 1.5 1994/10/02 17:26:54 phk Exp $ */ #ifndef _NFS_NFS_H_ @@ -179,8 +179,7 @@ struct nfsstats { * Nfs outstanding request list element */ struct nfsreq { - struct nfsreq *r_next; - struct nfsreq *r_prev; + TAILQ_ENTRY(nfsreq) r_chain; struct mbuf *r_mreq; struct mbuf *r_mrep; struct mbuf *r_md; @@ -197,6 +196,11 @@ struct nfsreq { struct proc *r_procp; /* Proc that did I/O system call */ }; +/* + * Queue head for nfsreq's + */ +TAILQ_HEAD(, nfsreq) nfs_reqq; + /* Flag values for r_flags */ #define R_TIMING 0x01 /* timing request (in mntp) */ #define R_SENT 0x02 /* request has been sent */ @@ -216,7 +220,8 @@ struct nfsstats nfsstats; * and uid hash lists. */ #define NUIDHASHSIZ 32 -#define NUIDHASH(uid) ((uid) & (NUIDHASHSIZ - 1)) +#define NUIDHASH(sock, uid) \ + (&(sock)->ns_uidhashtbl[(uid) & (sock)->ns_uidhash]) /* * Network address hash list element @@ -227,10 +232,8 @@ union nethostaddr { }; struct nfsuid { - struct nfsuid *nu_lrunext; /* MUST be first */ - struct nfsuid *nu_lruprev; - struct nfsuid *nu_hnext; - struct nfsuid *nu_hprev; + TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ + LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ int nu_flag; /* Flags */ uid_t nu_uid; /* Uid mapped by this entry */ union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ @@ -243,10 +246,11 @@ struct nfsuid { #define NU_INETADDR 0x1 struct nfssvc_sock { - struct nfsuid *ns_lrunext; /* MUST be first */ - struct nfsuid *ns_lruprev; - struct nfssvc_sock *ns_next; - struct nfssvc_sock *ns_prev; + TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ + TAILQ_HEAD(, nfsuid) ns_uidlruhead; + LIST_HEAD(, nfsuid) *ns_uidhashtbl; + u_long ns_uidhash; + int ns_flag; u_long ns_sref; struct file *ns_fp; @@ -260,7 +264,6 @@ struct nfssvc_sock { struct mbuf *ns_rec; struct mbuf *ns_recend; int ns_numuids; - struct nfsuid *ns_uidh[NUIDHASHSIZ]; }; /* Bits for "ns_flag" */ @@ -269,17 +272,18 @@ struct nfssvc_sock { #define SLP_NEEDQ 0x04 #define SLP_DISCONN 0x08 #define SLP_GETSTREAM 0x10 -#define SLP_INIT 0x20 -#define SLP_WANTINIT 0x40 - #define SLP_ALLFLAGS 0xff +TAILQ_HEAD(, nfssvc_sock) nfssvc_sockhead; +int nfssvc_sockhead_flag; +#define SLP_INIT 0x01 +#define SLP_WANTINIT 0x02 + /* * One of these structures is allocated for each nfsd. */ struct nfsd { - struct nfsd *nd_next; /* Must be first */ - struct nfsd *nd_prev; + TAILQ_ENTRY(nfsd) nd_chain; /* List of all nfsd's */ int nd_flag; /* NFSD_ flags */ struct nfssvc_sock *nd_slp; /* Current socket */ struct mbuf *nd_nam; /* Client addr for datagram req. */ @@ -297,11 +301,15 @@ struct nfsd { struct proc *nd_procp; /* Proc ptr */ }; +/* Bits for "nd_flag" */ #define NFSD_WAITING 0x01 -#define NFSD_CHECKSLP 0x02 -#define NFSD_REQINPROG 0x04 -#define NFSD_NEEDAUTH 0x08 -#define NFSD_AUTHFAIL 0x10 +#define NFSD_REQINPROG 0x02 +#define NFSD_NEEDAUTH 0x04 +#define NFSD_AUTHFAIL 0x08 + +TAILQ_HEAD(, nfsd) nfsd_head; +int nfsd_head_flag; +#define NFSD_CHECKSLP 0x01 int nfs_reply __P((struct nfsreq *)); int nfs_getreq __P((struct nfsd *,int)); @@ -335,7 +343,7 @@ int nfs_adv __P((struct mbuf **,caddr_t *,int,int)); int nfsrv_getstream __P((struct nfssvc_sock *,int)); void nfs_nhinit __P((void)); void nfs_timer __P((void*)); -struct nfsnode ** nfs_hash __P((nfsv2fh_t *)); +struct nfsnodehashhead * nfs_hash __P((nfsv2fh_t *)); int nfssvc_iod __P((struct proc *)); int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t,struct proc *)); int nfssvc_addsock __P((struct file *,struct mbuf *)); diff --git a/sys/nfsserver/nfs_srvcache.c b/sys/nfsserver/nfs_srvcache.c index f496ea1..0f31ae0 100644 --- a/sys/nfsserver/nfs_srvcache.c +++ b/sys/nfsserver/nfs_srvcache.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_srvcache.c 8.1 (Berkeley) 6/10/93 - * $Id: nfs_srvcache.c,v 1.3 1994/08/02 07:52:12 davidg Exp $ + * $Id: nfs_srvcache.c,v 1.4 1994/10/02 17:27:00 phk Exp $ */ /* @@ -66,10 +66,11 @@ long numnfsrvcache, desirednfsrvcache = NFSRVCACHESIZ; -#define NFSRCHASH(xid) (((xid) + ((xid) >> 24)) & rheadhash) -static struct nfsrvcache *nfsrvlruhead, **nfsrvlrutail = &nfsrvlruhead; -static struct nfsrvcache **rheadhtbl; -static u_long rheadhash; +#define NFSRCHASH(xid) \ + (&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash]) +LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl; +TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead; +u_long nfsrvhash; #define TRUE 1 #define FALSE 0 @@ -140,7 +141,8 @@ void nfsrv_initcache() { - rheadhtbl = hashinit(desirednfsrvcache, M_NFSD, &rheadhash); + nfsrvhashtbl = hashinit(desirednfsrvcache, M_NFSD, &nfsrvhash); + TAILQ_INIT(&nfsrvlruhead); } /* @@ -163,7 +165,7 @@ nfsrv_getcache(nam, nd, repp) register struct nfsd *nd; struct mbuf **repp; { - register struct nfsrvcache *rp, *rq, **rpp; + register struct nfsrvcache *rp; struct mbuf *mb; struct sockaddr_in *saddr; caddr_t bpos; @@ -171,9 +173,9 @@ nfsrv_getcache(nam, nd, repp) if (nd->nd_nqlflag != NQL_NOVAL) return (RC_DOIT); - rpp = &rheadhtbl[NFSRCHASH(nd->nd_retxid)]; loop: - for (rp = *rpp; rp; rp = rp->rc_forw) { + for (rp = NFSRCHASH(nd->nd_retxid)->lh_first; rp != 0; + rp = rp->rc_hash.le_next) { if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc && netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nam)) { if ((rp->rc_flag & RC_LOCKED) != 0) { @@ -183,15 +185,9 @@ loop: } rp->rc_flag |= RC_LOCKED; /* If not at end of LRU chain, move it there */ - if (rp->rc_next) { - /* remove from LRU chain */ - *rp->rc_prev = rp->rc_next; - rp->rc_next->rc_prev = rp->rc_prev; - /* and replace at end of it */ - rp->rc_next = NULL; - rp->rc_prev = nfsrvlrutail; - *nfsrvlrutail = rp; - nfsrvlrutail = &rp->rc_next; + if (rp->rc_lru.tqe_next) { + TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru); + TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru); } if (rp->rc_state == RC_UNUSED) panic("nfsrv cache"); @@ -229,32 +225,22 @@ loop: numnfsrvcache++; rp->rc_flag = RC_LOCKED; } else { - rp = nfsrvlruhead; + rp = nfsrvlruhead.tqh_first; while ((rp->rc_flag & RC_LOCKED) != 0) { rp->rc_flag |= RC_WANTED; (void) tsleep((caddr_t)rp, PZERO-1, "nfsrc", 0); - rp = nfsrvlruhead; + rp = nfsrvlruhead.tqh_first; } rp->rc_flag |= RC_LOCKED; - /* remove from hash chain */ - rq = rp->rc_forw; - if (rq) - rq->rc_back = rp->rc_back; - *rp->rc_back = rq; - /* remove from LRU chain */ - *rp->rc_prev = rp->rc_next; - rp->rc_next->rc_prev = rp->rc_prev; + 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) MFREE(rp->rc_nam, mb); rp->rc_flag &= (RC_LOCKED | RC_WANTED); } - /* place at end of LRU list */ - rp->rc_next = NULL; - rp->rc_prev = nfsrvlrutail; - *nfsrvlrutail = rp; - nfsrvlrutail = &rp->rc_next; + TAILQ_INSERT_TAIL(&nfsrvlruhead, rp, rc_lru); rp->rc_state = RC_INPROG; rp->rc_xid = nd->nd_retxid; saddr = mtod(nam, struct sockaddr_in *); @@ -270,13 +256,7 @@ loop: break; }; rp->rc_proc = nd->nd_procnum; - /* insert into hash chain */ - rq = *rpp; - if (rq) - rq->rc_back = &rp->rc_forw; - rp->rc_forw = rq; - rp->rc_back = rpp; - *rpp = rp; + 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; @@ -300,7 +280,8 @@ nfsrv_updatecache(nam, nd, repvalid, repmbuf) if (nd->nd_nqlflag != NQL_NOVAL) return; loop: - for (rp = rheadhtbl[NFSRCHASH(nd->nd_retxid)]; rp; rp = rp->rc_forw) { + for (rp = NFSRCHASH(nd->nd_retxid)->lh_first; rp != 0; + rp = rp->rc_hash.le_next) { if (nd->nd_retxid == rp->rc_xid && nd->nd_procnum == rp->rc_proc && netaddr_match(NETFAMILY(rp), &rp->rc_haddr, nam)) { if ((rp->rc_flag & RC_LOCKED) != 0) { @@ -342,12 +323,11 @@ nfsrv_cleancache() { register struct nfsrvcache *rp, *nextrp; - for (rp = nfsrvlruhead; rp; rp = nextrp) { - nextrp = rp->rc_next; + for (rp = nfsrvlruhead.tqh_first; rp != 0; rp = nextrp) { + nextrp = rp->rc_lru.tqe_next; + LIST_REMOVE(rp, rc_hash); + TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru); free(rp, M_NFSD); } - bzero((char *)rheadhtbl, (rheadhash + 1) * sizeof(void *)); - nfsrvlruhead = NULL; - nfsrvlrutail = &nfsrvlruhead; numnfsrvcache = 0; } diff --git a/sys/nfsserver/nfs_srvsock.c b/sys/nfsserver/nfs_srvsock.c index 4cc719f..27c4561 100644 --- a/sys/nfsserver/nfs_srvsock.c +++ b/sys/nfsserver/nfs_srvsock.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_socket.c 8.3 (Berkeley) 1/12/94 - * $Id: nfs_socket.c,v 1.3 1994/08/02 07:52:11 davidg Exp $ + * $Id: nfs_socket.c,v 1.4 1994/10/02 17:26:59 phk Exp $ */ /* @@ -57,6 +57,7 @@ #include <netinet/in.h> #include <netinet/tcp.h> + #include <nfs/rpcv2.h> #include <nfs/nfsv2.h> #include <nfs/nfs.h> @@ -67,6 +68,8 @@ #include <nfs/nfsrtt.h> #include <nfs/nqnfs.h> +#include <machine/clock.h> /* for inittodr */ + #define TRUE 1 #define FALSE 0 @@ -158,7 +161,6 @@ void nfs_rcvunlock(), nqnfs_serverd(), nqnfs_clientlease(); struct mbuf *nfsm_rpchead(); int nfsrtton = 0; struct nfsrtt nfsrtt; -struct nfsd nfsd_head; int nfsrv_null(), nfsrv_getattr(), @@ -208,8 +210,6 @@ int (*nfsrv_procs[NFS_NPROCS])() = { nqnfsrv_access, }; -struct nfsreq nfsreqh; - /* * Initialize sockets and congestion for a new NFS connection. * We do not free the sockaddr if error. @@ -375,11 +375,9 @@ nfs_reconnect(rep) * Loop through outstanding request list and fix up all requests * on old socket. */ - rp = nfsreqh.r_next; - while (rp != &nfsreqh) { + for (rp = nfs_reqq.tqh_first; rp != 0; rp = rp->r_chain.tqe_next) { if (rp->r_nmp == nmp) rp->r_flags |= R_MUSTRESEND; - rp = rp->r_next; } return (0); } @@ -769,8 +767,8 @@ nfsmout: * Loop through the request list to match up the reply * Iff no match, just drop the datagram */ - rep = nfsreqh.r_next; - while (rep != &nfsreqh) { + for (rep = nfs_reqq.tqh_first; rep != 0; + rep = rep->r_chain.tqe_next) { if (rep->r_mrep == NULL && rxid == rep->r_xid) { /* Found it.. */ rep->r_mrep = mrep; @@ -832,13 +830,12 @@ nfsmout: nmp->nm_timeouts = 0; break; } - rep = rep->r_next; } /* * If not matched to a request, drop it. * If it's mine, get out. */ - if (rep == &nfsreqh) { + if (rep == 0) { nfsstats.rpcunexpected++; m_freem(mrep); } else if (rep == myrep) { @@ -878,7 +875,6 @@ nfs_request(vp, mrest, procnum, procp, cred, mrp, mdp, dposp) register int i; struct nfsmount *nmp; struct mbuf *md, *mheadend; - struct nfsreq *reph; struct nfsnode *np; time_t reqtime, waituntil; caddr_t dpos, cp2; @@ -964,11 +960,7 @@ tryagain: * to put it LAST so timer finds oldest requests first. */ s = splsoftclock(); - reph = &nfsreqh; - reph->r_prev->r_next = rep; - rep->r_prev = reph->r_prev; - reph->r_prev = rep; - rep->r_next = reph; + TAILQ_INSERT_TAIL(&nfs_reqq, rep, r_chain); /* Get send time for nqnfs */ reqtime = time.tv_sec; @@ -1009,8 +1001,7 @@ tryagain: * RPC done, unlink the request. */ s = splsoftclock(); - rep->r_prev->r_next = rep->r_next; - rep->r_next->r_prev = rep->r_prev; + TAILQ_REMOVE(&nfs_reqq, rep, r_chain); splx(s); /* @@ -1167,7 +1158,7 @@ nfs_rephead(siz, nd, err, cache, frev, mrq, mbp, bposp) tl = mtod(mreq, u_long *); mreq->m_len = 6*NFSX_UNSIGNED; bpos = ((caddr_t)tl)+mreq->m_len; - *tl++ = nd->nd_retxid; + *tl++ = txdr_unsigned(nd->nd_retxid); *tl++ = rpc_reply; if (err == ERPCMISMATCH || err == NQNFS_AUTHERR) { *tl++ = rpc_msgdenied; @@ -1255,7 +1246,7 @@ nfs_timer(arg) int s, error; s = splnet(); - for (rep = nfsreqh.r_next; rep != &nfsreqh; rep = rep->r_next) { + for (rep = nfs_reqq.tqh_first; rep != 0; rep = rep->r_chain.tqe_next) { nmp = rep->r_nmp; if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) continue; @@ -1842,7 +1833,7 @@ nfs_getreq(nd, has_header) dpos = nd->nd_dpos; if (has_header) { nfsm_dissect(tl, u_long *, 10*NFSX_UNSIGNED); - nd->nd_retxid = *tl++; + nd->nd_retxid = fxdr_unsigned(u_long, *tl++); if (*tl++ != rpc_call) { m_freem(mrep); return (EBADRPC); @@ -1980,11 +1971,11 @@ void nfsrv_wakenfsd(slp) struct nfssvc_sock *slp; { - register struct nfsd *nd = nfsd_head.nd_next; + register struct nfsd *nd; if ((slp->ns_flag & SLP_VALID) == 0) return; - while (nd != (struct nfsd *)&nfsd_head) { + for (nd = nfsd_head.tqh_first; nd != 0; nd = nd->nd_chain.tqe_next) { if (nd->nd_flag & NFSD_WAITING) { nd->nd_flag &= ~NFSD_WAITING; if (nd->nd_slp) @@ -1994,10 +1985,9 @@ nfsrv_wakenfsd(slp) wakeup((caddr_t)nd); return; } - nd = nd->nd_next; } slp->ns_flag |= SLP_DOREC; - nfsd_head.nd_flag |= NFSD_CHECKSLP; + nfsd_head_flag |= NFSD_CHECKSLP; } int diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c index ee8200c..9b2ef80 100644 --- a/sys/nfsserver/nfs_srvsubs.c +++ b/sys/nfsserver/nfs_srvsubs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_subs.c,v 1.5 1994/09/22 22:10:44 wollman Exp $ + * $Id: nfs_subs.c,v 1.6 1994/10/02 17:27:01 phk Exp $ */ /* @@ -94,7 +94,6 @@ u_long nfs_vers, nfs_prog, nfs_true, nfs_false; static u_long nfs_xid = 0; enum vtype ntov_type[7] = { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON }; extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; -extern struct nfsreq nfsreqh; extern int nqnfs_piggy[NFS_NPROCS]; extern struct nfsrtt nfsrtt; extern time_t nqnfsstarttime; @@ -110,6 +109,8 @@ struct nfssvc_args; extern int nfssvc(struct proc *, struct nfssvc_args *, int *); #endif +LIST_HEAD(nfsnodehashhead, nfsnode); + /* * Create the header for an rpc request packet * The hsiz is the size of the rest of the nfs request header. @@ -615,6 +616,7 @@ nfs_init() nfs_prog = txdr_unsigned(NFS_PROG); nfs_true = txdr_unsigned(TRUE); nfs_false = txdr_unsigned(FALSE); + nfs_xdrneg1 = txdr_unsigned(-1); /* Loop thru nfs procids */ for (i = 0; i < NFS_NPROCS; i++) nfs_procids[i] = txdr_unsigned(i); @@ -622,7 +624,6 @@ nfs_init() for (i = 0; i < NFS_MAXASYNCDAEMON; i++) nfs_iodwant[i] = (struct proc *)0; TAILQ_INIT(&nfs_bufq); - nfs_xdrneg1 = txdr_unsigned(-1); nfs_nhinit(); /* Init the nfsnode table */ nfsrv_init(0); /* Init server data structures */ nfsrv_initcache(); /* Init the server request cache */ @@ -636,15 +637,14 @@ nfs_init() NQLOADNOVRAM(nqnfsstarttime); nqnfs_prog = txdr_unsigned(NQNFS_PROG); nqnfs_vers = txdr_unsigned(NQNFS_VER1); - nqthead.th_head[0] = &nqthead; - nqthead.th_head[1] = &nqthead; - nqfhead = hashinit(NQLCHSZ, M_NQLEASE, &nqfheadhash); + CIRCLEQ_INIT(&nqtimerhead); + nqfhhashtbl = hashinit(NQLCHSZ, M_NQLEASE, &nqfhhash); } /* * Initialize reply list and start timer */ - nfsreqh.r_prev = nfsreqh.r_next = &nfsreqh; + TAILQ_INIT(&nfs_reqq); nfs_timer(0); /* @@ -689,7 +689,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) register struct vattr *vap; register struct nfsv2_fattr *fp; extern int (**spec_nfsv2nodeop_p)(); - register struct nfsnode *np, *nq, **nhpp; + register struct nfsnode *np; + register struct nfsnodehashhead *nhpp; register long t1; caddr_t dpos, cp2; int error = 0, isnq; @@ -743,10 +744,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) /* * Discard unneeded vnode, but save its nfsnode. */ - nq = np->n_forw; - if (nq) - nq->n_back = np->n_back; - *np->n_back = nq; + LIST_REMOVE(np, n_hash); nvp->v_data = vp->v_data; vp->v_data = NULL; vp->v_op = spec_vnodeop_p; @@ -756,13 +754,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) * Reinitialize aliased node. */ np->n_vnode = nvp; - nhpp = (struct nfsnode **)nfs_hash(&np->n_fh); - nq = *nhpp; - if (nq) - nq->n_back = &np->n_forw; - np->n_forw = nq; - np->n_back = nhpp; - *nhpp = np; + nhpp = nfs_hash(&np->n_fh); + LIST_INSERT_HEAD(nhpp, np, n_hash); *vpp = vp = nvp; } } @@ -794,9 +787,8 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper) vap->va_fileid = fxdr_unsigned(long, fp->fa_nfsfileid); fxdr_nfstime(&fp->fa_nfsatime, &vap->va_atime); vap->va_flags = 0; - vap->va_ctime.ts_sec = fxdr_unsigned(long, fp->fa_nfsctime.nfs_sec); - vap->va_ctime.ts_nsec = 0; - vap->va_gen = fxdr_unsigned(u_long, fp->fa_nfsctime.nfs_usec); + fxdr_nfstime(&fp->fa_nfsctime, &vap->va_ctime); + vap->va_gen = 0; vap->va_filerev = 0; } if (vap->va_size != np->n_size) { @@ -1106,24 +1098,24 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp) * Check/setup credentials. */ if (exflags & MNT_EXKERB) { - uidp = slp->ns_uidh[NUIDHASH(cred->cr_uid)]; - while (uidp) { + for (uidp = NUIDHASH(slp, cred->cr_uid)->lh_first; uidp != 0; + uidp = uidp->nu_hash.le_next) { if (uidp->nu_uid == cred->cr_uid) break; - uidp = uidp->nu_hnext; } - if (uidp) { - cred->cr_uid = uidp->nu_cr.cr_uid; - for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) - cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; - } else { + if (uidp == 0) { vput(*vpp); return (NQNFS_AUTHERR); } + cred->cr_uid = uidp->nu_cr.cr_uid; + for (i = 0; i < uidp->nu_cr.cr_ngroups; i++) + cred->cr_groups[i] = uidp->nu_cr.cr_groups[i]; + cred->cr_ngroups = i; } else if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { cred->cr_uid = credanon->cr_uid; for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++) cred->cr_groups[i] = credanon->cr_groups[i]; + cred->cr_ngroups = i; } if (exflags & MNT_EXRDONLY) *rdonlyp = 1; diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c index 5645e45..8cdbfe7 100644 --- a/sys/nfsserver/nfs_syscalls.c +++ b/sys/nfsserver/nfs_syscalls.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_syscalls.c 8.3 (Berkeley) 1/4/94 - * $Id: nfs_syscalls.c,v 1.3 1994/08/02 07:52:15 davidg Exp $ + * $Id: nfs_syscalls.c,v 1.4 1994/10/02 17:27:02 phk Exp $ */ #include <sys/param.h> @@ -78,8 +78,6 @@ extern int (*nfsrv_procs[NFS_NPROCS])(); extern struct proc *nfs_iodwant[NFS_MAXASYNCDAEMON]; extern int nfs_numasync; extern time_t nqnfsstarttime; -extern struct nfsrv_req nsrvq_head; -extern struct nfsd nfsd_head; extern int nqsrv_writeslack; extern int nfsrtton; struct nfssvc_sock *nfs_udpsock, *nfs_cltpsock; @@ -91,7 +89,7 @@ static int modify_flag = 0; static struct nfsdrt nfsdrt; void nfsrv_cleancache(), nfsrv_rcv(), nfsrv_wakenfsd(), nfs_sndunlock(); static void nfsd_rt(); -void nfsrv_slpderef(), nfsrv_init(); +void nfsrv_slpderef(); #define TRUE 1 #define FALSE 0 @@ -141,8 +139,6 @@ getfh(p, uap, retval) return (error); } -static struct nfssvc_sock nfssvc_sockhead; - /* * Nfs server psuedo system call for the nfsd's * Based on the flag value it either: @@ -168,7 +164,7 @@ nfssvc(p, uap, retval) struct nfsd_cargs ncd; struct nfsd *nfsd; struct nfssvc_sock *slp; - struct nfsuid *nuidp, **nuh; + struct nfsuid *nuidp; struct nfsmount *nmp; int error; @@ -178,8 +174,8 @@ nfssvc(p, uap, retval) error = suser(p->p_ucred, &p->p_acflag); if(error) return (error); - while (nfssvc_sockhead.ns_flag & SLP_INIT) { - nfssvc_sockhead.ns_flag |= SLP_WANTINIT; + while (nfssvc_sockhead_flag & SLP_INIT) { + nfssvc_sockhead_flag |= SLP_WANTINIT; (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); } if (uap->flag & NFSSVC_BIOD) @@ -236,11 +232,10 @@ nfssvc(p, uap, retval) * First check to see if another nfsd has already * added this credential. */ - nuidp = slp->ns_uidh[NUIDHASH(nsd->nsd_uid)]; - while (nuidp) { + for (nuidp = NUIDHASH(slp, nsd->nsd_uid)->lh_first; + nuidp != 0; nuidp = nuidp->nu_hash.le_next) { if (nuidp->nu_uid == nsd->nsd_uid) break; - nuidp = nuidp->nu_hnext; } if (!nuidp) { /* @@ -258,27 +253,21 @@ nfssvc(p, uap, retval) free((caddr_t)nuidp, M_NFSUID); } else { if (nuidp == (struct nfsuid *)0) { - nuidp = slp->ns_lruprev; - remque(nuidp); - if (nuidp->nu_hprev) - nuidp->nu_hprev->nu_hnext = - nuidp->nu_hnext; - if (nuidp->nu_hnext) - nuidp->nu_hnext->nu_hprev = - nuidp->nu_hprev; + nuidp = slp->ns_uidlruhead.tqh_first; + LIST_REMOVE(nuidp, nu_hash); + TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, + nu_lru); } nuidp->nu_cr = nsd->nsd_cr; if (nuidp->nu_cr.cr_ngroups > NGROUPS) nuidp->nu_cr.cr_ngroups = NGROUPS; nuidp->nu_cr.cr_ref = 1; nuidp->nu_uid = nsd->nsd_uid; - insque(nuidp, (struct nfsuid *)slp); - nuh = &slp->ns_uidh[NUIDHASH(nsd->nsd_uid)]; - nuidp->nu_hnext = *nuh; - if (nuidp->nu_hnext) - nuidp->nu_hnext->nu_hprev = nuidp; - nuidp->nu_hprev = (struct nfsuid *)0; - *nuh = nuidp; + TAILQ_INSERT_TAIL(&slp->ns_uidlruhead, nuidp, + nu_lru); + LIST_INSERT_HEAD(NUIDHASH(slp, nsd->nsd_uid), + nuidp, nu_hash); + } } } @@ -364,11 +353,10 @@ nfssvc_addsock(fp, mynam) slp = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)slp, sizeof (struct nfssvc_sock)); - slp->ns_prev = nfssvc_sockhead.ns_prev; - slp->ns_prev->ns_next = slp; - slp->ns_next = &nfssvc_sockhead; - nfssvc_sockhead.ns_prev = slp; - slp->ns_lrunext = slp->ns_lruprev = (struct nfsuid *)slp; + slp->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &slp->ns_uidhash); + TAILQ_INIT(&slp->ns_uidlruhead); + TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain); } slp->ns_so = so; slp->ns_nam = mynam; @@ -412,7 +400,7 @@ nfssvc_nfsd(nsd, argp, p) bzero((caddr_t)nd, sizeof (struct nfsd)); nd->nd_procp = p; nd->nd_cr.cr_ref = 1; - insque(nd, &nfsd_head); + TAILQ_INSERT_TAIL(&nfsd_head, nd, nd_chain); nd->nd_nqlflag = NQL_NOVAL; nfs_numnfsd++; } @@ -422,7 +410,7 @@ nfssvc_nfsd(nsd, argp, p) for (;;) { if ((nd->nd_flag & NFSD_REQINPROG) == 0) { while (nd->nd_slp == (struct nfssvc_sock *)0 && - (nfsd_head.nd_flag & NFSD_CHECKSLP) == 0) { + (nfsd_head_flag & NFSD_CHECKSLP) == 0) { nd->nd_flag |= NFSD_WAITING; nfsd_waiting++; error = tsleep((caddr_t)nd, PSOCK | PCATCH, "nfsd", 0); @@ -431,9 +419,9 @@ nfssvc_nfsd(nsd, argp, p) goto done; } if (nd->nd_slp == (struct nfssvc_sock *)0 && - (nfsd_head.nd_flag & NFSD_CHECKSLP)) { - slp = nfssvc_sockhead.ns_next; - while (slp != &nfssvc_sockhead) { + (nfsd_head_flag & NFSD_CHECKSLP) != 0) { + for (slp = nfssvc_sockhead.tqh_first; slp != 0; + slp = slp->ns_chain.tqe_next) { if ((slp->ns_flag & (SLP_VALID | SLP_DOREC)) == (SLP_VALID | SLP_DOREC)) { slp->ns_flag &= ~SLP_DOREC; @@ -441,10 +429,9 @@ nfssvc_nfsd(nsd, argp, p) nd->nd_slp = slp; break; } - slp = slp->ns_next; } - if (slp == &nfssvc_sockhead) - nfsd_head.nd_flag &= ~NFSD_CHECKSLP; + if (slp == 0) + nfsd_head_flag &= ~NFSD_CHECKSLP; } if ((slp = nd->nd_slp) == (struct nfssvc_sock *)0) continue; @@ -504,11 +491,10 @@ nfssvc_nfsd(nsd, argp, p) /* * Check for a mapping already installed. */ - uidp = slp->ns_uidh[NUIDHASH(nd->nd_cr.cr_uid)]; - while (uidp) { + for (uidp = NUIDHASH(slp, nd->nd_cr.cr_uid)->lh_first; + uidp != 0; uidp = uidp->nu_hash.le_next) { if (uidp->nu_uid == nd->nd_cr.cr_uid) break; - uidp = uidp->nu_hnext; } if (!uidp) { nsd->nsd_uid = nd->nd_cr.cr_uid; @@ -637,7 +623,7 @@ nfssvc_nfsd(nsd, argp, p) } } done: - remque(nd); + TAILQ_REMOVE(&nfsd_head, nd, nd_chain); splx(s); free((caddr_t)nd, M_NFSD); nsd->nsd_nfsd = (struct nfsd *)0; @@ -708,8 +694,7 @@ void nfsrv_zapsock(slp) register struct nfssvc_sock *slp; { - register struct nfsuid *nuidp, *onuidp; - register int i; + register struct nfsuid *nuidp, *nnuidp; struct socket *so; struct file *fp; struct mbuf *m; @@ -726,15 +711,13 @@ nfsrv_zapsock(slp) MFREE(slp->ns_nam, m); m_freem(slp->ns_raw); m_freem(slp->ns_rec); - nuidp = slp->ns_lrunext; - while (nuidp != (struct nfsuid *)slp) { - onuidp = nuidp; - nuidp = nuidp->nu_lrunext; - free((caddr_t)onuidp, M_NFSUID); + for (nuidp = slp->ns_uidlruhead.tqh_first; nuidp != 0; + nuidp = nnuidp) { + nnuidp = nuidp->nu_lru.tqe_next; + LIST_REMOVE(nuidp, nu_hash); + TAILQ_REMOVE(&slp->ns_uidlruhead, nuidp, nu_lru); + free((caddr_t)nuidp, M_NFSUID); } - slp->ns_lrunext = slp->ns_lruprev = (struct nfsuid *)slp; - for (i = 0; i < NUIDHASHSIZ; i++) - slp->ns_uidh[i] = (struct nfsuid *)0; } } @@ -804,8 +787,7 @@ nfsrv_slpderef(slp) register struct nfssvc_sock *slp; { if (--(slp->ns_sref) == 0 && (slp->ns_flag & SLP_VALID) == 0) { - slp->ns_prev->ns_next = slp->ns_next; - slp->ns_next->ns_prev = slp->ns_prev; + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); free((caddr_t)slp, M_NFSSVC); } } @@ -819,48 +801,47 @@ void nfsrv_init(terminating) int terminating; { - register struct nfssvc_sock *slp; - struct nfssvc_sock *oslp; + register struct nfssvc_sock *slp, *nslp; - if (nfssvc_sockhead.ns_flag & SLP_INIT) + if (nfssvc_sockhead_flag & SLP_INIT) panic("nfsd init"); - nfssvc_sockhead.ns_flag |= SLP_INIT; + nfssvc_sockhead_flag |= SLP_INIT; if (terminating) { - slp = nfssvc_sockhead.ns_next; - while (slp != &nfssvc_sockhead) { + for (slp = nfssvc_sockhead.tqh_first; slp != 0; slp = nslp) { + nslp = slp->ns_chain.tqe_next; if (slp->ns_flag & SLP_VALID) nfsrv_zapsock(slp); - slp->ns_next->ns_prev = slp->ns_prev; - slp->ns_prev->ns_next = slp->ns_next; - oslp = slp; - slp = slp->ns_next; - free((caddr_t)oslp, M_NFSSVC); + TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain); + free((caddr_t)slp, M_NFSSVC); } nfsrv_cleancache(); /* And clear out server cache */ } + + TAILQ_INIT(&nfssvc_sockhead); + nfssvc_sockhead_flag &= ~SLP_INIT; + if (nfssvc_sockhead_flag & SLP_WANTINIT) { + nfssvc_sockhead_flag &= ~SLP_WANTINIT; + wakeup((caddr_t)&nfssvc_sockhead); + } + + TAILQ_INIT(&nfsd_head); + nfsd_head_flag &= ~NFSD_CHECKSLP; + nfs_udpsock = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)nfs_udpsock, sizeof (struct nfssvc_sock)); + nfs_udpsock->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &nfs_udpsock->ns_uidhash); + TAILQ_INIT(&nfs_udpsock->ns_uidlruhead); + TAILQ_INSERT_HEAD(&nfssvc_sockhead, nfs_udpsock, ns_chain); + nfs_cltpsock = (struct nfssvc_sock *) malloc(sizeof (struct nfssvc_sock), M_NFSSVC, M_WAITOK); bzero((caddr_t)nfs_cltpsock, sizeof (struct nfssvc_sock)); - nfssvc_sockhead.ns_next = nfs_udpsock; - nfs_udpsock->ns_next = nfs_cltpsock; - nfs_cltpsock->ns_next = &nfssvc_sockhead; - nfssvc_sockhead.ns_prev = nfs_cltpsock; - nfs_cltpsock->ns_prev = nfs_udpsock; - nfs_udpsock->ns_prev = &nfssvc_sockhead; - nfs_udpsock->ns_lrunext = nfs_udpsock->ns_lruprev = - (struct nfsuid *)nfs_udpsock; - nfs_cltpsock->ns_lrunext = nfs_cltpsock->ns_lruprev = - (struct nfsuid *)nfs_cltpsock; - nfsd_head.nd_next = nfsd_head.nd_prev = &nfsd_head; - nfsd_head.nd_flag = 0; - nfssvc_sockhead.ns_flag &= ~SLP_INIT; - if (nfssvc_sockhead.ns_flag & SLP_WANTINIT) { - nfssvc_sockhead.ns_flag &= ~SLP_WANTINIT; - wakeup((caddr_t)&nfssvc_sockhead); - } + nfs_cltpsock->ns_uidhashtbl = + hashinit(NUIDHASHSIZ, M_NFSSVC, &nfs_cltpsock->ns_uidhash); + TAILQ_INIT(&nfs_cltpsock->ns_uidlruhead); + TAILQ_INSERT_TAIL(&nfssvc_sockhead, nfs_cltpsock, ns_chain); } /* diff --git a/sys/nfsserver/nfsm_subs.h b/sys/nfsserver/nfsm_subs.h index 954a92f..994c0b6 100644 --- a/sys/nfsserver/nfsm_subs.h +++ b/sys/nfsserver/nfsm_subs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsm_subs.h 8.1 (Berkeley) 6/16/93 - * $Id: nfsm_subs.h,v 1.3 1994/08/21 06:50:10 paul Exp $ + * $Id: nfsm_subs.h,v 1.4 1994/10/02 17:27:05 phk Exp $ */ #ifndef _NFS_NFSM_SUBS_H_ @@ -264,8 +264,7 @@ extern struct mbuf *nfsm_reqh(); fp->fa_nfsblocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); \ txdr_nfstime(&vap->va_atime, &fp->fa_nfsatime); \ txdr_nfstime(&vap->va_mtime, &fp->fa_nfsmtime); \ - fp->fa_nfsctime.nfs_sec = txdr_unsigned(vap->va_ctime.ts_sec); \ - fp->fa_nfsctime.nfs_usec = txdr_unsigned(vap->va_gen); \ + txdr_nfstime(&vap->va_ctime, &fp->fa_nfsctime); \ } else { \ fp->fa_nqblocksize = txdr_unsigned(vap->va_blocksize); \ if (vap->va_type == VFIFO) \ diff --git a/sys/nfsserver/nfsrvcache.h b/sys/nfsserver/nfsrvcache.h index 00eac6a..b367b9f 100644 --- a/sys/nfsserver/nfsrvcache.h +++ b/sys/nfsserver/nfsrvcache.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfsrvcache.h 8.1 (Berkeley) 6/10/93 - * $Id: nfsrvcache.h,v 1.2 1994/08/02 07:52:25 davidg Exp $ + * $Id: nfsrvcache.h,v 1.3 1994/08/21 06:50:13 paul Exp $ */ #ifndef _NFS_NFSRVCACHE_H_ @@ -47,10 +47,8 @@ #define NFSRVCACHESIZ 256 struct nfsrvcache { - struct nfsrvcache *rc_forw; /* Hash chain links */ - struct nfsrvcache **rc_back; /* Hash chain links */ - struct nfsrvcache *rc_next; /* Lru list */ - struct nfsrvcache **rc_prev; /* Lru list */ + TAILQ_ENTRY(nfsrvcache) rc_lru; /* LRU chain */ + LIST_ENTRY(nfsrvcache) rc_hash; /* Hash chain */ u_long rc_xid; /* rpc id number */ union { struct mbuf *ru_repmb; /* Reply mbuf list OR */ diff --git a/sys/nfsserver/nfsrvstats.h b/sys/nfsserver/nfsrvstats.h index 844acdc..c79eefb 100644 --- a/sys/nfsserver/nfsrvstats.h +++ b/sys/nfsserver/nfsrvstats.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs.h 8.1 (Berkeley) 6/10/93 - * $Id: nfs.h,v 1.4 1994/08/21 06:50:08 paul Exp $ + * $Id: nfs.h,v 1.5 1994/10/02 17:26:54 phk Exp $ */ #ifndef _NFS_NFS_H_ @@ -179,8 +179,7 @@ struct nfsstats { * Nfs outstanding request list element */ struct nfsreq { - struct nfsreq *r_next; - struct nfsreq *r_prev; + TAILQ_ENTRY(nfsreq) r_chain; struct mbuf *r_mreq; struct mbuf *r_mrep; struct mbuf *r_md; @@ -197,6 +196,11 @@ struct nfsreq { struct proc *r_procp; /* Proc that did I/O system call */ }; +/* + * Queue head for nfsreq's + */ +TAILQ_HEAD(, nfsreq) nfs_reqq; + /* Flag values for r_flags */ #define R_TIMING 0x01 /* timing request (in mntp) */ #define R_SENT 0x02 /* request has been sent */ @@ -216,7 +220,8 @@ struct nfsstats nfsstats; * and uid hash lists. */ #define NUIDHASHSIZ 32 -#define NUIDHASH(uid) ((uid) & (NUIDHASHSIZ - 1)) +#define NUIDHASH(sock, uid) \ + (&(sock)->ns_uidhashtbl[(uid) & (sock)->ns_uidhash]) /* * Network address hash list element @@ -227,10 +232,8 @@ union nethostaddr { }; struct nfsuid { - struct nfsuid *nu_lrunext; /* MUST be first */ - struct nfsuid *nu_lruprev; - struct nfsuid *nu_hnext; - struct nfsuid *nu_hprev; + TAILQ_ENTRY(nfsuid) nu_lru; /* LRU chain */ + LIST_ENTRY(nfsuid) nu_hash; /* Hash list */ int nu_flag; /* Flags */ uid_t nu_uid; /* Uid mapped by this entry */ union nethostaddr nu_haddr; /* Host addr. for dgram sockets */ @@ -243,10 +246,11 @@ struct nfsuid { #define NU_INETADDR 0x1 struct nfssvc_sock { - struct nfsuid *ns_lrunext; /* MUST be first */ - struct nfsuid *ns_lruprev; - struct nfssvc_sock *ns_next; - struct nfssvc_sock *ns_prev; + TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */ + TAILQ_HEAD(, nfsuid) ns_uidlruhead; + LIST_HEAD(, nfsuid) *ns_uidhashtbl; + u_long ns_uidhash; + int ns_flag; u_long ns_sref; struct file *ns_fp; @@ -260,7 +264,6 @@ struct nfssvc_sock { struct mbuf *ns_rec; struct mbuf *ns_recend; int ns_numuids; - struct nfsuid *ns_uidh[NUIDHASHSIZ]; }; /* Bits for "ns_flag" */ @@ -269,17 +272,18 @@ struct nfssvc_sock { #define SLP_NEEDQ 0x04 #define SLP_DISCONN 0x08 #define SLP_GETSTREAM 0x10 -#define SLP_INIT 0x20 -#define SLP_WANTINIT 0x40 - #define SLP_ALLFLAGS 0xff +TAILQ_HEAD(, nfssvc_sock) nfssvc_sockhead; +int nfssvc_sockhead_flag; +#define SLP_INIT 0x01 +#define SLP_WANTINIT 0x02 + /* * One of these structures is allocated for each nfsd. */ struct nfsd { - struct nfsd *nd_next; /* Must be first */ - struct nfsd *nd_prev; + TAILQ_ENTRY(nfsd) nd_chain; /* List of all nfsd's */ int nd_flag; /* NFSD_ flags */ struct nfssvc_sock *nd_slp; /* Current socket */ struct mbuf *nd_nam; /* Client addr for datagram req. */ @@ -297,11 +301,15 @@ struct nfsd { struct proc *nd_procp; /* Proc ptr */ }; +/* Bits for "nd_flag" */ #define NFSD_WAITING 0x01 -#define NFSD_CHECKSLP 0x02 -#define NFSD_REQINPROG 0x04 -#define NFSD_NEEDAUTH 0x08 -#define NFSD_AUTHFAIL 0x10 +#define NFSD_REQINPROG 0x02 +#define NFSD_NEEDAUTH 0x04 +#define NFSD_AUTHFAIL 0x08 + +TAILQ_HEAD(, nfsd) nfsd_head; +int nfsd_head_flag; +#define NFSD_CHECKSLP 0x01 int nfs_reply __P((struct nfsreq *)); int nfs_getreq __P((struct nfsd *,int)); @@ -335,7 +343,7 @@ int nfs_adv __P((struct mbuf **,caddr_t *,int,int)); int nfsrv_getstream __P((struct nfssvc_sock *,int)); void nfs_nhinit __P((void)); void nfs_timer __P((void*)); -struct nfsnode ** nfs_hash __P((nfsv2fh_t *)); +struct nfsnodehashhead * nfs_hash __P((nfsv2fh_t *)); int nfssvc_iod __P((struct proc *)); int nfssvc_nfsd __P((struct nfsd_srvargs *,caddr_t,struct proc *)); int nfssvc_addsock __P((struct file *,struct mbuf *)); |