summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/nfs/nfs.h4
-rw-r--r--sys/fs/nfs/nfsdport.h2
-rw-r--r--sys/fs/nfs/nfsrvstate.h12
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c13
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c22
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c5
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c80
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsubs.c23
8 files changed, 105 insertions, 56 deletions
diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h
index 2ee9145..be60c1c 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 efa4b12..a20b554 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 59a0542..972fffe 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 cae2e9f..a700ee9 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];
@@ -3325,9 +3328,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();
@@ -3375,9 +3375,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 bca0cde..0264182 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;
@@ -3442,9 +3443,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));
@@ -3504,7 +3506,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);
@@ -3521,7 +3524,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);
@@ -3712,8 +3716,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));
@@ -3770,6 +3776,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) {
@@ -3802,6 +3809,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 b15dfec..9c00a0c 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 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);
diff --git a/sys/fs/nfsserver/nfs_nfsdsubs.c b/sys/fs/nfsserver/nfs_nfsdsubs.c
index 72408b4..986a0f4 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);
OpenPOWER on IntegriCloud