aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-11-12 15:00:56 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-11-12 18:55:11 -0500
commitac55fdc408039b425a2fa3cbcaed7444e5339f9a (patch)
tree6fb1420263d6f06ddb27b9b7943ffed50f7d638d /fs
parent0ce0c2b5d23080eec39ccc52354be1eea326ed5f (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4state.c144
-rw-r--r--fs/nfsd/state.h3
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 */
427static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE]; 429static struct list_head reclaim_str_hashtbl[CLIENT_HASH_SIZE];
428static int reclaim_str_hashtbl_size = 0; 430static int reclaim_str_hashtbl_size = 0;
429static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; 431static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE];
430static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE];
431static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE];
432static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; 432static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE];
433static struct rb_root conf_name_tree;
434static struct rb_root unconf_name_tree;
433static struct list_head client_lru; 435static struct list_head client_lru;
434static struct list_head close_lru; 436static 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
1195static long long
1196compare_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
1190static int same_name(const char *n1, const char *n2) 1206static 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
1327static void 1342static void
1328add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval) 1343add_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
1362static struct nfs4_client *
1363find_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
1382static void
1383add_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
1339move_to_confirmed(struct nfs4_client *clp) 1395move_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
1389static struct nfs4_client * 1445static struct nfs4_client *
1390find_confirmed_client_by_str(const char *dname, unsigned int hashval) 1446find_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
1401static struct nfs4_client * 1451static struct nfs4_client *
1402find_unconfirmed_client_by_str(const char *dname, unsigned int hashval) 1452find_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
1413static void 1457static 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);
1672out_copy: 1713out_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 */
4798static void 4833static 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 */
233struct nfs4_client { 233struct 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;