aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c424
1 files changed, 311 insertions, 113 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 3e2f19b04c06..e97dd219f84f 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -40,12 +40,13 @@
40 40
41#include <linux/kernel.h> 41#include <linux/kernel.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/smp_lock.h> 43#include <linux/fs.h>
44#include <linux/nfs_fs.h> 44#include <linux/nfs_fs.h>
45#include <linux/nfs_idmap.h> 45#include <linux/nfs_idmap.h>
46#include <linux/kthread.h> 46#include <linux/kthread.h>
47#include <linux/module.h> 47#include <linux/module.h>
48#include <linux/random.h> 48#include <linux/random.h>
49#include <linux/ratelimit.h>
49#include <linux/workqueue.h> 50#include <linux/workqueue.h>
50#include <linux/bitops.h> 51#include <linux/bitops.h>
51 52
@@ -53,6 +54,7 @@
53#include "callback.h" 54#include "callback.h"
54#include "delegation.h" 55#include "delegation.h"
55#include "internal.h" 56#include "internal.h"
57#include "pnfs.h"
56 58
57#define OPENOWNER_POOL_SIZE 8 59#define OPENOWNER_POOL_SIZE 8
58 60
@@ -62,10 +64,15 @@ static LIST_HEAD(nfs4_clientid_list);
62 64
63int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 65int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
64{ 66{
65 struct nfs4_setclientid_res clid; 67 struct nfs4_setclientid_res clid = {
68 .clientid = clp->cl_clientid,
69 .confirm = clp->cl_confirm,
70 };
66 unsigned short port; 71 unsigned short port;
67 int status; 72 int status;
68 73
74 if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
75 goto do_confirm;
69 port = nfs_callback_tcpport; 76 port = nfs_callback_tcpport;
70 if (clp->cl_addr.ss_family == AF_INET6) 77 if (clp->cl_addr.ss_family == AF_INET6)
71 port = nfs_callback_tcpport6; 78 port = nfs_callback_tcpport6;
@@ -73,10 +80,14 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
73 status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid); 80 status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
74 if (status != 0) 81 if (status != 0)
75 goto out; 82 goto out;
83 clp->cl_clientid = clid.clientid;
84 clp->cl_confirm = clid.confirm;
85 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
86do_confirm:
76 status = nfs4_proc_setclientid_confirm(clp, &clid, cred); 87 status = nfs4_proc_setclientid_confirm(clp, &clid, cred);
77 if (status != 0) 88 if (status != 0)
78 goto out; 89 goto out;
79 clp->cl_clientid = clid.clientid; 90 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
80 nfs4_schedule_state_renewal(clp); 91 nfs4_schedule_state_renewal(clp);
81out: 92out:
82 return status; 93 return status;
@@ -103,14 +114,17 @@ static void nfs4_clear_machine_cred(struct nfs_client *clp)
103 put_rpccred(cred); 114 put_rpccred(cred);
104} 115}
105 116
106struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp) 117static struct rpc_cred *
118nfs4_get_renew_cred_server_locked(struct nfs_server *server)
107{ 119{
120 struct rpc_cred *cred = NULL;
108 struct nfs4_state_owner *sp; 121 struct nfs4_state_owner *sp;
109 struct rb_node *pos; 122 struct rb_node *pos;
110 struct rpc_cred *cred = NULL;
111 123
112 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 124 for (pos = rb_first(&server->state_owners);
113 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 125 pos != NULL;
126 pos = rb_next(pos)) {
127 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
114 if (list_empty(&sp->so_states)) 128 if (list_empty(&sp->so_states))
115 continue; 129 continue;
116 cred = get_rpccred(sp->so_cred); 130 cred = get_rpccred(sp->so_cred);
@@ -119,6 +133,28 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
119 return cred; 133 return cred;
120} 134}
121 135
136/**
137 * nfs4_get_renew_cred_locked - Acquire credential for a renew operation
138 * @clp: client state handle
139 *
140 * Returns an rpc_cred with reference count bumped, or NULL.
141 * Caller must hold clp->cl_lock.
142 */
143struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
144{
145 struct rpc_cred *cred = NULL;
146 struct nfs_server *server;
147
148 rcu_read_lock();
149 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
150 cred = nfs4_get_renew_cred_server_locked(server);
151 if (cred != NULL)
152 break;
153 }
154 rcu_read_unlock();
155 return cred;
156}
157
122#if defined(CONFIG_NFS_V4_1) 158#if defined(CONFIG_NFS_V4_1)
123 159
124static int nfs41_setup_state_renewal(struct nfs_client *clp) 160static int nfs41_setup_state_renewal(struct nfs_client *clp)
@@ -126,6 +162,11 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
126 int status; 162 int status;
127 struct nfs_fsinfo fsinfo; 163 struct nfs_fsinfo fsinfo;
128 164
165 if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) {
166 nfs4_schedule_state_renewal(clp);
167 return 0;
168 }
169
129 status = nfs4_proc_get_lease_time(clp, &fsinfo); 170 status = nfs4_proc_get_lease_time(clp, &fsinfo);
130 if (status == 0) { 171 if (status == 0) {
131 /* Update lease time and schedule renewal */ 172 /* Update lease time and schedule renewal */
@@ -140,6 +181,11 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
140 return status; 181 return status;
141} 182}
142 183
184/*
185 * Back channel returns NFS4ERR_DELAY for new requests when
186 * NFS4_SESSION_DRAINING is set so there is no work to be done when draining
187 * is ended.
188 */
143static void nfs4_end_drain_session(struct nfs_client *clp) 189static void nfs4_end_drain_session(struct nfs_client *clp)
144{ 190{
145 struct nfs4_session *ses = clp->cl_session; 191 struct nfs4_session *ses = clp->cl_session;
@@ -163,33 +209,48 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
163 } 209 }
164} 210}
165 211
166static int nfs4_begin_drain_session(struct nfs_client *clp) 212static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
167{ 213{
168 struct nfs4_session *ses = clp->cl_session;
169 struct nfs4_slot_table *tbl = &ses->fc_slot_table;
170
171 spin_lock(&tbl->slot_tbl_lock); 214 spin_lock(&tbl->slot_tbl_lock);
172 set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
173 if (tbl->highest_used_slotid != -1) { 215 if (tbl->highest_used_slotid != -1) {
174 INIT_COMPLETION(ses->complete); 216 INIT_COMPLETION(tbl->complete);
175 spin_unlock(&tbl->slot_tbl_lock); 217 spin_unlock(&tbl->slot_tbl_lock);
176 return wait_for_completion_interruptible(&ses->complete); 218 return wait_for_completion_interruptible(&tbl->complete);
177 } 219 }
178 spin_unlock(&tbl->slot_tbl_lock); 220 spin_unlock(&tbl->slot_tbl_lock);
179 return 0; 221 return 0;
180} 222}
181 223
224static int nfs4_begin_drain_session(struct nfs_client *clp)
225{
226 struct nfs4_session *ses = clp->cl_session;
227 int ret = 0;
228
229 set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
230 /* back channel */
231 ret = nfs4_wait_on_slot_tbl(&ses->bc_slot_table);
232 if (ret)
233 return ret;
234 /* fore channel */
235 return nfs4_wait_on_slot_tbl(&ses->fc_slot_table);
236}
237
182int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 238int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
183{ 239{
184 int status; 240 int status;
185 241
242 if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
243 goto do_confirm;
186 nfs4_begin_drain_session(clp); 244 nfs4_begin_drain_session(clp);
187 status = nfs4_proc_exchange_id(clp, cred); 245 status = nfs4_proc_exchange_id(clp, cred);
188 if (status != 0) 246 if (status != 0)
189 goto out; 247 goto out;
248 set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
249do_confirm:
190 status = nfs4_proc_create_session(clp); 250 status = nfs4_proc_create_session(clp);
191 if (status != 0) 251 if (status != 0)
192 goto out; 252 goto out;
253 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
193 nfs41_setup_state_renewal(clp); 254 nfs41_setup_state_renewal(clp);
194 nfs_mark_client_ready(clp, NFS_CS_READY); 255 nfs_mark_client_ready(clp, NFS_CS_READY);
195out: 256out:
@@ -208,28 +269,56 @@ struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
208 269
209#endif /* CONFIG_NFS_V4_1 */ 270#endif /* CONFIG_NFS_V4_1 */
210 271
211struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) 272static struct rpc_cred *
273nfs4_get_setclientid_cred_server(struct nfs_server *server)
212{ 274{
275 struct nfs_client *clp = server->nfs_client;
276 struct rpc_cred *cred = NULL;
213 struct nfs4_state_owner *sp; 277 struct nfs4_state_owner *sp;
214 struct rb_node *pos; 278 struct rb_node *pos;
279
280 spin_lock(&clp->cl_lock);
281 pos = rb_first(&server->state_owners);
282 if (pos != NULL) {
283 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
284 cred = get_rpccred(sp->so_cred);
285 }
286 spin_unlock(&clp->cl_lock);
287 return cred;
288}
289
290/**
291 * nfs4_get_setclientid_cred - Acquire credential for a setclientid operation
292 * @clp: client state handle
293 *
294 * Returns an rpc_cred with reference count bumped, or NULL.
295 */
296struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
297{
298 struct nfs_server *server;
215 struct rpc_cred *cred; 299 struct rpc_cred *cred;
216 300
217 spin_lock(&clp->cl_lock); 301 spin_lock(&clp->cl_lock);
218 cred = nfs4_get_machine_cred_locked(clp); 302 cred = nfs4_get_machine_cred_locked(clp);
303 spin_unlock(&clp->cl_lock);
219 if (cred != NULL) 304 if (cred != NULL)
220 goto out; 305 goto out;
221 pos = rb_first(&clp->cl_state_owners); 306
222 if (pos != NULL) { 307 rcu_read_lock();
223 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 308 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
224 cred = get_rpccred(sp->so_cred); 309 cred = nfs4_get_setclientid_cred_server(server);
310 if (cred != NULL)
311 break;
225 } 312 }
313 rcu_read_unlock();
314
226out: 315out:
227 spin_unlock(&clp->cl_lock);
228 return cred; 316 return cred;
229} 317}
230 318
231static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new, 319static void nfs_alloc_unique_id_locked(struct rb_root *root,
232 __u64 minval, int maxbits) 320 struct nfs_unique_id *new,
321 __u64 minval, int maxbits)
233{ 322{
234 struct rb_node **p, *parent; 323 struct rb_node **p, *parent;
235 struct nfs_unique_id *pos; 324 struct nfs_unique_id *pos;
@@ -284,16 +373,15 @@ static void nfs_free_unique_id(struct rb_root *root, struct nfs_unique_id *id)
284} 373}
285 374
286static struct nfs4_state_owner * 375static struct nfs4_state_owner *
287nfs4_find_state_owner(struct nfs_server *server, struct rpc_cred *cred) 376nfs4_find_state_owner_locked(struct nfs_server *server, struct rpc_cred *cred)
288{ 377{
289 struct nfs_client *clp = server->nfs_client; 378 struct rb_node **p = &server->state_owners.rb_node,
290 struct rb_node **p = &clp->cl_state_owners.rb_node,
291 *parent = NULL; 379 *parent = NULL;
292 struct nfs4_state_owner *sp, *res = NULL; 380 struct nfs4_state_owner *sp, *res = NULL;
293 381
294 while (*p != NULL) { 382 while (*p != NULL) {
295 parent = *p; 383 parent = *p;
296 sp = rb_entry(parent, struct nfs4_state_owner, so_client_node); 384 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
297 385
298 if (server < sp->so_server) { 386 if (server < sp->so_server) {
299 p = &parent->rb_left; 387 p = &parent->rb_left;
@@ -317,24 +405,17 @@ nfs4_find_state_owner(struct nfs_server *server, struct rpc_cred *cred)
317} 405}
318 406
319static struct nfs4_state_owner * 407static struct nfs4_state_owner *
320nfs4_insert_state_owner(struct nfs_client *clp, struct nfs4_state_owner *new) 408nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
321{ 409{
322 struct rb_node **p = &clp->cl_state_owners.rb_node, 410 struct nfs_server *server = new->so_server;
411 struct rb_node **p = &server->state_owners.rb_node,
323 *parent = NULL; 412 *parent = NULL;
324 struct nfs4_state_owner *sp; 413 struct nfs4_state_owner *sp;
325 414
326 while (*p != NULL) { 415 while (*p != NULL) {
327 parent = *p; 416 parent = *p;
328 sp = rb_entry(parent, struct nfs4_state_owner, so_client_node); 417 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
329 418
330 if (new->so_server < sp->so_server) {
331 p = &parent->rb_left;
332 continue;
333 }
334 if (new->so_server > sp->so_server) {
335 p = &parent->rb_right;
336 continue;
337 }
338 if (new->so_cred < sp->so_cred) 419 if (new->so_cred < sp->so_cred)
339 p = &parent->rb_left; 420 p = &parent->rb_left;
340 else if (new->so_cred > sp->so_cred) 421 else if (new->so_cred > sp->so_cred)
@@ -344,18 +425,21 @@ nfs4_insert_state_owner(struct nfs_client *clp, struct nfs4_state_owner *new)
344 return sp; 425 return sp;
345 } 426 }
346 } 427 }
347 nfs_alloc_unique_id(&clp->cl_openowner_id, &new->so_owner_id, 1, 64); 428 nfs_alloc_unique_id_locked(&server->openowner_id,
348 rb_link_node(&new->so_client_node, parent, p); 429 &new->so_owner_id, 1, 64);
349 rb_insert_color(&new->so_client_node, &clp->cl_state_owners); 430 rb_link_node(&new->so_server_node, parent, p);
431 rb_insert_color(&new->so_server_node, &server->state_owners);
350 return new; 432 return new;
351} 433}
352 434
353static void 435static void
354nfs4_remove_state_owner(struct nfs_client *clp, struct nfs4_state_owner *sp) 436nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)
355{ 437{
356 if (!RB_EMPTY_NODE(&sp->so_client_node)) 438 struct nfs_server *server = sp->so_server;
357 rb_erase(&sp->so_client_node, &clp->cl_state_owners); 439
358 nfs_free_unique_id(&clp->cl_openowner_id, &sp->so_owner_id); 440 if (!RB_EMPTY_NODE(&sp->so_server_node))
441 rb_erase(&sp->so_server_node, &server->state_owners);
442 nfs_free_unique_id(&server->openowner_id, &sp->so_owner_id);
359} 443}
360 444
361/* 445/*
@@ -384,23 +468,32 @@ nfs4_alloc_state_owner(void)
384static void 468static void
385nfs4_drop_state_owner(struct nfs4_state_owner *sp) 469nfs4_drop_state_owner(struct nfs4_state_owner *sp)
386{ 470{
387 if (!RB_EMPTY_NODE(&sp->so_client_node)) { 471 if (!RB_EMPTY_NODE(&sp->so_server_node)) {
388 struct nfs_client *clp = sp->so_server->nfs_client; 472 struct nfs_server *server = sp->so_server;
473 struct nfs_client *clp = server->nfs_client;
389 474
390 spin_lock(&clp->cl_lock); 475 spin_lock(&clp->cl_lock);
391 rb_erase(&sp->so_client_node, &clp->cl_state_owners); 476 rb_erase(&sp->so_server_node, &server->state_owners);
392 RB_CLEAR_NODE(&sp->so_client_node); 477 RB_CLEAR_NODE(&sp->so_server_node);
393 spin_unlock(&clp->cl_lock); 478 spin_unlock(&clp->cl_lock);
394 } 479 }
395} 480}
396 481
397struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) 482/**
483 * nfs4_get_state_owner - Look up a state owner given a credential
484 * @server: nfs_server to search
485 * @cred: RPC credential to match
486 *
487 * Returns a pointer to an instantiated nfs4_state_owner struct, or NULL.
488 */
489struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
490 struct rpc_cred *cred)
398{ 491{
399 struct nfs_client *clp = server->nfs_client; 492 struct nfs_client *clp = server->nfs_client;
400 struct nfs4_state_owner *sp, *new; 493 struct nfs4_state_owner *sp, *new;
401 494
402 spin_lock(&clp->cl_lock); 495 spin_lock(&clp->cl_lock);
403 sp = nfs4_find_state_owner(server, cred); 496 sp = nfs4_find_state_owner_locked(server, cred);
404 spin_unlock(&clp->cl_lock); 497 spin_unlock(&clp->cl_lock);
405 if (sp != NULL) 498 if (sp != NULL)
406 return sp; 499 return sp;
@@ -410,7 +503,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
410 new->so_server = server; 503 new->so_server = server;
411 new->so_cred = cred; 504 new->so_cred = cred;
412 spin_lock(&clp->cl_lock); 505 spin_lock(&clp->cl_lock);
413 sp = nfs4_insert_state_owner(clp, new); 506 sp = nfs4_insert_state_owner_locked(new);
414 spin_unlock(&clp->cl_lock); 507 spin_unlock(&clp->cl_lock);
415 if (sp == new) 508 if (sp == new)
416 get_rpccred(cred); 509 get_rpccred(cred);
@@ -421,6 +514,11 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
421 return sp; 514 return sp;
422} 515}
423 516
517/**
518 * nfs4_put_state_owner - Release a nfs4_state_owner
519 * @sp: state owner data to release
520 *
521 */
424void nfs4_put_state_owner(struct nfs4_state_owner *sp) 522void nfs4_put_state_owner(struct nfs4_state_owner *sp)
425{ 523{
426 struct nfs_client *clp = sp->so_server->nfs_client; 524 struct nfs_client *clp = sp->so_server->nfs_client;
@@ -428,7 +526,7 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp)
428 526
429 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) 527 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
430 return; 528 return;
431 nfs4_remove_state_owner(clp, sp); 529 nfs4_remove_state_owner_locked(sp);
432 spin_unlock(&clp->cl_lock); 530 spin_unlock(&clp->cl_lock);
433 rpc_destroy_wait_queue(&sp->so_sequence.wait); 531 rpc_destroy_wait_queue(&sp->so_sequence.wait);
434 put_rpccred(cred); 532 put_rpccred(cred);
@@ -506,7 +604,8 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
506 state->owner = owner; 604 state->owner = owner;
507 atomic_inc(&owner->so_count); 605 atomic_inc(&owner->so_count);
508 list_add(&state->inode_states, &nfsi->open_states); 606 list_add(&state->inode_states, &nfsi->open_states);
509 state->inode = igrab(inode); 607 ihold(inode);
608 state->inode = inode;
510 spin_unlock(&inode->i_lock); 609 spin_unlock(&inode->i_lock);
511 /* Note: The reclaim code dictates that we add stateless 610 /* Note: The reclaim code dictates that we add stateless
512 * and read-only stateids to the end of the list */ 611 * and read-only stateids to the end of the list */
@@ -583,8 +682,11 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state,
583 if (!call_close) { 682 if (!call_close) {
584 nfs4_put_open_state(state); 683 nfs4_put_open_state(state);
585 nfs4_put_state_owner(owner); 684 nfs4_put_state_owner(owner);
586 } else 685 } else {
587 nfs4_do_close(path, state, gfp_mask, wait); 686 bool roc = pnfs_roc(state->inode);
687
688 nfs4_do_close(path, state, gfp_mask, wait, roc);
689 }
588} 690}
589 691
590void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode) 692void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode)
@@ -631,7 +733,8 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_p
631static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type) 733static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
632{ 734{
633 struct nfs4_lock_state *lsp; 735 struct nfs4_lock_state *lsp;
634 struct nfs_client *clp = state->owner->so_server->nfs_client; 736 struct nfs_server *server = state->owner->so_server;
737 struct nfs_client *clp = server->nfs_client;
635 738
636 lsp = kzalloc(sizeof(*lsp), GFP_NOFS); 739 lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
637 if (lsp == NULL) 740 if (lsp == NULL)
@@ -655,7 +758,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
655 return NULL; 758 return NULL;
656 } 759 }
657 spin_lock(&clp->cl_lock); 760 spin_lock(&clp->cl_lock);
658 nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64); 761 nfs_alloc_unique_id_locked(&server->lockowner_id, &lsp->ls_id, 1, 64);
659 spin_unlock(&clp->cl_lock); 762 spin_unlock(&clp->cl_lock);
660 INIT_LIST_HEAD(&lsp->ls_locks); 763 INIT_LIST_HEAD(&lsp->ls_locks);
661 return lsp; 764 return lsp;
@@ -663,10 +766,11 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
663 766
664static void nfs4_free_lock_state(struct nfs4_lock_state *lsp) 767static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
665{ 768{
666 struct nfs_client *clp = lsp->ls_state->owner->so_server->nfs_client; 769 struct nfs_server *server = lsp->ls_state->owner->so_server;
770 struct nfs_client *clp = server->nfs_client;
667 771
668 spin_lock(&clp->cl_lock); 772 spin_lock(&clp->cl_lock);
669 nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id); 773 nfs_free_unique_id(&server->lockowner_id, &lsp->ls_id);
670 spin_unlock(&clp->cl_lock); 774 spin_unlock(&clp->cl_lock);
671 rpc_destroy_wait_queue(&lsp->ls_sequence.wait); 775 rpc_destroy_wait_queue(&lsp->ls_sequence.wait);
672 kfree(lsp); 776 kfree(lsp);
@@ -923,9 +1027,9 @@ void nfs4_schedule_state_manager(struct nfs_client *clp)
923} 1027}
924 1028
925/* 1029/*
926 * Schedule a state recovery attempt 1030 * Schedule a lease recovery attempt
927 */ 1031 */
928void nfs4_schedule_state_recovery(struct nfs_client *clp) 1032void nfs4_schedule_lease_recovery(struct nfs_client *clp)
929{ 1033{
930 if (!clp) 1034 if (!clp)
931 return; 1035 return;
@@ -934,7 +1038,7 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp)
934 nfs4_schedule_state_manager(clp); 1038 nfs4_schedule_state_manager(clp);
935} 1039}
936 1040
937int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) 1041static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state)
938{ 1042{
939 1043
940 set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); 1044 set_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
@@ -948,7 +1052,7 @@ int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *st
948 return 1; 1052 return 1;
949} 1053}
950 1054
951int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state) 1055static int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state)
952{ 1056{
953 set_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags); 1057 set_bit(NFS_STATE_RECLAIM_NOGRACE, &state->flags);
954 clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags); 1058 clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags);
@@ -957,6 +1061,14 @@ int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *s
957 return 1; 1061 return 1;
958} 1062}
959 1063
1064void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4_state *state)
1065{
1066 struct nfs_client *clp = server->nfs_client;
1067
1068 nfs4_state_mark_reclaim_nograce(clp, state);
1069 nfs4_schedule_state_manager(clp);
1070}
1071
960static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops) 1072static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_recovery_ops *ops)
961{ 1073{
962 struct inode *inode = state->inode; 1074 struct inode *inode = state->inode;
@@ -970,13 +1082,13 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
970 /* Guard against delegation returns and new lock/unlock calls */ 1082 /* Guard against delegation returns and new lock/unlock calls */
971 down_write(&nfsi->rwsem); 1083 down_write(&nfsi->rwsem);
972 /* Protect inode->i_flock using the BKL */ 1084 /* Protect inode->i_flock using the BKL */
973 lock_kernel(); 1085 lock_flocks();
974 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 1086 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
975 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) 1087 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
976 continue; 1088 continue;
977 if (nfs_file_open_context(fl->fl_file)->state != state) 1089 if (nfs_file_open_context(fl->fl_file)->state != state)
978 continue; 1090 continue;
979 unlock_kernel(); 1091 unlock_flocks();
980 status = ops->recover_lock(state, fl); 1092 status = ops->recover_lock(state, fl);
981 switch (status) { 1093 switch (status) {
982 case 0: 1094 case 0:
@@ -1003,9 +1115,9 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
1003 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 1115 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
1004 status = 0; 1116 status = 0;
1005 } 1117 }
1006 lock_kernel(); 1118 lock_flocks();
1007 } 1119 }
1008 unlock_kernel(); 1120 unlock_flocks();
1009out: 1121out:
1010 up_write(&nfsi->rwsem); 1122 up_write(&nfsi->rwsem);
1011 return status; 1123 return status;
@@ -1063,6 +1175,14 @@ restart:
1063 /* Mark the file as being 'closed' */ 1175 /* Mark the file as being 'closed' */
1064 state->state = 0; 1176 state->state = 0;
1065 break; 1177 break;
1178 case -EKEYEXPIRED:
1179 /*
1180 * User RPCSEC_GSS context has expired.
1181 * We cannot recover this stateid now, so
1182 * skip it and allow recovery thread to
1183 * proceed.
1184 */
1185 break;
1066 case -NFS4ERR_ADMIN_REVOKED: 1186 case -NFS4ERR_ADMIN_REVOKED:
1067 case -NFS4ERR_STALE_STATEID: 1187 case -NFS4ERR_STALE_STATEID:
1068 case -NFS4ERR_BAD_STATEID: 1188 case -NFS4ERR_BAD_STATEID:
@@ -1104,15 +1224,19 @@ static void nfs4_clear_open_state(struct nfs4_state *state)
1104 } 1224 }
1105} 1225}
1106 1226
1107static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp, int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state)) 1227static void nfs4_reset_seqids(struct nfs_server *server,
1228 int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state))
1108{ 1229{
1230 struct nfs_client *clp = server->nfs_client;
1109 struct nfs4_state_owner *sp; 1231 struct nfs4_state_owner *sp;
1110 struct rb_node *pos; 1232 struct rb_node *pos;
1111 struct nfs4_state *state; 1233 struct nfs4_state *state;
1112 1234
1113 /* Reset all sequence ids to zero */ 1235 spin_lock(&clp->cl_lock);
1114 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1236 for (pos = rb_first(&server->state_owners);
1115 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1237 pos != NULL;
1238 pos = rb_next(pos)) {
1239 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
1116 sp->so_seqid.flags = 0; 1240 sp->so_seqid.flags = 0;
1117 spin_lock(&sp->so_lock); 1241 spin_lock(&sp->so_lock);
1118 list_for_each_entry(state, &sp->so_states, open_states) { 1242 list_for_each_entry(state, &sp->so_states, open_states) {
@@ -1121,6 +1245,18 @@ static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp, int (*mark_re
1121 } 1245 }
1122 spin_unlock(&sp->so_lock); 1246 spin_unlock(&sp->so_lock);
1123 } 1247 }
1248 spin_unlock(&clp->cl_lock);
1249}
1250
1251static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp,
1252 int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state))
1253{
1254 struct nfs_server *server;
1255
1256 rcu_read_lock();
1257 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1258 nfs4_reset_seqids(server, mark_reclaim);
1259 rcu_read_unlock();
1124} 1260}
1125 1261
1126static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp) 1262static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
@@ -1138,29 +1274,51 @@ static void nfs4_reclaim_complete(struct nfs_client *clp,
1138 (void)ops->reclaim_complete(clp); 1274 (void)ops->reclaim_complete(clp);
1139} 1275}
1140 1276
1141static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) 1277static void nfs4_clear_reclaim_server(struct nfs_server *server)
1142{ 1278{
1279 struct nfs_client *clp = server->nfs_client;
1143 struct nfs4_state_owner *sp; 1280 struct nfs4_state_owner *sp;
1144 struct rb_node *pos; 1281 struct rb_node *pos;
1145 struct nfs4_state *state; 1282 struct nfs4_state *state;
1146 1283
1147 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) 1284 spin_lock(&clp->cl_lock);
1148 return; 1285 for (pos = rb_first(&server->state_owners);
1149 1286 pos != NULL;
1150 nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops); 1287 pos = rb_next(pos)) {
1151 1288 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
1152 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
1153 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
1154 spin_lock(&sp->so_lock); 1289 spin_lock(&sp->so_lock);
1155 list_for_each_entry(state, &sp->so_states, open_states) { 1290 list_for_each_entry(state, &sp->so_states, open_states) {
1156 if (!test_and_clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags)) 1291 if (!test_and_clear_bit(NFS_STATE_RECLAIM_REBOOT,
1292 &state->flags))
1157 continue; 1293 continue;
1158 nfs4_state_mark_reclaim_nograce(clp, state); 1294 nfs4_state_mark_reclaim_nograce(clp, state);
1159 } 1295 }
1160 spin_unlock(&sp->so_lock); 1296 spin_unlock(&sp->so_lock);
1161 } 1297 }
1298 spin_unlock(&clp->cl_lock);
1299}
1300
1301static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp)
1302{
1303 struct nfs_server *server;
1304
1305 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1306 return 0;
1307
1308 rcu_read_lock();
1309 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1310 nfs4_clear_reclaim_server(server);
1311 rcu_read_unlock();
1162 1312
1163 nfs_delegation_reap_unclaimed(clp); 1313 nfs_delegation_reap_unclaimed(clp);
1314 return 1;
1315}
1316
1317static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
1318{
1319 if (!nfs4_state_clear_reclaim_reboot(clp))
1320 return;
1321 nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops);
1164} 1322}
1165 1323
1166static void nfs_delegation_clear_all(struct nfs_client *clp) 1324static void nfs_delegation_clear_all(struct nfs_client *clp)
@@ -1175,6 +1333,14 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp)
1175 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); 1333 nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce);
1176} 1334}
1177 1335
1336static void nfs4_warn_keyexpired(const char *s)
1337{
1338 printk_ratelimited(KERN_WARNING "Error: state manager"
1339 " encountered RPCSEC_GSS session"
1340 " expired against NFSv4 server %s.\n",
1341 s);
1342}
1343
1178static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) 1344static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1179{ 1345{
1180 switch (error) { 1346 switch (error) {
@@ -1187,7 +1353,7 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1187 case -NFS4ERR_STALE_CLIENTID: 1353 case -NFS4ERR_STALE_CLIENTID:
1188 case -NFS4ERR_LEASE_MOVED: 1354 case -NFS4ERR_LEASE_MOVED:
1189 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1355 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1190 nfs4_state_end_reclaim_reboot(clp); 1356 nfs4_state_clear_reclaim_reboot(clp);
1191 nfs4_state_start_reclaim_reboot(clp); 1357 nfs4_state_start_reclaim_reboot(clp);
1192 break; 1358 break;
1193 case -NFS4ERR_EXPIRED: 1359 case -NFS4ERR_EXPIRED:
@@ -1204,33 +1370,50 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1204 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); 1370 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
1205 /* Zero session reset errors */ 1371 /* Zero session reset errors */
1206 return 0; 1372 return 0;
1373 case -EKEYEXPIRED:
1374 /* Nothing we can do */
1375 nfs4_warn_keyexpired(clp->cl_hostname);
1376 return 0;
1207 } 1377 }
1208 return error; 1378 return error;
1209} 1379}
1210 1380
1211static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) 1381static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops)
1212{ 1382{
1383 struct nfs4_state_owner *sp;
1384 struct nfs_server *server;
1213 struct rb_node *pos; 1385 struct rb_node *pos;
1214 int status = 0; 1386 int status = 0;
1215 1387
1216restart: 1388restart:
1217 spin_lock(&clp->cl_lock); 1389 rcu_read_lock();
1218 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1390 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
1219 struct nfs4_state_owner *sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1391 spin_lock(&clp->cl_lock);
1220 if (!test_and_clear_bit(ops->owner_flag_bit, &sp->so_flags)) 1392 for (pos = rb_first(&server->state_owners);
1221 continue; 1393 pos != NULL;
1222 atomic_inc(&sp->so_count); 1394 pos = rb_next(pos)) {
1223 spin_unlock(&clp->cl_lock); 1395 sp = rb_entry(pos,
1224 status = nfs4_reclaim_open_state(sp, ops); 1396 struct nfs4_state_owner, so_server_node);
1225 if (status < 0) { 1397 if (!test_and_clear_bit(ops->owner_flag_bit,
1226 set_bit(ops->owner_flag_bit, &sp->so_flags); 1398 &sp->so_flags))
1399 continue;
1400 atomic_inc(&sp->so_count);
1401 spin_unlock(&clp->cl_lock);
1402 rcu_read_unlock();
1403
1404 status = nfs4_reclaim_open_state(sp, ops);
1405 if (status < 0) {
1406 set_bit(ops->owner_flag_bit, &sp->so_flags);
1407 nfs4_put_state_owner(sp);
1408 return nfs4_recovery_handle_error(clp, status);
1409 }
1410
1227 nfs4_put_state_owner(sp); 1411 nfs4_put_state_owner(sp);
1228 return nfs4_recovery_handle_error(clp, status); 1412 goto restart;
1229 } 1413 }
1230 nfs4_put_state_owner(sp); 1414 spin_unlock(&clp->cl_lock);
1231 goto restart;
1232 } 1415 }
1233 spin_unlock(&clp->cl_lock); 1416 rcu_read_unlock();
1234 return status; 1417 return status;
1235} 1418}
1236 1419
@@ -1281,10 +1464,19 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
1281} 1464}
1282 1465
1283#ifdef CONFIG_NFS_V4_1 1466#ifdef CONFIG_NFS_V4_1
1467void nfs4_schedule_session_recovery(struct nfs4_session *session)
1468{
1469 struct nfs_client *clp = session->clp;
1470
1471 set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
1472 nfs4_schedule_lease_recovery(clp);
1473}
1474EXPORT_SYMBOL_GPL(nfs4_schedule_session_recovery);
1475
1284void nfs41_handle_recall_slot(struct nfs_client *clp) 1476void nfs41_handle_recall_slot(struct nfs_client *clp)
1285{ 1477{
1286 set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); 1478 set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
1287 nfs4_schedule_state_recovery(clp); 1479 nfs4_schedule_state_manager(clp);
1288} 1480}
1289 1481
1290static void nfs4_reset_all_state(struct nfs_client *clp) 1482static void nfs4_reset_all_state(struct nfs_client *clp)
@@ -1292,7 +1484,7 @@ static void nfs4_reset_all_state(struct nfs_client *clp)
1292 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { 1484 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1293 clp->cl_boot_time = CURRENT_TIME; 1485 clp->cl_boot_time = CURRENT_TIME;
1294 nfs4_state_start_reclaim_nograce(clp); 1486 nfs4_state_start_reclaim_nograce(clp);
1295 nfs4_schedule_state_recovery(clp); 1487 nfs4_schedule_state_manager(clp);
1296 } 1488 }
1297} 1489}
1298 1490
@@ -1300,7 +1492,7 @@ static void nfs41_handle_server_reboot(struct nfs_client *clp)
1300{ 1492{
1301 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) { 1493 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1302 nfs4_state_start_reclaim_reboot(clp); 1494 nfs4_state_start_reclaim_reboot(clp);
1303 nfs4_schedule_state_recovery(clp); 1495 nfs4_schedule_state_manager(clp);
1304 } 1496 }
1305} 1497}
1306 1498
@@ -1320,7 +1512,7 @@ static void nfs41_handle_cb_path_down(struct nfs_client *clp)
1320{ 1512{
1321 nfs_expire_all_delegations(clp); 1513 nfs_expire_all_delegations(clp);
1322 if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0) 1514 if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0)
1323 nfs4_schedule_state_recovery(clp); 1515 nfs4_schedule_state_manager(clp);
1324} 1516}
1325 1517
1326void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) 1518void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
@@ -1360,6 +1552,7 @@ static int nfs4_reset_session(struct nfs_client *clp)
1360 status = nfs4_recovery_handle_error(clp, status); 1552 status = nfs4_recovery_handle_error(clp, status);
1361 goto out; 1553 goto out;
1362 } 1554 }
1555 clear_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state);
1363 /* create_session negotiated new slot table */ 1556 /* create_session negotiated new slot table */
1364 clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); 1557 clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state);
1365 1558
@@ -1409,19 +1602,23 @@ static int nfs4_recall_slot(struct nfs_client *clp) { return 0; }
1409 */ 1602 */
1410static void nfs4_set_lease_expired(struct nfs_client *clp, int status) 1603static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
1411{ 1604{
1412 if (nfs4_has_session(clp)) { 1605 switch (status) {
1413 switch (status) { 1606 case -NFS4ERR_CLID_INUSE:
1414 case -NFS4ERR_DELAY: 1607 case -NFS4ERR_STALE_CLIENTID:
1415 case -NFS4ERR_CLID_INUSE: 1608 clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
1416 case -EAGAIN: 1609 break;
1417 case -EKEYEXPIRED: 1610 case -NFS4ERR_DELAY:
1418 break; 1611 case -ETIMEDOUT:
1612 case -EAGAIN:
1613 ssleep(1);
1614 break;
1419 1615
1420 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery 1616 case -EKEYEXPIRED:
1421 * in nfs4_exchange_id */ 1617 nfs4_warn_keyexpired(clp->cl_hostname);
1422 default: 1618 case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
1423 return; 1619 * in nfs4_exchange_id */
1424 } 1620 default:
1621 return;
1425 } 1622 }
1426 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1623 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1427} 1624}
@@ -1431,7 +1628,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1431 int status = 0; 1628 int status = 0;
1432 1629
1433 /* Ensure exclusive access to NFSv4 state */ 1630 /* Ensure exclusive access to NFSv4 state */
1434 for(;;) { 1631 do {
1435 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { 1632 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
1436 /* We're going to have to re-establish a clientid */ 1633 /* We're going to have to re-establish a clientid */
1437 status = nfs4_reclaim_lease(clp); 1634 status = nfs4_reclaim_lease(clp);
@@ -1447,6 +1644,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1447 } 1644 }
1448 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); 1645 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1449 set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state); 1646 set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
1647 pnfs_destroy_all_layouts(clp);
1450 } 1648 }
1451 1649
1452 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) { 1650 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
@@ -1514,7 +1712,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
1514 break; 1712 break;
1515 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) 1713 if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0)
1516 break; 1714 break;
1517 } 1715 } while (atomic_read(&clp->cl_count) > 1);
1518 return; 1716 return;
1519out_error: 1717out_error:
1520 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" 1718 printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s"