diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index 2ee91457b5a1..be60c1ca7753 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -138,11 +138,11 @@ /* * This macro defines the high water mark for issuing V4 delegations. - * (It is currently set at a conservative 20% of NFSRV_V4STATELIMIT. This + * (It is currently set at a conservative 20% of nfsrv_v4statelimit. This * may want to increase when clients can make more effective use of * delegations.) */ -#define NFSRV_V4DELEGLIMIT(c) (((c) * 5) > NFSRV_V4STATELIMIT) +#define NFSRV_V4DELEGLIMIT(c) (((c) * 5) > nfsrv_v4statelimit) #define NFS_READDIRBLKSIZ DIRBLKSIZ /* Minimal nm_readdirsize */ diff --git a/sys/fs/nfs/nfsdport.h b/sys/fs/nfs/nfsdport.h index efa4b12500ca..a20b55469a71 100644 --- a/sys/fs/nfs/nfsdport.h +++ b/sys/fs/nfs/nfsdport.h @@ -88,7 +88,7 @@ struct nfsexstuff { bcmp(&(f1)->fh_fid, &(f2)->fh_fid, sizeof(struct fid)) == 0) #define NFSLOCKHASH(f) \ - (&nfslockhash[nfsrv_hashfh(f) % NFSLOCKHASHSIZE]) + (&nfslockhash[nfsrv_hashfh(f) % nfsrv_lockhashsize]) #define NFSFPVNODE(f) ((struct vnode *)((f)->f_data)) #define NFSFPCRED(f) ((f)->f_cred) diff --git a/sys/fs/nfs/nfsrvstate.h b/sys/fs/nfs/nfsrvstate.h index 59a0542c1c9c..972fffe15eb9 100644 --- a/sys/fs/nfs/nfsrvstate.h +++ b/sys/fs/nfs/nfsrvstate.h @@ -52,9 +52,9 @@ LIST_HEAD(nfsuserhashhead, nfsusrgrp); TAILQ_HEAD(nfsuserlruhead, nfsusrgrp); #define NFSCLIENTHASH(id) \ - (&nfsclienthash[(id).lval[1] % NFSCLIENTHASHSIZE]) + (&nfsclienthash[(id).lval[1] % nfsrv_clienthashsize]) #define NFSSTATEHASH(clp, id) \ - (&((clp)->lc_stateid[(id).other[2] % NFSSTATEHASHSIZE])) + (&((clp)->lc_stateid[(id).other[2] % nfsrv_statehashsize])) #define NFSUSERHASH(id) \ (&nfsuserhash[(id) % NFSUSERHASHSIZE]) #define NFSUSERNAMEHASH(p, l) \ @@ -71,7 +71,7 @@ struct nfssessionhash { struct nfssessionhashhead list; }; #define NFSSESSIONHASH(f) \ - (&nfssessionhash[nfsrv_hashsessionid(f) % NFSSESSIONHASHSIZE]) + (&nfssessionhash[nfsrv_hashsessionid(f) % nfsrv_sessionhashsize]) /* * Client server structure for V4. It is doubly linked into two lists. @@ -81,7 +81,7 @@ struct nfssessionhash { */ struct nfsclient { LIST_ENTRY(nfsclient) lc_hash; /* Clientid hash list */ - struct nfsstatehead lc_stateid[NFSSTATEHASHSIZE]; /* stateid hash */ + struct nfsstatehead *lc_stateid; /* Stateid hash */ struct nfsstatehead lc_open; /* Open owner list */ struct nfsstatehead lc_deleg; /* Delegations */ struct nfsstatehead lc_olddeleg; /* and old delegations */ @@ -97,10 +97,10 @@ struct nfsclient { u_int32_t lc_cbref; /* Cnt of callbacks */ uid_t lc_uid; /* User credential */ gid_t lc_gid; - u_int16_t lc_namelen; + u_int16_t lc_idlen; /* Client ID and len */ + u_int16_t lc_namelen; /* plus GSS principal and len */ u_char *lc_name; struct nfssockreq lc_req; /* Callback info */ - u_short lc_idlen; /* Length of id string */ u_int32_t lc_flags; /* LCL_ flag bits */ u_char lc_verf[NFSX_VERF]; /* client verifier */ u_char lc_id[1]; /* Malloc'd correct size */ diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 94475d93c66a..85b4466575af 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -58,7 +58,10 @@ extern struct nfsrv_stablefirst nfsrv_stablefirst; extern void (*nfsd_call_servertimer)(void); extern SVCPOOL *nfsrvd_pool; extern struct nfsv4lock nfsd_suspend_lock; -extern struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE]; +extern struct nfsclienthashhead *nfsclienthash; +extern struct nfslockhashhead *nfslockhash; +extern struct nfssessionhash *nfssessionhash; +extern int nfsrv_sessionhashsize; struct vfsoptlist nfsv4root_opt, nfsv4root_newopt; NFSDLOCKMUTEX; struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE]; @@ -3330,9 +3333,6 @@ nfsd_modevent(module_t mod, int type, void *data) mtx_init(&nfsrc_udpmtx, "nfsuc", NULL, MTX_DEF); mtx_init(&nfs_v4root_mutex, "nfs4rt", NULL, MTX_DEF); mtx_init(&nfsv4root_mnt.mnt_mtx, "nfs4mnt", NULL, MTX_DEF); - for (i = 0; i < NFSSESSIONHASHSIZE; i++) - mtx_init(&nfssessionhash[i].mtx, "nfssm", - NULL, MTX_DEF); lockinit(&nfsv4root_mnt.mnt_explock, PVFS, "explock", 0, 0); nfsrvd_initcache(); nfsd_init(); @@ -3380,9 +3380,12 @@ nfsd_modevent(module_t mod, int type, void *data) mtx_destroy(&nfsrc_udpmtx); mtx_destroy(&nfs_v4root_mutex); mtx_destroy(&nfsv4root_mnt.mnt_mtx); - for (i = 0; i < NFSSESSIONHASHSIZE; i++) + for (i = 0; i < nfsrv_sessionhashsize; i++) mtx_destroy(&nfssessionhash[i].mtx); lockdestroy(&nfsv4root_mnt.mnt_explock); + free(nfsclienthash, M_NFSDCLIENT); + free(nfslockhash, M_NFSDLOCKFILE); + free(nfssessionhash, M_NFSDSESSION); loaded = 0; break; default: diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index bd0c2dad73ad..bd054c47718d 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -53,6 +53,7 @@ extern enum vtype nv34tov_type[8]; extern struct timeval nfsboottime; extern int nfs_rootfhset; extern int nfsrv_enable_crossmntpt; +extern int nfsrv_statehashsize; #endif /* !APPLEKEXT */ static int nfs_async = 0; @@ -3468,9 +3469,10 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram, idlen = i; if (nd->nd_flag & ND_GSS) i += nd->nd_princlen; - MALLOC(clp, struct nfsclient *, sizeof (struct nfsclient) + i, - M_NFSDCLIENT, M_WAITOK); - NFSBZERO((caddr_t)clp, sizeof (struct nfsclient) + i); + clp = malloc(sizeof(struct nfsclient) + i, M_NFSDCLIENT, M_WAITOK | + M_ZERO); + clp->lc_stateid = malloc(sizeof(struct nfsstatehead) * + nfsrv_statehashsize, M_NFSDCLIENT, M_WAITOK); NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx); NFSSOCKADDRALLOC(clp->lc_req.nr_nam); NFSSOCKADDRSIZE(clp->lc_req.nr_nam, sizeof (struct sockaddr_in)); @@ -3530,7 +3532,8 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram, if (clp) { NFSSOCKADDRFREE(clp->lc_req.nr_nam); NFSFREEMUTEX(&clp->lc_req.nr_mtx); - free((caddr_t)clp, M_NFSDCLIENT); + free(clp->lc_stateid, M_NFSDCLIENT); + free(clp, M_NFSDCLIENT); } if (!nd->nd_repstat) { NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_HYPER); @@ -3547,7 +3550,8 @@ nfsmout: if (clp) { NFSSOCKADDRFREE(clp->lc_req.nr_nam); NFSFREEMUTEX(&clp->lc_req.nr_mtx); - free((caddr_t)clp, M_NFSDCLIENT); + free(clp->lc_stateid, M_NFSDCLIENT); + free(clp, M_NFSDCLIENT); } NFSEXITCODE2(error, nd); return (error); @@ -3738,8 +3742,10 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram, idlen = i; if (nd->nd_flag & ND_GSS) i += nd->nd_princlen; - clp = (struct nfsclient *)malloc(sizeof(struct nfsclient) + i, - M_NFSDCLIENT, M_WAITOK | M_ZERO); + clp = malloc(sizeof(struct nfsclient) + i, M_NFSDCLIENT, M_WAITOK | + M_ZERO); + clp->lc_stateid = malloc(sizeof(struct nfsstatehead) * + nfsrv_statehashsize, M_NFSDCLIENT, M_WAITOK); NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx); NFSSOCKADDRALLOC(clp->lc_req.nr_nam); NFSSOCKADDRSIZE(clp->lc_req.nr_nam, sizeof (struct sockaddr_in)); @@ -3796,6 +3802,7 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram, if (clp != NULL) { NFSSOCKADDRFREE(clp->lc_req.nr_nam); NFSFREEMUTEX(&clp->lc_req.nr_mtx); + free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); } if (nd->nd_repstat == 0) { @@ -3828,6 +3835,7 @@ nfsmout: if (clp != NULL) { NFSSOCKADDRFREE(clp->lc_req.nr_nam); NFSFREEMUTEX(&clp->lc_req.nr_mtx); + free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); } NFSEXITCODE2(error, nd); diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index b15dfec4b648..9c00a0c09b31 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -46,7 +46,8 @@ extern struct nfsrvfh nfs_pubfh, nfs_rootfh; extern int nfs_pubfhset, nfs_rootfhset; extern struct nfsv4lock nfsv4rootfs_lock; extern struct nfsrv_stablefirst nfsrv_stablefirst; -extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE]; +extern struct nfsclienthashhead *nfsclienthash; +extern int nfsrv_clienthashsize; extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies; extern int nfsd_debuglevel; NFSV4ROOTLOCKMUTEX; @@ -610,7 +611,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag, */ if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) { nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT; - for (i = 0; i < NFSCLIENTHASHSIZE; i++) { + for (i = 0; i < nfsrv_clienthashsize; i++) { LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) { if (clp->lc_flags & LCL_EXPIREIT) { diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 5e9beebf0875..15f5243717cf 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -44,14 +44,38 @@ extern u_int32_t newnfs_true, newnfs_false; NFSV4ROOTLOCKMUTEX; NFSSTATESPINLOCK; +SYSCTL_DECL(_vfs_nfsd); +int nfsrv_statehashsize = NFSSTATEHASHSIZE; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, statehashsize, CTLFLAG_RDTUN, + &nfsrv_statehashsize, 0, + "Size of state hash table set via loader.conf"); + +int nfsrv_clienthashsize = NFSCLIENTHASHSIZE; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, clienthashsize, CTLFLAG_RDTUN, + &nfsrv_clienthashsize, 0, + "Size of client hash table set via loader.conf"); + +int nfsrv_lockhashsize = NFSLOCKHASHSIZE; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, fhhashsize, CTLFLAG_RDTUN, + &nfsrv_lockhashsize, 0, + "Size of file handle hash table set via loader.conf"); + +int nfsrv_sessionhashsize = NFSSESSIONHASHSIZE; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, sessionhashsize, CTLFLAG_RDTUN, + &nfsrv_sessionhashsize, 0, + "Size of session hash table set via loader.conf"); + +static int nfsrv_v4statelimit = NFSRV_V4STATELIMIT; +SYSCTL_INT(_vfs_nfsd, OID_AUTO, v4statelimit, CTLFLAG_RWTUN, + &nfsrv_v4statelimit, 0, + "High water limit for NFSv4 opens+locks+delegations"); + /* * Hash lists for nfs V4. - * (Some would put them in the .h file, but I don't like declaring storage - * in a .h) */ -struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE]; -struct nfslockhashhead nfslockhash[NFSLOCKHASHSIZE]; -struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE]; +struct nfsclienthashhead *nfsclienthash; +struct nfslockhashhead *nfslockhash; +struct nfssessionhash *nfssessionhash; #endif /* !APPLEKEXT */ static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0; @@ -153,7 +177,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, /* * Check for state resource limit exceeded. */ - if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) { + if (nfsrv_openpluslock > nfsrv_v4statelimit) { error = NFSERR_RESOURCE; goto out; } @@ -188,7 +212,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, * Search for a match in the client list. */ gotit = i = 0; - while (i < NFSCLIENTHASHSIZE && !gotit) { + while (i < nfsrv_clienthashsize && !gotit) { LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { if (new_clp->lc_idlen == clp->lc_idlen && !NFSBCMP(new_clp->lc_id, clp->lc_id, clp->lc_idlen)) { @@ -215,7 +239,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, /* * Get rid of the old one. */ - if (i != NFSCLIENTHASHSIZE) { + if (i != nfsrv_clienthashsize) { LIST_REMOVE(clp, lc_hash); nfsrv_cleanclient(clp, p); nfsrv_freedeleglist(&clp->lc_deleg); @@ -244,7 +268,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, LIST_INIT(&new_clp->lc_deleg); LIST_INIT(&new_clp->lc_olddeleg); LIST_INIT(&new_clp->lc_session); - for (i = 0; i < NFSSTATEHASHSIZE; i++) + for (i = 0; i < nfsrv_statehashsize; i++) LIST_INIT(&new_clp->lc_stateid[i]); LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp, lc_hash); @@ -344,7 +368,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, ls_list); LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list) tstp->ls_clp = new_clp; - for (i = 0; i < NFSSTATEHASHSIZE; i++) { + for (i = 0; i < nfsrv_statehashsize; i++) { LIST_NEWHEAD(&new_clp->lc_stateid[i], &clp->lc_stateid[i], ls_hash); LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash) @@ -405,7 +429,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp, LIST_NEWHEAD(&new_clp->lc_olddeleg, &clp->lc_olddeleg, ls_list); LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list) tstp->ls_clp = new_clp; - for (i = 0; i < NFSSTATEHASHSIZE; i++) { + for (i = 0; i < nfsrv_statehashsize; i++) { LIST_NEWHEAD(&new_clp->lc_stateid[i], &clp->lc_stateid[i], ls_hash); LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash) @@ -615,7 +639,7 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp, if (!error && (opflags & CLOPS_RENEWOP)) { if (nfsrv_notsamecredname(nd, clp)) { doneok = 0; - for (i = 0; i < NFSSTATEHASHSIZE && doneok == 0; i++) { + for (i = 0; i < nfsrv_statehashsize && doneok == 0; i++) { LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) { if ((stp->ls_flags & NFSLCK_OPEN) && stp->ls_uid == nd->nd_cred->cr_uid) { @@ -687,7 +711,7 @@ nfsrv_destroyclient(nfsquad_t clientid, NFSPROC_T *p) } /* Scan for state on the clientid. */ - for (i = 0; i < NFSSTATEHASHSIZE; i++) + for (i = 0; i < nfsrv_statehashsize; i++) if (!LIST_EMPTY(&clp->lc_stateid[i])) { NFSLOCKV4ROOTMUTEX(); nfsv4_unlock(&nfsv4rootfs_lock, 1); @@ -744,7 +768,7 @@ nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p) * Search for a match in the client list. */ gotit = i = 0; - while (i < NFSCLIENTHASHSIZE && !gotit) { + while (i < nfsrv_clienthashsize && !gotit) { LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) { if (revokep->nclid_idlen == clp->lc_idlen && !NFSBCMP(revokep->nclid_id, clp->lc_id, clp->lc_idlen)) { @@ -806,7 +830,7 @@ nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt) /* * Rattle through the client lists until done. */ - while (i < NFSCLIENTHASHSIZE && cnt < maxcnt) { + while (i < nfsrv_clienthashsize && cnt < maxcnt) { clp = LIST_FIRST(&nfsclienthash[i]); while (clp != LIST_END(&nfsclienthash[i]) && cnt < maxcnt) { nfsrv_dumpaclient(clp, &dumpp[cnt]); @@ -1074,7 +1098,7 @@ nfsrv_servertimer(void) /* * For each client... */ - for (i = 0; i < NFSCLIENTHASHSIZE; i++) { + for (i = 0; i < nfsrv_clienthashsize; i++) { clp = LIST_FIRST(&nfsclienthash[i]); while (clp != LIST_END(&nfsclienthash[i])) { nclp = LIST_NEXT(clp, lc_hash); @@ -1085,7 +1109,7 @@ nfsrv_servertimer(void) nfsrv_clients > nfsrv_clienthighwater)) || (clp->lc_expiry + NFSRV_MOULDYLEASE) < NFSD_MONOSEC || (clp->lc_expiry < NFSD_MONOSEC && - (nfsrv_openpluslock * 10 / 9) > NFSRV_V4STATELIMIT)) { + (nfsrv_openpluslock * 10 / 9) > nfsrv_v4statelimit)) { /* * Lease has expired several nfsrv_lease times ago: * PLUS @@ -1124,7 +1148,7 @@ nfsrv_servertimer(void) stp->ls_noopens++; if (stp->ls_noopens > NFSNOOPEN || (nfsrv_openpluslock * 2) > - NFSRV_V4STATELIMIT) + nfsrv_v4statelimit) nfsrv_stablefirst.nsf_flags |= NFSNSF_NOOPENS; } else { @@ -1188,7 +1212,8 @@ nfsrv_zapclient(struct nfsclient *clp, NFSPROC_T *p) newnfs_disconnect(&clp->lc_req); NFSSOCKADDRFREE(clp->lc_req.nr_nam); NFSFREEMUTEX(&clp->lc_req.nr_mtx); - free((caddr_t)clp, M_NFSDCLIENT); + free(clp->lc_stateid, M_NFSDCLIENT); + free(clp, M_NFSDCLIENT); NFSLOCKSTATE(); newnfsstats.srvclients--; nfsrv_openpluslock--; @@ -1534,7 +1559,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp, * Check for state resource limit exceeded. */ if ((new_stp->ls_flags & NFSLCK_LOCK) && - nfsrv_openpluslock > NFSRV_V4STATELIMIT) { + nfsrv_openpluslock > nfsrv_v4statelimit) { error = NFSERR_RESOURCE; goto out; } @@ -2232,7 +2257,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp, * returns NFSERR_RESOURCE and the limit is just a rather * arbitrary high water mark, so no harm is done. */ - if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) { + if (nfsrv_openpluslock > nfsrv_v4statelimit) { error = NFSERR_RESOURCE; goto out; } @@ -4298,7 +4323,7 @@ nfsrv_nextstateindex(struct nfsclient *clp) */ min_index = 0; max_index = 0xffffffff; - for (i = 0; i < NFSSTATEHASHSIZE; i++) { + for (i = 0; i < nfsrv_statehashsize; i++) { LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) { if (stp->ls_stateid.other[2] > 0x80000000) { if (stp->ls_stateid.other[2] < max_index) @@ -4322,7 +4347,7 @@ nfsrv_nextstateindex(struct nfsclient *clp) * cleanest way to code the loop.) */ tryagain: - for (i = 0; i < NFSSTATEHASHSIZE; i++) { + for (i = 0; i < nfsrv_statehashsize; i++) { LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) { if (stp->ls_stateid.other[2] == canuse) { canuse++; @@ -5319,13 +5344,13 @@ nfsrv_throwawayopens(NFSPROC_T *p) /* * For each client... */ - for (i = 0; i < NFSCLIENTHASHSIZE; i++) { + for (i = 0; i < nfsrv_clienthashsize; i++) { LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) { LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) { if (LIST_EMPTY(&stp->ls_open) && (stp->ls_noopens > NFSNOOPEN || (nfsrv_openpluslock * 2) > - NFSRV_V4STATELIMIT)) + nfsrv_v4statelimit)) nfsrv_freeopenowner(stp, 0, p); } } @@ -5696,11 +5721,12 @@ nfsrv_throwawayallstate(NFSPROC_T *p) /* * For each client, clean out the state and then free the structure. */ - for (i = 0; i < NFSCLIENTHASHSIZE; i++) { + for (i = 0; i < nfsrv_clienthashsize; i++) { LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) { nfsrv_cleanclient(clp, p); nfsrv_freedeleglist(&clp->lc_deleg); nfsrv_freedeleglist(&clp->lc_olddeleg); + free(clp->lc_stateid, M_NFSDCLIENT); free(clp, M_NFSDCLIENT); } } @@ -5708,7 +5734,7 @@ nfsrv_throwawayallstate(NFSPROC_T *p) /* * Also, free up any remaining lock file structures. */ - for (i = 0; i < NFSLOCKHASHSIZE; i++) { + for (i = 0; i < nfsrv_lockhashsize; i++) { LIST_FOREACH_SAFE(lfp, &nfslockhash[i], lf_hash, nlfp) { printf("nfsd unload: fnd a lock file struct\n"); nfsrv_freenfslockfile(lfp); diff --git a/sys/fs/nfsserver/nfs_nfsdsubs.c b/sys/fs/nfsserver/nfs_nfsdsubs.c index 6bd141250784..c0421e34ce1f 100644 --- a/sys/fs/nfsserver/nfs_nfsdsubs.c +++ b/sys/fs/nfsserver/nfs_nfsdsubs.c @@ -44,9 +44,12 @@ __FBSDID("$FreeBSD$"); extern u_int32_t newnfs_true, newnfs_false; extern int nfs_pubfhset; -extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE]; -extern struct nfslockhashhead nfslockhash[NFSLOCKHASHSIZE]; -extern struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE]; +extern struct nfsclienthashhead *nfsclienthash; +extern int nfsrv_clienthashsize; +extern struct nfslockhashhead *nfslockhash; +extern int nfsrv_lockhashsize; +extern struct nfssessionhash *nfssessionhash; +extern int nfsrv_sessionhashsize; extern int nfsrv_useacl; extern uid_t nfsrv_defaultuid; extern gid_t nfsrv_defaultgid; @@ -2036,12 +2039,20 @@ nfsd_init(void) * Initialize client queues. Don't free/reinitialize * them when nfsds are restarted. */ - for (i = 0; i < NFSCLIENTHASHSIZE; i++) + nfsclienthash = malloc(sizeof(struct nfsclienthashhead) * + nfsrv_clienthashsize, M_NFSDCLIENT, M_WAITOK | M_ZERO); + for (i = 0; i < nfsrv_clienthashsize; i++) LIST_INIT(&nfsclienthash[i]); - for (i = 0; i < NFSLOCKHASHSIZE; i++) + nfslockhash = malloc(sizeof(struct nfslockhashhead) * + nfsrv_lockhashsize, M_NFSDLOCKFILE, M_WAITOK | M_ZERO); + for (i = 0; i < nfsrv_lockhashsize; i++) LIST_INIT(&nfslockhash[i]); - for (i = 0; i < NFSSESSIONHASHSIZE; i++) + nfssessionhash = malloc(sizeof(struct nfssessionhash) * + nfsrv_sessionhashsize, M_NFSDSESSION, M_WAITOK | M_ZERO); + for (i = 0; i < nfsrv_sessionhashsize; i++) { + mtx_init(&nfssessionhash[i].mtx, "nfssm", NULL, MTX_DEF); LIST_INIT(&nfssessionhash[i].list); + } /* and the v2 pubfh should be all zeros */ NFSBZERO(nfs_v2pubfh, NFSX_V2FH);