diff options
author | jh <jh@FreeBSD.org> | 2009-11-11 15:43:07 +0000 |
---|---|---|
committer | jh <jh@FreeBSD.org> | 2009-11-11 15:43:07 +0000 |
commit | 2727bc045c74159355a5a785f62ab8ce28f1731b (patch) | |
tree | bb61dc596d175ed65948508048afa07f3a43248b /sys/fs/nfsclient/nfs_clvnops.c | |
parent | 2a2df770dc273d9bdd8106d636a25d85954fccd0 (diff) | |
download | FreeBSD-src-2727bc045c74159355a5a785f62ab8ce28f1731b.zip FreeBSD-src-2727bc045c74159355a5a785f62ab8ce28f1731b.tar.gz |
Create verifier used by FreeBSD NFS client is suboptimal because the
first part of a verifier is set to the first IP address from
V_in_ifaddrhead list. This address is typically the loopback address
making the first part of the verifier practically non-unique. The second
part of the verifier is initialized to zero making its initial value
non-unique too.
This commit changes the strategy for create verifier initialization:
just initialize it to a random value. Also move verifier handling into
its own function and use a mutex to protect the variable.
This change is a candidate for porting to sys/nfsclient.
Reviewed by: jhb, rmacklem
Approved by: trasz (mentor)
Diffstat (limited to 'sys/fs/nfsclient/nfs_clvnops.c')
-rw-r--r-- | sys/fs/nfsclient/nfs_clvnops.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 5dc3a59..c60ae57 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1365,7 +1365,30 @@ nfs_mknod(struct vop_mknod_args *ap) return (nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap)); } -static u_long create_verf; +static struct mtx nfs_cverf_mtx; +MTX_SYSINIT(nfs_cverf_mtx, &nfs_cverf_mtx, "NFS create verifier mutex", + MTX_DEF); + +static nfsquad_t +nfs_get_cverf(void) +{ + static nfsquad_t cverf; + nfsquad_t ret; + static int cverf_initialized = 0; + + mtx_lock(&nfs_cverf_mtx); + if (cverf_initialized == 0) { + cverf.lval[0] = arc4random(); + cverf.lval[1] = arc4random(); + cverf_initialized = 1; + } else + cverf.qval++; + ret = cverf; + mtx_unlock(&nfs_cverf_mtx); + + return (ret); +} + /* * nfs file create call */ @@ -1405,19 +1428,7 @@ again: } mtx_unlock(&dnp->n_mtx); -#ifdef INET - CURVNET_SET(CRED_TO_VNET(cnp->cn_cred)); - IN_IFADDR_RLOCK(); - if (!TAILQ_EMPTY(&V_in_ifaddrhead)) - cverf.lval[0] = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr.s_addr; - else -#endif - cverf.lval[0] = create_verf; -#ifdef INET - IN_IFADDR_RUNLOCK(); - CURVNET_RESTORE(); -#endif - cverf.lval[1] = ++create_verf; + cverf = nfs_get_cverf(); error = nfsrpc_create(dvp, cnp->cn_nameptr, cnp->cn_namelen, vap, cverf, fmode, cnp->cn_cred, cnp->cn_thread, &dnfsva, &nfsva, &nfhp, &attrflag, &dattrflag, NULL); |