summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsserver/nfs_nfsdstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/nfsserver/nfs_nfsdstate.c')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c80
1 files changed, 53 insertions, 27 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 9e723a9..f820641 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;
}
@@ -2224,7 +2249,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;
}
@@ -4290,7 +4315,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)
@@ -4314,7 +4339,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++;
@@ -5306,13 +5331,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);
}
}
@@ -5683,11 +5708,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);
}
}
@@ -5695,7 +5721,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);
OpenPOWER on IntegriCloud