diff options
-rw-r--r-- | fs/nfsd/nfs4state.c | 144 | ||||
-rw-r--r-- | fs/nfsd/state.h | 3 |
2 files changed, 95 insertions, 52 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 559ab574d46..99998a1eb42 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -412,10 +412,10 @@ static unsigned int clientstr_hashval(const char *name) | |||
412 | * reclaim_str_hashtbl[] holds known client info from previous reset/reboot | 412 | * reclaim_str_hashtbl[] holds known client info from previous reset/reboot |
413 | * used in reboot/reset lease grace period processing | 413 | * used in reboot/reset lease grace period processing |
414 | * | 414 | * |
415 | * conf_id_hashtbl[], and conf_str_hashtbl[] hold confirmed | 415 | * conf_id_hashtbl[], and conf_name_tree hold confirmed |
416 | * setclientid_confirmed info. | 416 | * setclientid_confirmed info. |
417 | * | 417 | * |
418 | * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed | 418 | * unconf_id_hashtbl[] and unconf_name_tree hold unconfirmed |
419 | * setclientid info. | 419 | * setclientid info. |
420 | * | 420 | * |
421 | * client_lru holds client queue ordered by nfs4_client.cl_time | 421 | * client_lru holds client queue ordered by nfs4_client.cl_time |
@@ -423,13 +423,15 @@ static unsigned int clientstr_hashval(const char *name) | |||
423 | * | 423 | * |
424 | * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time | 424 | * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time |
425 | * for last close replay. | 425 | * for last close replay. |
426 | * | ||
427 | * All of the above fields are protected by the client_mutex. | ||
426 | */ | 428 | */ |
427 | static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE]; | 429 | static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE]; |
428 | static int reclaim_str_hashtbl_size = 0; | 430 | static int reclaim_str_hashtbl_size = 0; |
429 | static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; | 431 | static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; |
430 | static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE]; | ||
431 | static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE]; | ||
432 | static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; | 432 | static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; |
433 | static struct rb_root conf_name_tree; | ||
434 | static struct rb_root unconf_name_tree; | ||
433 | static struct list_head client_lru; | 435 | static struct list_head client_lru; |
434 | static struct list_head close_lru; | 436 | static struct list_head close_lru; |
435 | 437 | ||
@@ -1144,7 +1146,10 @@ destroy_client(struct nfs4_client *clp) | |||
1144 | if (clp->cl_cb_conn.cb_xprt) | 1146 | if (clp->cl_cb_conn.cb_xprt) |
1145 | svc_xprt_put(clp->cl_cb_conn.cb_xprt); | 1147 | svc_xprt_put(clp->cl_cb_conn.cb_xprt); |
1146 | list_del(&clp->cl_idhash); | 1148 | list_del(&clp->cl_idhash); |
1147 | list_del(&clp->cl_strhash); | 1149 | if (test_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags)) |
1150 | rb_erase(&clp->cl_namenode, &conf_name_tree); | ||
1151 | else | ||
1152 | rb_erase(&clp->cl_namenode, &unconf_name_tree); | ||
1148 | spin_lock(&client_lock); | 1153 | spin_lock(&client_lock); |
1149 | unhash_client_locked(clp); | 1154 | unhash_client_locked(clp); |
1150 | if (atomic_read(&clp->cl_refcount) == 0) | 1155 | if (atomic_read(&clp->cl_refcount) == 0) |
@@ -1187,6 +1192,17 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source) | |||
1187 | return 0; | 1192 | return 0; |
1188 | } | 1193 | } |
1189 | 1194 | ||
1195 | static long long | ||
1196 | compare_blob(const struct xdr_netobj *o1, const struct xdr_netobj *o2) | ||
1197 | { | ||
1198 | long long res; | ||
1199 | |||
1200 | res = o1->len - o2->len; | ||
1201 | if (res) | ||
1202 | return res; | ||
1203 | return (long long)memcmp(o1->data, o2->data, o1->len); | ||
1204 | } | ||
1205 | |||
1190 | static int same_name(const char *n1, const char *n2) | 1206 | static int same_name(const char *n1, const char *n2) |
1191 | { | 1207 | { |
1192 | return 0 == memcmp(n1, n2, HEXDIR_LEN); | 1208 | return 0 == memcmp(n1, n2, HEXDIR_LEN); |
@@ -1307,7 +1323,6 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, | |||
1307 | atomic_set(&clp->cl_refcount, 0); | 1323 | atomic_set(&clp->cl_refcount, 0); |
1308 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; | 1324 | clp->cl_cb_state = NFSD4_CB_UNKNOWN; |
1309 | INIT_LIST_HEAD(&clp->cl_idhash); | 1325 | INIT_LIST_HEAD(&clp->cl_idhash); |
1310 | INIT_LIST_HEAD(&clp->cl_strhash); | ||
1311 | INIT_LIST_HEAD(&clp->cl_openowners); | 1326 | INIT_LIST_HEAD(&clp->cl_openowners); |
1312 | INIT_LIST_HEAD(&clp->cl_delegations); | 1327 | INIT_LIST_HEAD(&clp->cl_delegations); |
1313 | INIT_LIST_HEAD(&clp->cl_lru); | 1328 | INIT_LIST_HEAD(&clp->cl_lru); |
@@ -1325,11 +1340,52 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir, | |||
1325 | } | 1340 | } |
1326 | 1341 | ||
1327 | static void | 1342 | static void |
1328 | add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval) | 1343 | add_clp_to_name_tree(struct nfs4_client *new_clp, struct rb_root *root) |
1344 | { | ||
1345 | struct rb_node **new = &(root->rb_node), *parent = NULL; | ||
1346 | struct nfs4_client *clp; | ||
1347 | |||
1348 | while (*new) { | ||
1349 | clp = rb_entry(*new, struct nfs4_client, cl_namenode); | ||
1350 | parent = *new; | ||
1351 | |||
1352 | if (compare_blob(&clp->cl_name, &new_clp->cl_name) > 0) | ||
1353 | new = &((*new)->rb_left); | ||
1354 | else | ||
1355 | new = &((*new)->rb_right); | ||
1356 | } | ||
1357 | |||
1358 | rb_link_node(&new_clp->cl_namenode, parent, new); | ||
1359 | rb_insert_color(&new_clp->cl_namenode, root); | ||
1360 | } | ||
1361 | |||
1362 | static struct nfs4_client * | ||
1363 | find_clp_in_name_tree(struct xdr_netobj *name, struct rb_root *root) | ||
1364 | { | ||
1365 | long long cmp; | ||
1366 | struct rb_node *node = root->rb_node; | ||
1367 | struct nfs4_client *clp; | ||
1368 | |||
1369 | while (node) { | ||
1370 | clp = rb_entry(node, struct nfs4_client, cl_namenode); | ||
1371 | cmp = compare_blob(&clp->cl_name, name); | ||
1372 | if (cmp > 0) | ||
1373 | node = node->rb_left; | ||
1374 | else if (cmp < 0) | ||
1375 | node = node->rb_right; | ||
1376 | else | ||
1377 | return clp; | ||
1378 | } | ||
1379 | return NULL; | ||
1380 | } | ||
1381 | |||
1382 | static void | ||
1383 | add_to_unconfirmed(struct nfs4_client *clp) | ||
1329 | { | 1384 | { |
1330 | unsigned int idhashval; | 1385 | unsigned int idhashval; |
1331 | 1386 | ||
1332 | list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]); | 1387 | clear_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags); |
1388 | add_clp_to_name_tree(clp, &unconf_name_tree); | ||
1333 | idhashval = clientid_hashval(clp->cl_clientid.cl_id); | 1389 | idhashval = clientid_hashval(clp->cl_clientid.cl_id); |
1334 | list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]); | 1390 | list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]); |
1335 | renew_client(clp); | 1391 | renew_client(clp); |
@@ -1339,12 +1395,12 @@ static void | |||
1339 | move_to_confirmed(struct nfs4_client *clp) | 1395 | move_to_confirmed(struct nfs4_client *clp) |
1340 | { | 1396 | { |
1341 | unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id); | 1397 | unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id); |
1342 | unsigned int strhashval; | ||
1343 | 1398 | ||
1344 | dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); | 1399 | dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); |
1345 | list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); | 1400 | list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); |
1346 | strhashval = clientstr_hashval(clp->cl_recdir); | 1401 | rb_erase(&clp->cl_namenode, &unconf_name_tree); |
1347 | list_move(&clp->cl_strhash, &conf_str_hashtbl[strhashval]); | 1402 | add_clp_to_name_tree(clp, &conf_name_tree); |
1403 | set_bit(NFSD4_CLIENT_CONFIRMED, &clp->cl_flags); | ||
1348 | renew_client(clp); | 1404 | renew_client(clp); |
1349 | } | 1405 | } |
1350 | 1406 | ||
@@ -1387,27 +1443,15 @@ static bool clp_used_exchangeid(struct nfs4_client *clp) | |||
1387 | } | 1443 | } |
1388 | 1444 | ||
1389 | static struct nfs4_client * | 1445 | static struct nfs4_client * |
1390 | find_confirmed_client_by_str(const char *dname, unsigned int hashval) | 1446 | find_confirmed_client_by_name(struct xdr_netobj *name) |
1391 | { | 1447 | { |
1392 | struct nfs4_client *clp; | 1448 | return find_clp_in_name_tree(name, &conf_name_tree); |
1393 | |||
1394 | list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { | ||
1395 | if (same_name(clp->cl_recdir, dname)) | ||
1396 | return clp; | ||
1397 | } | ||
1398 | return NULL; | ||
1399 | } | 1449 | } |
1400 | 1450 | ||
1401 | static struct nfs4_client * | 1451 | static struct nfs4_client * |
1402 | find_unconfirmed_client_by_str(const char *dname, unsigned int hashval) | 1452 | find_unconfirmed_client_by_name(struct xdr_netobj *name) |
1403 | { | 1453 | { |
1404 | struct nfs4_client *clp; | 1454 | return find_clp_in_name_tree(name, &unconf_name_tree); |
1405 | |||
1406 | list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { | ||
1407 | if (same_name(clp->cl_recdir, dname)) | ||
1408 | return clp; | ||
1409 | } | ||
1410 | return NULL; | ||
1411 | } | 1455 | } |
1412 | 1456 | ||
1413 | static void | 1457 | static void |
@@ -1572,7 +1616,6 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
1572 | { | 1616 | { |
1573 | struct nfs4_client *unconf, *conf, *new; | 1617 | struct nfs4_client *unconf, *conf, *new; |
1574 | __be32 status; | 1618 | __be32 status; |
1575 | unsigned int strhashval; | ||
1576 | char dname[HEXDIR_LEN]; | 1619 | char dname[HEXDIR_LEN]; |
1577 | char addr_str[INET6_ADDRSTRLEN]; | 1620 | char addr_str[INET6_ADDRSTRLEN]; |
1578 | nfs4_verifier verf = exid->verifier; | 1621 | nfs4_verifier verf = exid->verifier; |
@@ -1605,11 +1648,9 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
1605 | if (status) | 1648 | if (status) |
1606 | return status; | 1649 | return status; |
1607 | 1650 | ||
1608 | strhashval = clientstr_hashval(dname); | ||
1609 | |||
1610 | /* Cases below refer to rfc 5661 section 18.35.4: */ | 1651 | /* Cases below refer to rfc 5661 section 18.35.4: */ |
1611 | nfs4_lock_state(); | 1652 | nfs4_lock_state(); |
1612 | conf = find_confirmed_client_by_str(dname, strhashval); | 1653 | conf = find_confirmed_client_by_name(&exid->clname); |
1613 | if (conf) { | 1654 | if (conf) { |
1614 | bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred); | 1655 | bool creds_match = same_creds(&conf->cl_cred, &rqstp->rq_cred); |
1615 | bool verfs_match = same_verf(&verf, &conf->cl_verifier); | 1656 | bool verfs_match = same_verf(&verf, &conf->cl_verifier); |
@@ -1654,7 +1695,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
1654 | goto out; | 1695 | goto out; |
1655 | } | 1696 | } |
1656 | 1697 | ||
1657 | unconf = find_unconfirmed_client_by_str(dname, strhashval); | 1698 | unconf = find_unconfirmed_client_by_name(&exid->clname); |
1658 | if (unconf) /* case 4, possible retry or client restart */ | 1699 | if (unconf) /* case 4, possible retry or client restart */ |
1659 | expire_client(unconf); | 1700 | expire_client(unconf); |
1660 | 1701 | ||
@@ -1668,7 +1709,7 @@ out_new: | |||
1668 | new->cl_minorversion = 1; | 1709 | new->cl_minorversion = 1; |
1669 | 1710 | ||
1670 | gen_clid(new); | 1711 | gen_clid(new); |
1671 | add_to_unconfirmed(new, strhashval); | 1712 | add_to_unconfirmed(new); |
1672 | out_copy: | 1713 | out_copy: |
1673 | exid->clientid.cl_boot = new->cl_clientid.cl_boot; | 1714 | exid->clientid.cl_boot = new->cl_clientid.cl_boot; |
1674 | exid->clientid.cl_id = new->cl_clientid.cl_id; | 1715 | exid->clientid.cl_id = new->cl_clientid.cl_id; |
@@ -1789,7 +1830,6 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
1789 | goto out_free_conn; | 1830 | goto out_free_conn; |
1790 | } | 1831 | } |
1791 | } else if (unconf) { | 1832 | } else if (unconf) { |
1792 | unsigned int hash; | ||
1793 | struct nfs4_client *old; | 1833 | struct nfs4_client *old; |
1794 | if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) || | 1834 | if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred) || |
1795 | !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) { | 1835 | !rpc_cmp_addr(sa, (struct sockaddr *) &unconf->cl_addr)) { |
@@ -1803,8 +1843,7 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
1803 | status = nfserr_seq_misordered; | 1843 | status = nfserr_seq_misordered; |
1804 | goto out_free_conn; | 1844 | goto out_free_conn; |
1805 | } | 1845 | } |
1806 | hash = clientstr_hashval(unconf->cl_recdir); | 1846 | old = find_confirmed_client_by_name(&unconf->cl_name); |
1807 | old = find_confirmed_client_by_str(unconf->cl_recdir, hash); | ||
1808 | if (old) | 1847 | if (old) |
1809 | expire_client(old); | 1848 | expire_client(old); |
1810 | move_to_confirmed(unconf); | 1849 | move_to_confirmed(unconf); |
@@ -2195,7 +2234,6 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2195 | { | 2234 | { |
2196 | struct xdr_netobj clname = setclid->se_name; | 2235 | struct xdr_netobj clname = setclid->se_name; |
2197 | nfs4_verifier clverifier = setclid->se_verf; | 2236 | nfs4_verifier clverifier = setclid->se_verf; |
2198 | unsigned int strhashval; | ||
2199 | struct nfs4_client *conf, *unconf, *new; | 2237 | struct nfs4_client *conf, *unconf, *new; |
2200 | __be32 status; | 2238 | __be32 status; |
2201 | char dname[HEXDIR_LEN]; | 2239 | char dname[HEXDIR_LEN]; |
@@ -2204,11 +2242,9 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2204 | if (status) | 2242 | if (status) |
2205 | return status; | 2243 | return status; |
2206 | 2244 | ||
2207 | strhashval = clientstr_hashval(dname); | ||
2208 | |||
2209 | /* Cases below refer to rfc 3530 section 14.2.33: */ | 2245 | /* Cases below refer to rfc 3530 section 14.2.33: */ |
2210 | nfs4_lock_state(); | 2246 | nfs4_lock_state(); |
2211 | conf = find_confirmed_client_by_str(dname, strhashval); | 2247 | conf = find_confirmed_client_by_name(&clname); |
2212 | if (conf) { | 2248 | if (conf) { |
2213 | /* case 0: */ | 2249 | /* case 0: */ |
2214 | status = nfserr_clid_inuse; | 2250 | status = nfserr_clid_inuse; |
@@ -2223,7 +2259,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2223 | goto out; | 2259 | goto out; |
2224 | } | 2260 | } |
2225 | } | 2261 | } |
2226 | unconf = find_unconfirmed_client_by_str(dname, strhashval); | 2262 | unconf = find_unconfirmed_client_by_name(&clname); |
2227 | if (unconf) | 2263 | if (unconf) |
2228 | expire_client(unconf); | 2264 | expire_client(unconf); |
2229 | status = nfserr_jukebox; | 2265 | status = nfserr_jukebox; |
@@ -2237,7 +2273,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
2237 | gen_clid(new); | 2273 | gen_clid(new); |
2238 | new->cl_minorversion = 0; | 2274 | new->cl_minorversion = 0; |
2239 | gen_callback(new, setclid, rqstp); | 2275 | gen_callback(new, setclid, rqstp); |
2240 | add_to_unconfirmed(new, strhashval); | 2276 | add_to_unconfirmed(new); |
2241 | setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; | 2277 | setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot; |
2242 | setclid->se_clientid.cl_id = new->cl_clientid.cl_id; | 2278 | setclid->se_clientid.cl_id = new->cl_clientid.cl_id; |
2243 | memcpy(setclid->se_confirm.data, new->cl_confirm.data, sizeof(setclid->se_confirm.data)); | 2279 | 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, | |||
2290 | nfsd4_probe_callback(conf); | 2326 | nfsd4_probe_callback(conf); |
2291 | expire_client(unconf); | 2327 | expire_client(unconf); |
2292 | } else { /* case 3: normal case; new or rebooted client */ | 2328 | } else { /* case 3: normal case; new or rebooted client */ |
2293 | unsigned int hash = clientstr_hashval(unconf->cl_recdir); | 2329 | conf = find_confirmed_client_by_name(&unconf->cl_name); |
2294 | |||
2295 | conf = find_confirmed_client_by_str(unconf->cl_recdir, hash); | ||
2296 | if (conf) | 2330 | if (conf) |
2297 | expire_client(conf); | 2331 | expire_client(conf); |
2298 | move_to_confirmed(unconf); | 2332 | move_to_confirmed(unconf); |
@@ -4706,11 +4740,11 @@ nfs4_state_init(void) | |||
4706 | 4740 | ||
4707 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { | 4741 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { |
4708 | INIT_LIST_HEAD(&conf_id_hashtbl[i]); | 4742 | INIT_LIST_HEAD(&conf_id_hashtbl[i]); |
4709 | INIT_LIST_HEAD(&conf_str_hashtbl[i]); | ||
4710 | INIT_LIST_HEAD(&unconf_str_hashtbl[i]); | ||
4711 | INIT_LIST_HEAD(&unconf_id_hashtbl[i]); | 4743 | INIT_LIST_HEAD(&unconf_id_hashtbl[i]); |
4712 | INIT_LIST_HEAD(&reclaim_str_hashtbl[i]); | 4744 | INIT_LIST_HEAD(&reclaim_str_hashtbl[i]); |
4713 | } | 4745 | } |
4746 | conf_name_tree = RB_ROOT; | ||
4747 | unconf_name_tree = RB_ROOT; | ||
4714 | for (i = 0; i < SESSION_HASH_SIZE; i++) | 4748 | for (i = 0; i < SESSION_HASH_SIZE; i++) |
4715 | INIT_LIST_HEAD(&sessionid_hashtbl[i]); | 4749 | INIT_LIST_HEAD(&sessionid_hashtbl[i]); |
4716 | for (i = 0; i < FILE_HASH_SIZE; i++) { | 4750 | for (i = 0; i < FILE_HASH_SIZE; i++) { |
@@ -4795,6 +4829,7 @@ out_recovery: | |||
4795 | return ret; | 4829 | return ret; |
4796 | } | 4830 | } |
4797 | 4831 | ||
4832 | /* should be called with the state lock held */ | ||
4798 | static void | 4833 | static void |
4799 | __nfs4_state_shutdown(void) | 4834 | __nfs4_state_shutdown(void) |
4800 | { | 4835 | { |
@@ -4802,17 +4837,24 @@ __nfs4_state_shutdown(void) | |||
4802 | struct nfs4_client *clp = NULL; | 4837 | struct nfs4_client *clp = NULL; |
4803 | struct nfs4_delegation *dp = NULL; | 4838 | struct nfs4_delegation *dp = NULL; |
4804 | struct list_head *pos, *next, reaplist; | 4839 | struct list_head *pos, *next, reaplist; |
4840 | struct rb_node *node, *tmp; | ||
4805 | 4841 | ||
4806 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { | 4842 | for (i = 0; i < CLIENT_HASH_SIZE; i++) { |
4807 | while (!list_empty(&conf_id_hashtbl[i])) { | 4843 | while (!list_empty(&conf_id_hashtbl[i])) { |
4808 | clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); | 4844 | clp = list_entry(conf_id_hashtbl[i].next, struct nfs4_client, cl_idhash); |
4809 | destroy_client(clp); | 4845 | destroy_client(clp); |
4810 | } | 4846 | } |
4811 | while (!list_empty(&unconf_str_hashtbl[i])) { | ||
4812 | clp = list_entry(unconf_str_hashtbl[i].next, struct nfs4_client, cl_strhash); | ||
4813 | destroy_client(clp); | ||
4814 | } | ||
4815 | } | 4847 | } |
4848 | |||
4849 | node = rb_first(&unconf_name_tree); | ||
4850 | while (node != NULL) { | ||
4851 | tmp = node; | ||
4852 | node = rb_next(tmp); | ||
4853 | clp = rb_entry(tmp, struct nfs4_client, cl_namenode); | ||
4854 | rb_erase(tmp, &unconf_name_tree); | ||
4855 | destroy_client(clp); | ||
4856 | } | ||
4857 | |||
4816 | INIT_LIST_HEAD(&reaplist); | 4858 | INIT_LIST_HEAD(&reaplist); |
4817 | spin_lock(&recall_lock); | 4859 | spin_lock(&recall_lock); |
4818 | list_for_each_safe(pos, next, &del_recall_lru) { | 4860 | list_for_each_safe(pos, next, &del_recall_lru) { |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index cf9f7ba4df8..6c342bd806e 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -232,7 +232,7 @@ struct nfsd4_sessionid { | |||
232 | */ | 232 | */ |
233 | struct nfs4_client { | 233 | struct nfs4_client { |
234 | struct list_head cl_idhash; /* hash by cl_clientid.id */ | 234 | struct list_head cl_idhash; /* hash by cl_clientid.id */ |
235 | struct list_head cl_strhash; /* hash by cl_name */ | 235 | struct rb_node cl_namenode; /* link into by-name trees */ |
236 | struct list_head cl_openowners; | 236 | struct list_head cl_openowners; |
237 | struct idr cl_stateids; /* stateid lookup */ | 237 | struct idr cl_stateids; /* stateid lookup */ |
238 | struct list_head cl_delegations; | 238 | struct list_head cl_delegations; |
@@ -253,6 +253,7 @@ struct nfs4_client { | |||
253 | #define NFSD4_CLIENT_CB_KILL (1) | 253 | #define NFSD4_CLIENT_CB_KILL (1) |
254 | #define NFSD4_CLIENT_STABLE (2) /* client on stable storage */ | 254 | #define NFSD4_CLIENT_STABLE (2) /* client on stable storage */ |
255 | #define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */ | 255 | #define NFSD4_CLIENT_RECLAIM_COMPLETE (3) /* reclaim_complete done */ |
256 | #define NFSD4_CLIENT_CONFIRMED (4) /* client is confirmed */ | ||
256 | #define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ | 257 | #define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ |
257 | 1 << NFSD4_CLIENT_CB_KILL) | 258 | 1 << NFSD4_CLIENT_CB_KILL) |
258 | unsigned long cl_flags; | 259 | unsigned long cl_flags; |