mirror of
https://github.com/torvalds/linux.git
synced 2024-11-05 19:41:54 +00:00
nfsd: move the confirmed and unconfirmed hlists to a rbtree
The current code requires that we md5 hash the name in order to store the client in the confirmed and unconfirmed trees. Change it instead to store the clients in a pair of rbtrees, and simply compare the cl_names directly instead of hashing them. This also necessitates that we add a new flag to the clp->cl_flags field to indicate which tree the client is currently in. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
parent
0ce0c2b5d2
commit
ac55fdc408
@ -412,10 +412,10 @@ static unsigned int clientstr_hashval(const char *name)
|
|||||||
* reclaim_str_hashtbl[] holds known client info from previous reset/reboot
|
* reclaim_str_hashtbl[] holds known client info from previous reset/reboot
|
||||||
* used in reboot/reset lease grace period processing
|
* used in reboot/reset lease grace period processing
|
||||||
*
|
*
|
||||||
* conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed
|
* conf_id_hashtbl[], and conf_name_tree hold confirmed
|
||||||
* setclientid_confirmed info.
|
* setclientid_confirmed info.
|
||||||
*
|
*
|
||||||
* unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed
|
* unconf_id_hashtbl[] and unconf_name_tree hold unconfirmed
|
||||||
* setclientid info.
|
* setclientid info.
|
||||||
*
|
*
|
||||||
* client_lru holds client queue ordered by nfs4_client.cl_time
|
* client_lru holds client queue ordered by nfs4_client.cl_time
|
||||||
@ -423,13 +423,15 @@ static unsigned int clientstr_hashval(const char *name)
|
|||||||
*
|
*
|
||||||
* close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
|
* close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time
|
||||||
* for last close replay.
|
* for last close replay.
|
||||||
|
*
|
||||||
|
* All of the above fields are protected by the client_mutex.
|
||||||
*/
|
*/
|
||||||
static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
|
static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
|
||||||
static int reclaim_str_hashtbl_size = 0;
|
static int reclaim_str_hashtbl_size = 0;
|
||||||
static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
|
static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
|
||||||
static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
|
|
||||||
static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
|
|
||||||
static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
|
static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
|
||||||
|
static struct rb_root conf_name_tree;
|
||||||
|
static struct rb_root unconf_name_tree;
|
||||||
static struct list_head client_lru;
|
static struct list_head client_lru;
|
||||||
static struct list_head close_lru;
|
static struct list_head close_lru;
|
||||||
|
|
||||||
@ -1144,7 +1146,10 @@ destroy_client(struct nfs4_client *clp)
|
|||||||
if (clp->cl_cb_conn.cb_xprt)
|
if (clp->cl_cb_conn.cb_xprt)
|
||||||
svc_xprt_put(clp->cl_cb_conn.cb_xprt);
|
svc_xprt_put(clp->cl_cb_conn.cb_xprt);
|
||||||
list_del(&clp->cl_idhash);
|
list_del(&clp->cl_idhash);
|
||||||
list_del(&clp->cl_strhash);
|
if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags))
|
||||||
|
rb_erase(&clp->cl_namenode, &conf_name_tree);
|
||||||
|
else
|
||||||
|
rb_erase(&clp->cl_namenode, &unconf_name_tree);
|
||||||
spin_lock(&client_lock);
|
spin_lock(&client_lock);
|
||||||
unhash_client_locked(clp);
|
unhash_client_locked(clp);
|
||||||
if (atomic_read(&clp->cl_refcount) == 0)
|
if (atomic_read(&clp->cl_refcount) == 0)
|
||||||
@ -1187,6 +1192,17 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long long
|
||||||
|
compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2)
|
||||||
|
{
|
||||||
|
long long res;
|
||||||
|
|
||||||
|
res = o1->len - o2->len;
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
return (long long)memcmp(o1->data, o2->data, o1->len);
|
||||||
|
}
|
||||||
|
|
||||||
static int same_name(const char *n1, const char *n2)
|
static int same_name(const char *n1, const char *n2)
|
||||||
{
|
{
|
||||||
return 0 == memcmp(n1, n2, HEXDIR_LEN);
|
return 0 == memcmp(n1, n2, HEXDIR_LEN);
|
||||||
@ -1307,7 +1323,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
|
|||||||
atomic_set(&clp->cl_refcount, 0);
|
atomic_set(&clp->cl_refcount, 0);
|
||||||
clp->cl_cb_state = NFSD4_CB_UNKNOWN;
|
clp->cl_cb_state = NFSD4_CB_UNKNOWN;
|
||||||
INIT_LIST_HEAD(&clp->cl_idhash);
|
INIT_LIST_HEAD(&clp->cl_idhash);
|
||||||
INIT_LIST_HEAD(&clp->cl_strhash);
|
|
||||||
INIT_LIST_HEAD(&clp->cl_openowners);
|
INIT_LIST_HEAD(&clp->cl_openowners);
|
||||||
INIT_LIST_HEAD(&clp->cl_delegations);
|
INIT_LIST_HEAD(&clp->cl_delegations);
|
||||||
INIT_LIST_HEAD(&clp->cl_lru);
|
INIT_LIST_HEAD(&clp->cl_lru);
|
||||||
@ -1325,11 +1340,52 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
|
add_clp_to_name_tree(struct nfs4_client *new_clp, struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node **new = &(root->rb_node), *parent = NULL;
|
||||||
|
struct nfs4_client *clp;
|
||||||
|
|
||||||
|
while (*new) {
|
||||||
|
clp = rb_entry(*new, struct nfs4_client, cl_namenode);
|
||||||
|
parent = *new;
|
||||||
|
|
||||||
|
if (compare_blob(&clp->cl_name, &new_clp->cl_name) > 0)
|
||||||
|
new = &((*new)->rb_left);
|
||||||
|
else
|
||||||
|
new = &((*new)->rb_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_link_node(&new_clp->cl_namenode, parent, new);
|
||||||
|
rb_insert_color(&new_clp->cl_namenode, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct nfs4_client *
|
||||||
|
find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root)
|
||||||
|
{
|
||||||
|
long long cmp;
|
||||||
|
struct rb_node *node = root->rb_node;
|
||||||
|
struct nfs4_client *clp;
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
clp = rb_entry(node, struct nfs4_client, cl_namenode);
|
||||||
|
cmp = compare_blob(&clp->cl_name, name);
|
||||||
|
if (cmp > 0)
|
||||||
|
node = node->rb_left;
|
||||||
|
else if (cmp < 0)
|
||||||
|
node = node->rb_right;
|
||||||
|
else
|
||||||
|
return clp;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_to_unconfirmed(struct nfs4_client *clp)
|
||||||
{
|
{
|
||||||
unsigned int idhashval;
|
unsigned int idhashval;
|
||||||
|
|
||||||
list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
|
clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
|
||||||
|
add_clp_to_name_tree(clp, &unconf_name_tree);
|
||||||
idhashval = clientid_hashval(clp->cl_clientid.cl_id);
|
idhashval = clientid_hashval(clp->cl_clientid.cl_id);
|
||||||
list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
|
list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
|
||||||
renew_client(clp);
|
renew_client(clp);
|
||||||
@ -1339,12 +1395,12 @@ static void
|
|||||||
move_to_confirmed(struct nfs4_client *clp)
|
move_to_confirmed(struct nfs4_client *clp)
|
||||||
{
|
{
|
||||||
unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
|
unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
|
||||||
unsigned int strhashval;
|
|
||||||
|
|
||||||
dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
|
dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
|
||||||
list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
|
list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
|
||||||
strhashval = clientstr_hashval(clp->cl_recdir);
|
rb_erase(&clp->cl_namenode, &unconf_name_tree);
|
||||||
list_move(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
|
add_clp_to_name_tree(clp, &conf_name_tree);
|
||||||
|
set_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags);
|
||||||
renew_client(clp);
|
renew_client(clp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1387,27 +1443,15 @@ static bool clp_used_exchangeid(struct nfs4_client *clp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct nfs4_client *
|
static struct nfs4_client *
|
||||||
find_confirmed_client_by_str(const char *dname, unsigned int hashval)
|
find_confirmed_client_by_name(struct xdr_netobj *name)
|
||||||
{
|
{
|
||||||
struct nfs4_client *clp;
|
return find_clp_in_name_tree(name, &conf_name_tree);
|
||||||
|
|
||||||
list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
|
|
||||||
if (same_name(clp->cl_recdir, dname))
|
|
||||||
return clp;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nfs4_client *
|
static struct nfs4_client *
|
||||||
find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
|
find_unconfirmed_client_by_name(struct xdr_netobj *name)
|
||||||
{
|
{
|
||||||
struct nfs4_client *clp;
|
return find_clp_in_name_tree(name, &unconf_name_tree);
|
||||||
|
|
||||||
list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
|
|
||||||
if (same_name(clp->cl_recdir, dname))
|
|
||||||
return clp;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1572,7 +1616,6 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
|
|||||||
{
|
{
|
||||||
struct nfs4_client *unconf, *conf, *new;
|
struct nfs4_client *unconf, *conf, *new;
|
||||||
__be32 status;
|
__be32 status;
|
||||||
unsigned int strhashval;
|
|
||||||
char dname[HEXDIR_LEN];
|
char dname[HEXDIR_LEN];
|
||||||
char addr_str[INET6_ADDRSTRLEN];
|
char addr_str[INET6_ADDRSTRLEN];
|
||||||
nfs4_verifier verf = exid->verifier;
|
nfs4_verifier verf = exid->verifier;
|
||||||
@ -1605,11 +1648,9 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
|
|||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
strhashval = clientstr_hashval(dname);
|
|
||||||
|
|
||||||
/* Cases below refer to rfc 5661 section 18.35.4: */
|
/* Cases below refer to rfc 5661 section 18.35.4: */
|
||||||
nfs4_lock_state();
|
nfs4_lock_state();
|
||||||
conf = find_confirmed_client_by_str(dname, strhashval);
|
conf = find_confirmed_client_by_name(&exid->clname);
|
||||||
if (conf) {
|
if (conf) {
|
||||||
bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
|
bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred);
|
||||||
bool verfs_match = same_verf(&verf, &conf->cl_verifier);
|
bool verfs_match = same_verf(&verf, &conf->cl_verifier);
|
||||||
@ -1654,7 +1695,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
unconf = find_unconfirmed_client_by_str(dname, strhashval);
|
unconf = find_unconfirmed_client_by_name(&exid->clname);
|
||||||
if (unconf) /* case 4, possible retry or client restart */
|
if (unconf) /* case 4, possible retry or client restart */
|
||||||
expire_client(unconf);
|
expire_client(unconf);
|
||||||
|
|
||||||
@ -1668,7 +1709,7 @@ out_new:
|
|||||||
new->cl_minorversion = 1;
|
new->cl_minorversion = 1;
|
||||||
|
|
||||||
gen_clid(new);
|
gen_clid(new);
|
||||||
add_to_unconfirmed(new, strhashval);
|
add_to_unconfirmed(new);
|
||||||
out_copy:
|
out_copy:
|
||||||
exid->clientid.cl_boot = new->cl_clientid.cl_boot;
|
exid->clientid.cl_boot = new->cl_clientid.cl_boot;
|
||||||
exid->clientid.cl_id = new->cl_clientid.cl_id;
|
exid->clientid.cl_id = new->cl_clientid.cl_id;
|
||||||
@ -1789,7 +1830,6 @@ nfsd4_create_session(struct svc_rqst *rqstp,
|
|||||||
goto out_free_conn;
|
goto out_free_conn;
|
||||||
}
|
}
|
||||||
} else if (unconf) {
|
} else if (unconf) {
|
||||||
unsigned int hash;
|
|
||||||
struct nfs4_client *old;
|
struct nfs4_client *old;
|
||||||
if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
|
if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) ||
|
||||||
!rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
|
!rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) {
|
||||||
@ -1803,8 +1843,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
|
|||||||
status = nfserr_seq_misordered;
|
status = nfserr_seq_misordered;
|
||||||
goto out_free_conn;
|
goto out_free_conn;
|
||||||
}
|
}
|
||||||
hash = clientstr_hashval(unconf->cl_recdir);
|
old = find_confirmed_client_by_name(&unconf->cl_name);
|
||||||
old = find_confirmed_client_by_str(unconf->cl_recdir, hash);
|
|
||||||
if (old)
|
if (old)
|
||||||
expire_client(old);
|
expire_client(old);
|
||||||
move_to_confirmed(unconf);
|
move_to_confirmed(unconf);
|
||||||
@ -2195,7 +2234,6 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
{
|
{
|
||||||
struct xdr_netobj clname = setclid->se_name;
|
struct xdr_netobj clname = setclid->se_name;
|
||||||
nfs4_verifier clverifier = setclid->se_verf;
|
nfs4_verifier clverifier = setclid->se_verf;
|
||||||
unsigned int strhashval;
|
|
||||||
struct nfs4_client *conf, *unconf, *new;
|
struct nfs4_client *conf, *unconf, *new;
|
||||||
__be32 status;
|
__be32 status;
|
||||||
char dname[HEXDIR_LEN];
|
char dname[HEXDIR_LEN];
|
||||||
@ -2204,11 +2242,9 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
strhashval = clientstr_hashval(dname);
|
|
||||||
|
|
||||||
/* Cases below refer to rfc 3530 section 14.2.33: */
|
/* Cases below refer to rfc 3530 section 14.2.33: */
|
||||||
nfs4_lock_state();
|
nfs4_lock_state();
|
||||||
conf = find_confirmed_client_by_str(dname, strhashval);
|
conf = find_confirmed_client_by_name(&clname);
|
||||||
if (conf) {
|
if (conf) {
|
||||||
/* case 0: */
|
/* case 0: */
|
||||||
status = nfserr_clid_inuse;
|
status = nfserr_clid_inuse;
|
||||||
@ -2223,7 +2259,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unconf = find_unconfirmed_client_by_str(dname, strhashval);
|
unconf = find_unconfirmed_client_by_name(&clname);
|
||||||
if (unconf)
|
if (unconf)
|
||||||
expire_client(unconf);
|
expire_client(unconf);
|
||||||
status = nfserr_jukebox;
|
status = nfserr_jukebox;
|
||||||
@ -2237,7 +2273,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
gen_clid(new);
|
gen_clid(new);
|
||||||
new->cl_minorversion = 0;
|
new->cl_minorversion = 0;
|
||||||
gen_callback(new, setclid, rqstp);
|
gen_callback(new, setclid, rqstp);
|
||||||
add_to_unconfirmed(new, strhashval);
|
add_to_unconfirmed(new);
|
||||||
setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
|
setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
|
||||||
setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
|
setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
|
||||||
memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
|
memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data));
|
||||||
@ -2290,9 +2326,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
|
|||||||
nfsd4_probe_callback(conf);
|
nfsd4_probe_callback(conf);
|
||||||
expire_client(unconf);
|
expire_client(unconf);
|
||||||
} else { /* case 3: normal case; new or rebooted client */
|
} else { /* case 3: normal case; new or rebooted client */
|
||||||
unsigned int hash = clientstr_hashval(unconf->cl_recdir);
|
conf = find_confirmed_client_by_name(&unconf->cl_name);
|
||||||
|
|
||||||
conf = find_confirmed_client_by_str(unconf->cl_recdir, hash);
|
|
||||||
if (conf)
|
if (conf)
|
||||||
expire_client(conf);
|
expire_client(conf);
|
||||||
move_to_confirmed(unconf);
|
move_to_confirmed(unconf);
|
||||||
@ -4706,11 +4740,11 @@ nfs4_state_init(void)
|
|||||||
|
|
||||||
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
||||||
INIT_LIST_HEAD(&conf_id_hashtbl[i]);
|
INIT_LIST_HEAD(&conf_id_hashtbl[i]);
|
||||||
INIT_LIST_HEAD(&conf_str_hashtbl[i]);
|
|
||||||
INIT_LIST_HEAD(&unconf_str_hashtbl[i]);
|
|
||||||
INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
|
INIT_LIST_HEAD(&unconf_id_hashtbl[i]);
|
||||||
INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
|
INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
|
||||||
}
|
}
|
||||||
|
conf_name_tree = RB_ROOT;
|
||||||
|
unconf_name_tree = RB_ROOT;
|
||||||
for (i = 0; i < SESSION_HASH_SIZE; i++)
|
for (i = 0; i < SESSION_HASH_SIZE; i++)
|
||||||
INIT_LIST_HEAD(&sessionid_hashtbl[i]);
|
INIT_LIST_HEAD(&sessionid_hashtbl[i]);
|
||||||
for (i = 0; i < FILE_HASH_SIZE; i++) {
|
for (i = 0; i < FILE_HASH_SIZE; i++) {
|
||||||
@ -4795,6 +4829,7 @@ out_recovery:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* should be called with the state lock held */
|
||||||
static void
|
static void
|
||||||
__nfs4_state_shutdown(void)
|
__nfs4_state_shutdown(void)
|
||||||
{
|
{
|
||||||
@ -4802,17 +4837,24 @@ __nfs4_state_shutdown(void)
|
|||||||
struct nfs4_client *clp = NULL;
|
struct nfs4_client *clp = NULL;
|
||||||
struct nfs4_delegation *dp = NULL;
|
struct nfs4_delegation *dp = NULL;
|
||||||
struct list_head *pos, *next, reaplist;
|
struct list_head *pos, *next, reaplist;
|
||||||
|
struct rb_node *node, *tmp;
|
||||||
|
|
||||||
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
|
||||||
while (!list_empty(&conf_id_hashtbl[i])) {
|
while (!list_empty(&conf_id_hashtbl[i])) {
|
||||||
clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
|
clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash);
|
||||||
destroy_client(clp);
|
destroy_client(clp);
|
||||||
}
|
}
|
||||||
while (!list_empty(&unconf_str_hashtbl[i])) {
|
|
||||||
clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash);
|
|
||||||
destroy_client(clp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = rb_first(&unconf_name_tree);
|
||||||
|
while (node != NULL) {
|
||||||
|
tmp = node;
|
||||||
|
node = rb_next(tmp);
|
||||||
|
clp = rb_entry(tmp, struct nfs4_client, cl_namenode);
|
||||||
|
rb_erase(tmp, &unconf_name_tree);
|
||||||
|
destroy_client(clp);
|
||||||
|
}
|
||||||
|
|
||||||
INIT_LIST_HEAD(&reaplist);
|
INIT_LIST_HEAD(&reaplist);
|
||||||
spin_lock(&recall_lock);
|
spin_lock(&recall_lock);
|
||||||
list_for_each_safe(pos, next, &del_recall_lru) {
|
list_for_each_safe(pos, next, &del_recall_lru) {
|
||||||
|
@ -232,7 +232,7 @@ struct nfsd4_sessionid {
|
|||||||
*/
|
*/
|
||||||
struct nfs4_client {
|
struct nfs4_client {
|
||||||
struct list_head cl_idhash; /* hash by cl_clientid.id */
|
struct list_head cl_idhash; /* hash by cl_clientid.id */
|
||||||
struct list_head cl_strhash; /* hash by cl_name */
|
struct rb_node cl_namenode; /* link into by-name trees */
|
||||||
struct list_head cl_openowners;
|
struct list_head cl_openowners;
|
||||||
struct idr cl_stateids; /* stateid lookup */
|
struct idr cl_stateids; /* stateid lookup */
|
||||||
struct list_head cl_delegations;
|
struct list_head cl_delegations;
|
||||||
@ -253,6 +253,7 @@ struct nfs4_client {
|
|||||||
#define NFSD4_CLIENT_CB_KILL (1)
|
#define NFSD4_CLIENT_CB_KILL (1)
|
||||||
#define NFSD4_CLIENT_STABLE (2) /* client on stable storage */
|
#define NFSD4_CLIENT_STABLE (2) /* client on stable storage */
|
||||||
#define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */
|
#define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */
|
||||||
|
#define NFSD4_CLIENT_CONFIRMED (4) /* client is confirmed */
|
||||||
#define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \
|
#define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \
|
||||||
1 << NFSD4_CLIENT_CB_KILL)
|
1 << NFSD4_CLIENT_CB_KILL)
|
||||||
unsigned long cl_flags;
|
unsigned long cl_flags;
|
||||||
|
Loading…
Reference in New Issue
Block a user