Make the size of the hash tables used by the NFSv4 server tunable.
No appreciable change in performance was observed after increasing the sizes of these tables and then testing with a single client. However, there was an email that indicated high CPU overheads for a heavily loaded NFSv4 and it is hoped that increasing the sizes of the hash tables via these tunables might help. The tables remain the same size by default. Differential Revision: https://reviews.freebsd.org/D2596 MFC after: 2 weeks
This commit is contained in:
parent
2ca937d2ad
commit
1f54e596ad
@ -138,11 +138,11 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* This macro defines the high water mark for issuing V4 delegations.
|
* 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
|
* may want to increase when clients can make more effective use of
|
||||||
* delegations.)
|
* delegations.)
|
||||||
*/
|
*/
|
||||||
#define NFSRV_V4DELEGLIMIT(c) (((c) * 5) > NFSRV_V4STATELIMIT)
|
#define NFSRV_V4DELEGLIMIT(c) (((c) * 5) > nfsrv_v4statelimit)
|
||||||
|
|
||||||
#define NFS_READDIRBLKSIZ DIRBLKSIZ /* Minimal nm_readdirsize */
|
#define NFS_READDIRBLKSIZ DIRBLKSIZ /* Minimal nm_readdirsize */
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ struct nfsexstuff {
|
|||||||
bcmp(&(f1)->fh_fid, &(f2)->fh_fid, sizeof(struct fid)) == 0)
|
bcmp(&(f1)->fh_fid, &(f2)->fh_fid, sizeof(struct fid)) == 0)
|
||||||
|
|
||||||
#define NFSLOCKHASH(f) \
|
#define NFSLOCKHASH(f) \
|
||||||
(&nfslockhash[nfsrv_hashfh(f) % NFSLOCKHASHSIZE])
|
(&nfslockhash[nfsrv_hashfh(f) % nfsrv_lockhashsize])
|
||||||
|
|
||||||
#define NFSFPVNODE(f) ((struct vnode *)((f)->f_data))
|
#define NFSFPVNODE(f) ((struct vnode *)((f)->f_data))
|
||||||
#define NFSFPCRED(f) ((f)->f_cred)
|
#define NFSFPCRED(f) ((f)->f_cred)
|
||||||
|
@ -52,9 +52,9 @@ LIST_HEAD(nfsuserhashhead, nfsusrgrp);
|
|||||||
TAILQ_HEAD(nfsuserlruhead, nfsusrgrp);
|
TAILQ_HEAD(nfsuserlruhead, nfsusrgrp);
|
||||||
|
|
||||||
#define NFSCLIENTHASH(id) \
|
#define NFSCLIENTHASH(id) \
|
||||||
(&nfsclienthash[(id).lval[1] % NFSCLIENTHASHSIZE])
|
(&nfsclienthash[(id).lval[1] % nfsrv_clienthashsize])
|
||||||
#define NFSSTATEHASH(clp, id) \
|
#define NFSSTATEHASH(clp, id) \
|
||||||
(&((clp)->lc_stateid[(id).other[2] % NFSSTATEHASHSIZE]))
|
(&((clp)->lc_stateid[(id).other[2] % nfsrv_statehashsize]))
|
||||||
#define NFSUSERHASH(id) \
|
#define NFSUSERHASH(id) \
|
||||||
(&nfsuserhash[(id) % NFSUSERHASHSIZE])
|
(&nfsuserhash[(id) % NFSUSERHASHSIZE])
|
||||||
#define NFSUSERNAMEHASH(p, l) \
|
#define NFSUSERNAMEHASH(p, l) \
|
||||||
@ -71,7 +71,7 @@ struct nfssessionhash {
|
|||||||
struct nfssessionhashhead list;
|
struct nfssessionhashhead list;
|
||||||
};
|
};
|
||||||
#define NFSSESSIONHASH(f) \
|
#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.
|
* Client server structure for V4. It is doubly linked into two lists.
|
||||||
@ -81,7 +81,7 @@ struct nfssessionhash {
|
|||||||
*/
|
*/
|
||||||
struct nfsclient {
|
struct nfsclient {
|
||||||
LIST_ENTRY(nfsclient) lc_hash; /* Clientid hash list */
|
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_open; /* Open owner list */
|
||||||
struct nfsstatehead lc_deleg; /* Delegations */
|
struct nfsstatehead lc_deleg; /* Delegations */
|
||||||
struct nfsstatehead lc_olddeleg; /* and old delegations */
|
struct nfsstatehead lc_olddeleg; /* and old delegations */
|
||||||
@ -97,10 +97,10 @@ struct nfsclient {
|
|||||||
u_int32_t lc_cbref; /* Cnt of callbacks */
|
u_int32_t lc_cbref; /* Cnt of callbacks */
|
||||||
uid_t lc_uid; /* User credential */
|
uid_t lc_uid; /* User credential */
|
||||||
gid_t lc_gid;
|
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;
|
u_char *lc_name;
|
||||||
struct nfssockreq lc_req; /* Callback info */
|
struct nfssockreq lc_req; /* Callback info */
|
||||||
u_short lc_idlen; /* Length of id string */
|
|
||||||
u_int32_t lc_flags; /* LCL_ flag bits */
|
u_int32_t lc_flags; /* LCL_ flag bits */
|
||||||
u_char lc_verf[NFSX_VERF]; /* client verifier */
|
u_char lc_verf[NFSX_VERF]; /* client verifier */
|
||||||
u_char lc_id[1]; /* Malloc'd correct size */
|
u_char lc_id[1]; /* Malloc'd correct size */
|
||||||
|
@ -58,7 +58,10 @@ extern struct nfsrv_stablefirst nfsrv_stablefirst;
|
|||||||
extern void (*nfsd_call_servertimer)(void);
|
extern void (*nfsd_call_servertimer)(void);
|
||||||
extern SVCPOOL *nfsrvd_pool;
|
extern SVCPOOL *nfsrvd_pool;
|
||||||
extern struct nfsv4lock nfsd_suspend_lock;
|
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;
|
struct vfsoptlist nfsv4root_opt, nfsv4root_newopt;
|
||||||
NFSDLOCKMUTEX;
|
NFSDLOCKMUTEX;
|
||||||
struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE];
|
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(&nfsrc_udpmtx, "nfsuc", NULL, MTX_DEF);
|
||||||
mtx_init(&nfs_v4root_mutex, "nfs4rt", NULL, MTX_DEF);
|
mtx_init(&nfs_v4root_mutex, "nfs4rt", NULL, MTX_DEF);
|
||||||
mtx_init(&nfsv4root_mnt.mnt_mtx, "nfs4mnt", 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);
|
lockinit(&nfsv4root_mnt.mnt_explock, PVFS, "explock", 0, 0);
|
||||||
nfsrvd_initcache();
|
nfsrvd_initcache();
|
||||||
nfsd_init();
|
nfsd_init();
|
||||||
@ -3380,9 +3380,12 @@ nfsd_modevent(module_t mod, int type, void *data)
|
|||||||
mtx_destroy(&nfsrc_udpmtx);
|
mtx_destroy(&nfsrc_udpmtx);
|
||||||
mtx_destroy(&nfs_v4root_mutex);
|
mtx_destroy(&nfs_v4root_mutex);
|
||||||
mtx_destroy(&nfsv4root_mnt.mnt_mtx);
|
mtx_destroy(&nfsv4root_mnt.mnt_mtx);
|
||||||
for (i = 0; i < NFSSESSIONHASHSIZE; i++)
|
for (i = 0; i < nfsrv_sessionhashsize; i++)
|
||||||
mtx_destroy(&nfssessionhash[i].mtx);
|
mtx_destroy(&nfssessionhash[i].mtx);
|
||||||
lockdestroy(&nfsv4root_mnt.mnt_explock);
|
lockdestroy(&nfsv4root_mnt.mnt_explock);
|
||||||
|
free(nfsclienthash, M_NFSDCLIENT);
|
||||||
|
free(nfslockhash, M_NFSDLOCKFILE);
|
||||||
|
free(nfssessionhash, M_NFSDSESSION);
|
||||||
loaded = 0;
|
loaded = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -53,6 +53,7 @@ extern enum vtype nv34tov_type[8];
|
|||||||
extern struct timeval nfsboottime;
|
extern struct timeval nfsboottime;
|
||||||
extern int nfs_rootfhset;
|
extern int nfs_rootfhset;
|
||||||
extern int nfsrv_enable_crossmntpt;
|
extern int nfsrv_enable_crossmntpt;
|
||||||
|
extern int nfsrv_statehashsize;
|
||||||
#endif /* !APPLEKEXT */
|
#endif /* !APPLEKEXT */
|
||||||
|
|
||||||
static int nfs_async = 0;
|
static int nfs_async = 0;
|
||||||
@ -3468,9 +3469,10 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram,
|
|||||||
idlen = i;
|
idlen = i;
|
||||||
if (nd->nd_flag & ND_GSS)
|
if (nd->nd_flag & ND_GSS)
|
||||||
i += nd->nd_princlen;
|
i += nd->nd_princlen;
|
||||||
MALLOC(clp, struct nfsclient *, sizeof (struct nfsclient) + i,
|
clp = malloc(sizeof(struct nfsclient) + i, M_NFSDCLIENT, M_WAITOK |
|
||||||
M_NFSDCLIENT, M_WAITOK);
|
M_ZERO);
|
||||||
NFSBZERO((caddr_t)clp, sizeof (struct nfsclient) + i);
|
clp->lc_stateid = malloc(sizeof(struct nfsstatehead) *
|
||||||
|
nfsrv_statehashsize, M_NFSDCLIENT, M_WAITOK);
|
||||||
NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx);
|
NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx);
|
||||||
NFSSOCKADDRALLOC(clp->lc_req.nr_nam);
|
NFSSOCKADDRALLOC(clp->lc_req.nr_nam);
|
||||||
NFSSOCKADDRSIZE(clp->lc_req.nr_nam, sizeof (struct sockaddr_in));
|
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) {
|
if (clp) {
|
||||||
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
||||||
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
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) {
|
if (!nd->nd_repstat) {
|
||||||
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_HYPER);
|
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_HYPER);
|
||||||
@ -3547,7 +3550,8 @@ nfsmout:
|
|||||||
if (clp) {
|
if (clp) {
|
||||||
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
||||||
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
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);
|
NFSEXITCODE2(error, nd);
|
||||||
return (error);
|
return (error);
|
||||||
@ -3738,8 +3742,10 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram,
|
|||||||
idlen = i;
|
idlen = i;
|
||||||
if (nd->nd_flag & ND_GSS)
|
if (nd->nd_flag & ND_GSS)
|
||||||
i += nd->nd_princlen;
|
i += nd->nd_princlen;
|
||||||
clp = (struct nfsclient *)malloc(sizeof(struct nfsclient) + i,
|
clp = malloc(sizeof(struct nfsclient) + i, M_NFSDCLIENT, M_WAITOK |
|
||||||
M_NFSDCLIENT, M_WAITOK | M_ZERO);
|
M_ZERO);
|
||||||
|
clp->lc_stateid = malloc(sizeof(struct nfsstatehead) *
|
||||||
|
nfsrv_statehashsize, M_NFSDCLIENT, M_WAITOK);
|
||||||
NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx);
|
NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx);
|
||||||
NFSSOCKADDRALLOC(clp->lc_req.nr_nam);
|
NFSSOCKADDRALLOC(clp->lc_req.nr_nam);
|
||||||
NFSSOCKADDRSIZE(clp->lc_req.nr_nam, sizeof (struct sockaddr_in));
|
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) {
|
if (clp != NULL) {
|
||||||
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
||||||
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
||||||
|
free(clp->lc_stateid, M_NFSDCLIENT);
|
||||||
free(clp, M_NFSDCLIENT);
|
free(clp, M_NFSDCLIENT);
|
||||||
}
|
}
|
||||||
if (nd->nd_repstat == 0) {
|
if (nd->nd_repstat == 0) {
|
||||||
@ -3828,6 +3835,7 @@ nfsmout:
|
|||||||
if (clp != NULL) {
|
if (clp != NULL) {
|
||||||
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
||||||
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
||||||
|
free(clp->lc_stateid, M_NFSDCLIENT);
|
||||||
free(clp, M_NFSDCLIENT);
|
free(clp, M_NFSDCLIENT);
|
||||||
}
|
}
|
||||||
NFSEXITCODE2(error, nd);
|
NFSEXITCODE2(error, nd);
|
||||||
|
@ -46,7 +46,8 @@ extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
|
|||||||
extern int nfs_pubfhset, nfs_rootfhset;
|
extern int nfs_pubfhset, nfs_rootfhset;
|
||||||
extern struct nfsv4lock nfsv4rootfs_lock;
|
extern struct nfsv4lock nfsv4rootfs_lock;
|
||||||
extern struct nfsrv_stablefirst nfsrv_stablefirst;
|
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 nfsrc_floodlevel, nfsrc_tcpsavedreplies;
|
||||||
extern int nfsd_debuglevel;
|
extern int nfsd_debuglevel;
|
||||||
NFSV4ROOTLOCKMUTEX;
|
NFSV4ROOTLOCKMUTEX;
|
||||||
@ -610,7 +611,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
|
|||||||
*/
|
*/
|
||||||
if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
|
if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
|
||||||
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,
|
LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
|
||||||
nclp) {
|
nclp) {
|
||||||
if (clp->lc_flags & LCL_EXPIREIT) {
|
if (clp->lc_flags & LCL_EXPIREIT) {
|
||||||
|
@ -44,14 +44,38 @@ extern u_int32_t newnfs_true, newnfs_false;
|
|||||||
NFSV4ROOTLOCKMUTEX;
|
NFSV4ROOTLOCKMUTEX;
|
||||||
NFSSTATESPINLOCK;
|
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.
|
* 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 nfsclienthashhead *nfsclienthash;
|
||||||
struct nfslockhashhead nfslockhash[NFSLOCKHASHSIZE];
|
struct nfslockhashhead *nfslockhash;
|
||||||
struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE];
|
struct nfssessionhash *nfssessionhash;
|
||||||
#endif /* !APPLEKEXT */
|
#endif /* !APPLEKEXT */
|
||||||
|
|
||||||
static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0;
|
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.
|
* Check for state resource limit exceeded.
|
||||||
*/
|
*/
|
||||||
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
|
if (nfsrv_openpluslock > nfsrv_v4statelimit) {
|
||||||
error = NFSERR_RESOURCE;
|
error = NFSERR_RESOURCE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -188,7 +212,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
|||||||
* Search for a match in the client list.
|
* Search for a match in the client list.
|
||||||
*/
|
*/
|
||||||
gotit = i = 0;
|
gotit = i = 0;
|
||||||
while (i < NFSCLIENTHASHSIZE && !gotit) {
|
while (i < nfsrv_clienthashsize && !gotit) {
|
||||||
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
|
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
|
||||||
if (new_clp->lc_idlen == clp->lc_idlen &&
|
if (new_clp->lc_idlen == clp->lc_idlen &&
|
||||||
!NFSBCMP(new_clp->lc_id, clp->lc_id, 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.
|
* Get rid of the old one.
|
||||||
*/
|
*/
|
||||||
if (i != NFSCLIENTHASHSIZE) {
|
if (i != nfsrv_clienthashsize) {
|
||||||
LIST_REMOVE(clp, lc_hash);
|
LIST_REMOVE(clp, lc_hash);
|
||||||
nfsrv_cleanclient(clp, p);
|
nfsrv_cleanclient(clp, p);
|
||||||
nfsrv_freedeleglist(&clp->lc_deleg);
|
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_deleg);
|
||||||
LIST_INIT(&new_clp->lc_olddeleg);
|
LIST_INIT(&new_clp->lc_olddeleg);
|
||||||
LIST_INIT(&new_clp->lc_session);
|
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_INIT(&new_clp->lc_stateid[i]);
|
||||||
LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
|
LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
|
||||||
lc_hash);
|
lc_hash);
|
||||||
@ -344,7 +368,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
|||||||
ls_list);
|
ls_list);
|
||||||
LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list)
|
LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list)
|
||||||
tstp->ls_clp = new_clp;
|
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],
|
LIST_NEWHEAD(&new_clp->lc_stateid[i],
|
||||||
&clp->lc_stateid[i], ls_hash);
|
&clp->lc_stateid[i], ls_hash);
|
||||||
LIST_FOREACH(tstp, &new_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_NEWHEAD(&new_clp->lc_olddeleg, &clp->lc_olddeleg, ls_list);
|
||||||
LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list)
|
LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list)
|
||||||
tstp->ls_clp = new_clp;
|
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],
|
LIST_NEWHEAD(&new_clp->lc_stateid[i],
|
||||||
&clp->lc_stateid[i], ls_hash);
|
&clp->lc_stateid[i], ls_hash);
|
||||||
LIST_FOREACH(tstp, &new_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 (!error && (opflags & CLOPS_RENEWOP)) {
|
||||||
if (nfsrv_notsamecredname(nd, clp)) {
|
if (nfsrv_notsamecredname(nd, clp)) {
|
||||||
doneok = 0;
|
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) {
|
LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) {
|
||||||
if ((stp->ls_flags & NFSLCK_OPEN) &&
|
if ((stp->ls_flags & NFSLCK_OPEN) &&
|
||||||
stp->ls_uid == nd->nd_cred->cr_uid) {
|
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. */
|
/* 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])) {
|
if (!LIST_EMPTY(&clp->lc_stateid[i])) {
|
||||||
NFSLOCKV4ROOTMUTEX();
|
NFSLOCKV4ROOTMUTEX();
|
||||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
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.
|
* Search for a match in the client list.
|
||||||
*/
|
*/
|
||||||
gotit = i = 0;
|
gotit = i = 0;
|
||||||
while (i < NFSCLIENTHASHSIZE && !gotit) {
|
while (i < nfsrv_clienthashsize && !gotit) {
|
||||||
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
|
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
|
||||||
if (revokep->nclid_idlen == clp->lc_idlen &&
|
if (revokep->nclid_idlen == clp->lc_idlen &&
|
||||||
!NFSBCMP(revokep->nclid_id, clp->lc_id, 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.
|
* Rattle through the client lists until done.
|
||||||
*/
|
*/
|
||||||
while (i < NFSCLIENTHASHSIZE && cnt < maxcnt) {
|
while (i < nfsrv_clienthashsize && cnt < maxcnt) {
|
||||||
clp = LIST_FIRST(&nfsclienthash[i]);
|
clp = LIST_FIRST(&nfsclienthash[i]);
|
||||||
while (clp != LIST_END(&nfsclienthash[i]) && cnt < maxcnt) {
|
while (clp != LIST_END(&nfsclienthash[i]) && cnt < maxcnt) {
|
||||||
nfsrv_dumpaclient(clp, &dumpp[cnt]);
|
nfsrv_dumpaclient(clp, &dumpp[cnt]);
|
||||||
@ -1074,7 +1098,7 @@ nfsrv_servertimer(void)
|
|||||||
/*
|
/*
|
||||||
* For each client...
|
* For each client...
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
|
for (i = 0; i < nfsrv_clienthashsize; i++) {
|
||||||
clp = LIST_FIRST(&nfsclienthash[i]);
|
clp = LIST_FIRST(&nfsclienthash[i]);
|
||||||
while (clp != LIST_END(&nfsclienthash[i])) {
|
while (clp != LIST_END(&nfsclienthash[i])) {
|
||||||
nclp = LIST_NEXT(clp, lc_hash);
|
nclp = LIST_NEXT(clp, lc_hash);
|
||||||
@ -1085,7 +1109,7 @@ nfsrv_servertimer(void)
|
|||||||
nfsrv_clients > nfsrv_clienthighwater)) ||
|
nfsrv_clients > nfsrv_clienthighwater)) ||
|
||||||
(clp->lc_expiry + NFSRV_MOULDYLEASE) < NFSD_MONOSEC ||
|
(clp->lc_expiry + NFSRV_MOULDYLEASE) < NFSD_MONOSEC ||
|
||||||
(clp->lc_expiry < 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:
|
* Lease has expired several nfsrv_lease times ago:
|
||||||
* PLUS
|
* PLUS
|
||||||
@ -1124,7 +1148,7 @@ nfsrv_servertimer(void)
|
|||||||
stp->ls_noopens++;
|
stp->ls_noopens++;
|
||||||
if (stp->ls_noopens > NFSNOOPEN ||
|
if (stp->ls_noopens > NFSNOOPEN ||
|
||||||
(nfsrv_openpluslock * 2) >
|
(nfsrv_openpluslock * 2) >
|
||||||
NFSRV_V4STATELIMIT)
|
nfsrv_v4statelimit)
|
||||||
nfsrv_stablefirst.nsf_flags |=
|
nfsrv_stablefirst.nsf_flags |=
|
||||||
NFSNSF_NOOPENS;
|
NFSNSF_NOOPENS;
|
||||||
} else {
|
} else {
|
||||||
@ -1188,7 +1212,8 @@ nfsrv_zapclient(struct nfsclient *clp, NFSPROC_T *p)
|
|||||||
newnfs_disconnect(&clp->lc_req);
|
newnfs_disconnect(&clp->lc_req);
|
||||||
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
|
||||||
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
|
||||||
free((caddr_t)clp, M_NFSDCLIENT);
|
free(clp->lc_stateid, M_NFSDCLIENT);
|
||||||
|
free(clp, M_NFSDCLIENT);
|
||||||
NFSLOCKSTATE();
|
NFSLOCKSTATE();
|
||||||
newnfsstats.srvclients--;
|
newnfsstats.srvclients--;
|
||||||
nfsrv_openpluslock--;
|
nfsrv_openpluslock--;
|
||||||
@ -1534,7 +1559,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
|||||||
* Check for state resource limit exceeded.
|
* Check for state resource limit exceeded.
|
||||||
*/
|
*/
|
||||||
if ((new_stp->ls_flags & NFSLCK_LOCK) &&
|
if ((new_stp->ls_flags & NFSLCK_LOCK) &&
|
||||||
nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
|
nfsrv_openpluslock > nfsrv_v4statelimit) {
|
||||||
error = NFSERR_RESOURCE;
|
error = NFSERR_RESOURCE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -2232,7 +2257,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
|||||||
* returns NFSERR_RESOURCE and the limit is just a rather
|
* returns NFSERR_RESOURCE and the limit is just a rather
|
||||||
* arbitrary high water mark, so no harm is done.
|
* arbitrary high water mark, so no harm is done.
|
||||||
*/
|
*/
|
||||||
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
|
if (nfsrv_openpluslock > nfsrv_v4statelimit) {
|
||||||
error = NFSERR_RESOURCE;
|
error = NFSERR_RESOURCE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -4298,7 +4323,7 @@ nfsrv_nextstateindex(struct nfsclient *clp)
|
|||||||
*/
|
*/
|
||||||
min_index = 0;
|
min_index = 0;
|
||||||
max_index = 0xffffffff;
|
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) {
|
LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) {
|
||||||
if (stp->ls_stateid.other[2] > 0x80000000) {
|
if (stp->ls_stateid.other[2] > 0x80000000) {
|
||||||
if (stp->ls_stateid.other[2] < max_index)
|
if (stp->ls_stateid.other[2] < max_index)
|
||||||
@ -4322,7 +4347,7 @@ nfsrv_nextstateindex(struct nfsclient *clp)
|
|||||||
* cleanest way to code the loop.)
|
* cleanest way to code the loop.)
|
||||||
*/
|
*/
|
||||||
tryagain:
|
tryagain:
|
||||||
for (i = 0; i < NFSSTATEHASHSIZE; i++) {
|
for (i = 0; i < nfsrv_statehashsize; i++) {
|
||||||
LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) {
|
LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) {
|
||||||
if (stp->ls_stateid.other[2] == canuse) {
|
if (stp->ls_stateid.other[2] == canuse) {
|
||||||
canuse++;
|
canuse++;
|
||||||
@ -5319,13 +5344,13 @@ nfsrv_throwawayopens(NFSPROC_T *p)
|
|||||||
/*
|
/*
|
||||||
* For each client...
|
* 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(clp, &nfsclienthash[i], lc_hash, nclp) {
|
||||||
LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) {
|
LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) {
|
||||||
if (LIST_EMPTY(&stp->ls_open) &&
|
if (LIST_EMPTY(&stp->ls_open) &&
|
||||||
(stp->ls_noopens > NFSNOOPEN ||
|
(stp->ls_noopens > NFSNOOPEN ||
|
||||||
(nfsrv_openpluslock * 2) >
|
(nfsrv_openpluslock * 2) >
|
||||||
NFSRV_V4STATELIMIT))
|
nfsrv_v4statelimit))
|
||||||
nfsrv_freeopenowner(stp, 0, p);
|
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 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) {
|
LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) {
|
||||||
nfsrv_cleanclient(clp, p);
|
nfsrv_cleanclient(clp, p);
|
||||||
nfsrv_freedeleglist(&clp->lc_deleg);
|
nfsrv_freedeleglist(&clp->lc_deleg);
|
||||||
nfsrv_freedeleglist(&clp->lc_olddeleg);
|
nfsrv_freedeleglist(&clp->lc_olddeleg);
|
||||||
|
free(clp->lc_stateid, M_NFSDCLIENT);
|
||||||
free(clp, M_NFSDCLIENT);
|
free(clp, M_NFSDCLIENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5708,7 +5734,7 @@ nfsrv_throwawayallstate(NFSPROC_T *p)
|
|||||||
/*
|
/*
|
||||||
* Also, free up any remaining lock file structures.
|
* 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) {
|
LIST_FOREACH_SAFE(lfp, &nfslockhash[i], lf_hash, nlfp) {
|
||||||
printf("nfsd unload: fnd a lock file struct\n");
|
printf("nfsd unload: fnd a lock file struct\n");
|
||||||
nfsrv_freenfslockfile(lfp);
|
nfsrv_freenfslockfile(lfp);
|
||||||
|
@ -44,9 +44,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
extern u_int32_t newnfs_true, newnfs_false;
|
extern u_int32_t newnfs_true, newnfs_false;
|
||||||
extern int nfs_pubfhset;
|
extern int nfs_pubfhset;
|
||||||
extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
|
extern struct nfsclienthashhead *nfsclienthash;
|
||||||
extern struct nfslockhashhead nfslockhash[NFSLOCKHASHSIZE];
|
extern int nfsrv_clienthashsize;
|
||||||
extern struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE];
|
extern struct nfslockhashhead *nfslockhash;
|
||||||
|
extern int nfsrv_lockhashsize;
|
||||||
|
extern struct nfssessionhash *nfssessionhash;
|
||||||
|
extern int nfsrv_sessionhashsize;
|
||||||
extern int nfsrv_useacl;
|
extern int nfsrv_useacl;
|
||||||
extern uid_t nfsrv_defaultuid;
|
extern uid_t nfsrv_defaultuid;
|
||||||
extern gid_t nfsrv_defaultgid;
|
extern gid_t nfsrv_defaultgid;
|
||||||
@ -2036,12 +2039,20 @@ nfsd_init(void)
|
|||||||
* Initialize client queues. Don't free/reinitialize
|
* Initialize client queues. Don't free/reinitialize
|
||||||
* them when nfsds are restarted.
|
* 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]);
|
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]);
|
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);
|
LIST_INIT(&nfssessionhash[i].list);
|
||||||
|
}
|
||||||
|
|
||||||
/* and the v2 pubfh should be all zeros */
|
/* and the v2 pubfh should be all zeros */
|
||||||
NFSBZERO(nfs_v2pubfh, NFSX_V2FH);
|
NFSBZERO(nfs_v2pubfh, NFSX_V2FH);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user