diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/nfs/nfs_subs.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index 3edd8a9d3a4..9906b699114 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_subs.c,v 1.16 1997/04/25 09:30:14 deraadt Exp $ */ +/* $OpenBSD: nfs_subs.c,v 1.17 1997/04/27 23:55:49 angelos Exp $ */ /* $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $ */ /* @@ -68,6 +68,7 @@ #include <nfs/xdr_subs.h> #include <nfs/nfsm_subs.h> #include <nfs/nfsmount.h> +#include <nfs/nfsrvcache.h> #include <nfs/nqnfs.h> #include <nfs/nfsrtt.h> #include <nfs/nfs_var.h> @@ -81,12 +82,20 @@ #include <netiso/iso.h> #endif +#include <dev/rndvar.h> + #ifdef __GNUC__ #define INLINE __inline #else #define INLINE #endif +#define NFSRCHASH(xid) \ + (&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash]) +extern LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl; +extern TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead; +extern u_long nfsrvhash; + int nfs_attrtimeo __P((struct nfsnode *np)); /* @@ -618,10 +627,9 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, register u_int32_t *tl; register caddr_t bpos; register int i; + register struct nfsrvcache *rp; struct mbuf *mreq, *mb2; int siz, grpsiz, authsiz; - struct timeval tv; - static u_int32_t base; authsiz = nfsm_rndup(auth_len); MGETHDR(mb, M_WAIT, MT_DATA); @@ -641,21 +649,27 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len, */ nfsm_build(tl, u_int32_t *, 8 * NFSX_UNSIGNED); - /* - * derive initial xid from system time - * XXX time is invalid if root not yet mounted - */ - if (!base && (rootvp)) { - microtime(&tv); - base = tv.tv_sec << 12; - nfs_xid = base; - } - /* - * Skip zero xid if it should ever happen. - */ - if (++nfs_xid == 0) - nfs_xid++; - + /* Get a new (non-zero) xid */ + + do + { + i = 0; + + while (((*xidp = arc4random()) == nfs_xid) || (*xidp == 0)) + ; + + nfs_xid = *xidp; + + for (rp = NFSRCHASH(nfs_xid)->lh_first; rp !=0; + rp = rp->rc_hash.le_next) + if ((nfs_xid == rp->rc_xid) && + (rp->rc_proc == procid)) + { + i = 1; /* do the loop again */ + break; + } + } while (i); + *tl++ = *xidp = txdr_unsigned(nfs_xid); *tl++ = rpc_call; *tl++ = rpc_vers; |