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.c293
1 files changed, 213 insertions, 80 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index f575a3126737..2336d532cf66 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -105,14 +105,17 @@ static void nfs4_clear_machine_cred(struct nfs_client *clp)
105 put_rpccred(cred); 105 put_rpccred(cred);
106} 106}
107 107
108struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp) 108static struct rpc_cred *
109nfs4_get_renew_cred_server_locked(struct nfs_server *server)
109{ 110{
111 struct rpc_cred *cred = NULL;
110 struct nfs4_state_owner *sp; 112 struct nfs4_state_owner *sp;
111 struct rb_node *pos; 113 struct rb_node *pos;
112 struct rpc_cred *cred = NULL;
113 114
114 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 115 for (pos = rb_first(&server->state_owners);
115 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 116 pos != NULL;
117 pos = rb_next(pos)) {
118 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
116 if (list_empty(&sp->so_states)) 119 if (list_empty(&sp->so_states))
117 continue; 120 continue;
118 cred = get_rpccred(sp->so_cred); 121 cred = get_rpccred(sp->so_cred);
@@ -121,6 +124,28 @@ struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
121 return cred; 124 return cred;
122} 125}
123 126
127/**
128 * nfs4_get_renew_cred_locked - Acquire credential for a renew operation
129 * @clp: client state handle
130 *
131 * Returns an rpc_cred with reference count bumped, or NULL.
132 * Caller must hold clp->cl_lock.
133 */
134struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp)
135{
136 struct rpc_cred *cred = NULL;
137 struct nfs_server *server;
138
139 rcu_read_lock();
140 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
141 cred = nfs4_get_renew_cred_server_locked(server);
142 if (cred != NULL)
143 break;
144 }
145 rcu_read_unlock();
146 return cred;
147}
148
124#if defined(CONFIG_NFS_V4_1) 149#if defined(CONFIG_NFS_V4_1)
125 150
126static int nfs41_setup_state_renewal(struct nfs_client *clp) 151static int nfs41_setup_state_renewal(struct nfs_client *clp)
@@ -142,6 +167,11 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp)
142 return status; 167 return status;
143} 168}
144 169
170/*
171 * Back channel returns NFS4ERR_DELAY for new requests when
172 * NFS4_SESSION_DRAINING is set so there is no work to be done when draining
173 * is ended.
174 */
145static void nfs4_end_drain_session(struct nfs_client *clp) 175static void nfs4_end_drain_session(struct nfs_client *clp)
146{ 176{
147 struct nfs4_session *ses = clp->cl_session; 177 struct nfs4_session *ses = clp->cl_session;
@@ -165,22 +195,32 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
165 } 195 }
166} 196}
167 197
168static int nfs4_begin_drain_session(struct nfs_client *clp) 198static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
169{ 199{
170 struct nfs4_session *ses = clp->cl_session;
171 struct nfs4_slot_table *tbl = &ses->fc_slot_table;
172
173 spin_lock(&tbl->slot_tbl_lock); 200 spin_lock(&tbl->slot_tbl_lock);
174 set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
175 if (tbl->highest_used_slotid != -1) { 201 if (tbl->highest_used_slotid != -1) {
176 INIT_COMPLETION(ses->complete); 202 INIT_COMPLETION(tbl->complete);
177 spin_unlock(&tbl->slot_tbl_lock); 203 spin_unlock(&tbl->slot_tbl_lock);
178 return wait_for_completion_interruptible(&ses->complete); 204 return wait_for_completion_interruptible(&tbl->complete);
179 } 205 }
180 spin_unlock(&tbl->slot_tbl_lock); 206 spin_unlock(&tbl->slot_tbl_lock);
181 return 0; 207 return 0;
182} 208}
183 209
210static int nfs4_begin_drain_session(struct nfs_client *clp)
211{
212 struct nfs4_session *ses = clp->cl_session;
213 int ret = 0;
214
215 set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
216 /* back channel */
217 ret = nfs4_wait_on_slot_tbl(&ses->bc_slot_table);
218 if (ret)
219 return ret;
220 /* fore channel */
221 return nfs4_wait_on_slot_tbl(&ses->fc_slot_table);
222}
223
184int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) 224int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
185{ 225{
186 int status; 226 int status;
@@ -192,6 +232,12 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
192 status = nfs4_proc_create_session(clp); 232 status = nfs4_proc_create_session(clp);
193 if (status != 0) 233 if (status != 0)
194 goto out; 234 goto out;
235 status = nfs4_set_callback_sessionid(clp);
236 if (status != 0) {
237 printk(KERN_WARNING "Sessionid not set. No callback service\n");
238 nfs_callback_down(1);
239 status = 0;
240 }
195 nfs41_setup_state_renewal(clp); 241 nfs41_setup_state_renewal(clp);
196 nfs_mark_client_ready(clp, NFS_CS_READY); 242 nfs_mark_client_ready(clp, NFS_CS_READY);
197out: 243out:
@@ -210,28 +256,56 @@ struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
210 256
211#endif /* CONFIG_NFS_V4_1 */ 257#endif /* CONFIG_NFS_V4_1 */
212 258
213struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp) 259static struct rpc_cred *
260nfs4_get_setclientid_cred_server(struct nfs_server *server)
214{ 261{
262 struct nfs_client *clp = server->nfs_client;
263 struct rpc_cred *cred = NULL;
215 struct nfs4_state_owner *sp; 264 struct nfs4_state_owner *sp;
216 struct rb_node *pos; 265 struct rb_node *pos;
266
267 spin_lock(&clp->cl_lock);
268 pos = rb_first(&server->state_owners);
269 if (pos != NULL) {
270 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
271 cred = get_rpccred(sp->so_cred);
272 }
273 spin_unlock(&clp->cl_lock);
274 return cred;
275}
276
277/**
278 * nfs4_get_setclientid_cred - Acquire credential for a setclientid operation
279 * @clp: client state handle
280 *
281 * Returns an rpc_cred with reference count bumped, or NULL.
282 */
283struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp)
284{
285 struct nfs_server *server;
217 struct rpc_cred *cred; 286 struct rpc_cred *cred;
218 287
219 spin_lock(&clp->cl_lock); 288 spin_lock(&clp->cl_lock);
220 cred = nfs4_get_machine_cred_locked(clp); 289 cred = nfs4_get_machine_cred_locked(clp);
290 spin_unlock(&clp->cl_lock);
221 if (cred != NULL) 291 if (cred != NULL)
222 goto out; 292 goto out;
223 pos = rb_first(&clp->cl_state_owners); 293
224 if (pos != NULL) { 294 rcu_read_lock();
225 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 295 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
226 cred = get_rpccred(sp->so_cred); 296 cred = nfs4_get_setclientid_cred_server(server);
297 if (cred != NULL)
298 break;
227 } 299 }
300 rcu_read_unlock();
301
228out: 302out:
229 spin_unlock(&clp->cl_lock);
230 return cred; 303 return cred;
231} 304}
232 305
233static void nfs_alloc_unique_id(struct rb_root *root, struct nfs_unique_id *new, 306static void nfs_alloc_unique_id_locked(struct rb_root *root,
234 __u64 minval, int maxbits) 307 struct nfs_unique_id *new,
308 __u64 minval, int maxbits)
235{ 309{
236 struct rb_node **p, *parent; 310 struct rb_node **p, *parent;
237 struct nfs_unique_id *pos; 311 struct nfs_unique_id *pos;
@@ -286,16 +360,15 @@ static void nfs_free_unique_id(struct rb_root *root, struct nfs_unique_id *id)
286} 360}
287 361
288static struct nfs4_state_owner * 362static struct nfs4_state_owner *
289nfs4_find_state_owner(struct nfs_server *server, struct rpc_cred *cred) 363nfs4_find_state_owner_locked(struct nfs_server *server, struct rpc_cred *cred)
290{ 364{
291 struct nfs_client *clp = server->nfs_client; 365 struct rb_node **p = &server->state_owners.rb_node,
292 struct rb_node **p = &clp->cl_state_owners.rb_node,
293 *parent = NULL; 366 *parent = NULL;
294 struct nfs4_state_owner *sp, *res = NULL; 367 struct nfs4_state_owner *sp, *res = NULL;
295 368
296 while (*p != NULL) { 369 while (*p != NULL) {
297 parent = *p; 370 parent = *p;
298 sp = rb_entry(parent, struct nfs4_state_owner, so_client_node); 371 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
299 372
300 if (server < sp->so_server) { 373 if (server < sp->so_server) {
301 p = &parent->rb_left; 374 p = &parent->rb_left;
@@ -319,24 +392,17 @@ nfs4_find_state_owner(struct nfs_server *server, struct rpc_cred *cred)
319} 392}
320 393
321static struct nfs4_state_owner * 394static struct nfs4_state_owner *
322nfs4_insert_state_owner(struct nfs_client *clp, struct nfs4_state_owner *new) 395nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
323{ 396{
324 struct rb_node **p = &clp->cl_state_owners.rb_node, 397 struct nfs_server *server = new->so_server;
398 struct rb_node **p = &server->state_owners.rb_node,
325 *parent = NULL; 399 *parent = NULL;
326 struct nfs4_state_owner *sp; 400 struct nfs4_state_owner *sp;
327 401
328 while (*p != NULL) { 402 while (*p != NULL) {
329 parent = *p; 403 parent = *p;
330 sp = rb_entry(parent, struct nfs4_state_owner, so_client_node); 404 sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
331 405
332 if (new->so_server < sp->so_server) {
333 p = &parent->rb_left;
334 continue;
335 }
336 if (new->so_server > sp->so_server) {
337 p = &parent->rb_right;
338 continue;
339 }
340 if (new->so_cred < sp->so_cred) 406 if (new->so_cred < sp->so_cred)
341 p = &parent->rb_left; 407 p = &parent->rb_left;
342 else if (new->so_cred > sp->so_cred) 408 else if (new->so_cred > sp->so_cred)
@@ -346,18 +412,21 @@ nfs4_insert_state_owner(struct nfs_client *clp, struct nfs4_state_owner *new)
346 return sp; 412 return sp;
347 } 413 }
348 } 414 }
349 nfs_alloc_unique_id(&clp->cl_openowner_id, &new->so_owner_id, 1, 64); 415 nfs_alloc_unique_id_locked(&server->openowner_id,
350 rb_link_node(&new->so_client_node, parent, p); 416 &new->so_owner_id, 1, 64);
351 rb_insert_color(&new->so_client_node, &clp->cl_state_owners); 417 rb_link_node(&new->so_server_node, parent, p);
418 rb_insert_color(&new->so_server_node, &server->state_owners);
352 return new; 419 return new;
353} 420}
354 421
355static void 422static void
356nfs4_remove_state_owner(struct nfs_client *clp, struct nfs4_state_owner *sp) 423nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp)
357{ 424{
358 if (!RB_EMPTY_NODE(&sp->so_client_node)) 425 struct nfs_server *server = sp->so_server;
359 rb_erase(&sp->so_client_node, &clp->cl_state_owners); 426
360 nfs_free_unique_id(&clp->cl_openowner_id, &sp->so_owner_id); 427 if (!RB_EMPTY_NODE(&sp->so_server_node))
428 rb_erase(&sp->so_server_node, &server->state_owners);
429 nfs_free_unique_id(&server->openowner_id, &sp->so_owner_id);
361} 430}
362 431
363/* 432/*
@@ -386,23 +455,32 @@ nfs4_alloc_state_owner(void)
386static void 455static void
387nfs4_drop_state_owner(struct nfs4_state_owner *sp) 456nfs4_drop_state_owner(struct nfs4_state_owner *sp)
388{ 457{
389 if (!RB_EMPTY_NODE(&sp->so_client_node)) { 458 if (!RB_EMPTY_NODE(&sp->so_server_node)) {
390 struct nfs_client *clp = sp->so_server->nfs_client; 459 struct nfs_server *server = sp->so_server;
460 struct nfs_client *clp = server->nfs_client;
391 461
392 spin_lock(&clp->cl_lock); 462 spin_lock(&clp->cl_lock);
393 rb_erase(&sp->so_client_node, &clp->cl_state_owners); 463 rb_erase(&sp->so_server_node, &server->state_owners);
394 RB_CLEAR_NODE(&sp->so_client_node); 464 RB_CLEAR_NODE(&sp->so_server_node);
395 spin_unlock(&clp->cl_lock); 465 spin_unlock(&clp->cl_lock);
396 } 466 }
397} 467}
398 468
399struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct rpc_cred *cred) 469/**
470 * nfs4_get_state_owner - Look up a state owner given a credential
471 * @server: nfs_server to search
472 * @cred: RPC credential to match
473 *
474 * Returns a pointer to an instantiated nfs4_state_owner struct, or NULL.
475 */
476struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
477 struct rpc_cred *cred)
400{ 478{
401 struct nfs_client *clp = server->nfs_client; 479 struct nfs_client *clp = server->nfs_client;
402 struct nfs4_state_owner *sp, *new; 480 struct nfs4_state_owner *sp, *new;
403 481
404 spin_lock(&clp->cl_lock); 482 spin_lock(&clp->cl_lock);
405 sp = nfs4_find_state_owner(server, cred); 483 sp = nfs4_find_state_owner_locked(server, cred);
406 spin_unlock(&clp->cl_lock); 484 spin_unlock(&clp->cl_lock);
407 if (sp != NULL) 485 if (sp != NULL)
408 return sp; 486 return sp;
@@ -412,7 +490,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
412 new->so_server = server; 490 new->so_server = server;
413 new->so_cred = cred; 491 new->so_cred = cred;
414 spin_lock(&clp->cl_lock); 492 spin_lock(&clp->cl_lock);
415 sp = nfs4_insert_state_owner(clp, new); 493 sp = nfs4_insert_state_owner_locked(new);
416 spin_unlock(&clp->cl_lock); 494 spin_unlock(&clp->cl_lock);
417 if (sp == new) 495 if (sp == new)
418 get_rpccred(cred); 496 get_rpccred(cred);
@@ -423,6 +501,11 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
423 return sp; 501 return sp;
424} 502}
425 503
504/**
505 * nfs4_put_state_owner - Release a nfs4_state_owner
506 * @sp: state owner data to release
507 *
508 */
426void nfs4_put_state_owner(struct nfs4_state_owner *sp) 509void nfs4_put_state_owner(struct nfs4_state_owner *sp)
427{ 510{
428 struct nfs_client *clp = sp->so_server->nfs_client; 511 struct nfs_client *clp = sp->so_server->nfs_client;
@@ -430,7 +513,7 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp)
430 513
431 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) 514 if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
432 return; 515 return;
433 nfs4_remove_state_owner(clp, sp); 516 nfs4_remove_state_owner_locked(sp);
434 spin_unlock(&clp->cl_lock); 517 spin_unlock(&clp->cl_lock);
435 rpc_destroy_wait_queue(&sp->so_sequence.wait); 518 rpc_destroy_wait_queue(&sp->so_sequence.wait);
436 put_rpccred(cred); 519 put_rpccred(cred);
@@ -585,8 +668,11 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state,
585 if (!call_close) { 668 if (!call_close) {
586 nfs4_put_open_state(state); 669 nfs4_put_open_state(state);
587 nfs4_put_state_owner(owner); 670 nfs4_put_state_owner(owner);
588 } else 671 } else {
589 nfs4_do_close(path, state, gfp_mask, wait); 672 bool roc = pnfs_roc(state->inode);
673
674 nfs4_do_close(path, state, gfp_mask, wait, roc);
675 }
590} 676}
591 677
592void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode) 678void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode)
@@ -633,7 +719,8 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_p
633static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type) 719static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
634{ 720{
635 struct nfs4_lock_state *lsp; 721 struct nfs4_lock_state *lsp;
636 struct nfs_client *clp = state->owner->so_server->nfs_client; 722 struct nfs_server *server = state->owner->so_server;
723 struct nfs_client *clp = server->nfs_client;
637 724
638 lsp = kzalloc(sizeof(*lsp), GFP_NOFS); 725 lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
639 if (lsp == NULL) 726 if (lsp == NULL)
@@ -657,7 +744,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
657 return NULL; 744 return NULL;
658 } 745 }
659 spin_lock(&clp->cl_lock); 746 spin_lock(&clp->cl_lock);
660 nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64); 747 nfs_alloc_unique_id_locked(&server->lockowner_id, &lsp->ls_id, 1, 64);
661 spin_unlock(&clp->cl_lock); 748 spin_unlock(&clp->cl_lock);
662 INIT_LIST_HEAD(&lsp->ls_locks); 749 INIT_LIST_HEAD(&lsp->ls_locks);
663 return lsp; 750 return lsp;
@@ -665,10 +752,11 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
665 752
666static void nfs4_free_lock_state(struct nfs4_lock_state *lsp) 753static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
667{ 754{
668 struct nfs_client *clp = lsp->ls_state->owner->so_server->nfs_client; 755 struct nfs_server *server = lsp->ls_state->owner->so_server;
756 struct nfs_client *clp = server->nfs_client;
669 757
670 spin_lock(&clp->cl_lock); 758 spin_lock(&clp->cl_lock);
671 nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id); 759 nfs_free_unique_id(&server->lockowner_id, &lsp->ls_id);
672 spin_unlock(&clp->cl_lock); 760 spin_unlock(&clp->cl_lock);
673 rpc_destroy_wait_queue(&lsp->ls_sequence.wait); 761 rpc_destroy_wait_queue(&lsp->ls_sequence.wait);
674 kfree(lsp); 762 kfree(lsp);
@@ -1114,15 +1202,19 @@ static void nfs4_clear_open_state(struct nfs4_state *state)
1114 } 1202 }
1115} 1203}
1116 1204
1117static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp, int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state)) 1205static void nfs4_reset_seqids(struct nfs_server *server,
1206 int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state))
1118{ 1207{
1208 struct nfs_client *clp = server->nfs_client;
1119 struct nfs4_state_owner *sp; 1209 struct nfs4_state_owner *sp;
1120 struct rb_node *pos; 1210 struct rb_node *pos;
1121 struct nfs4_state *state; 1211 struct nfs4_state *state;
1122 1212
1123 /* Reset all sequence ids to zero */ 1213 spin_lock(&clp->cl_lock);
1124 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1214 for (pos = rb_first(&server->state_owners);
1125 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1215 pos != NULL;
1216 pos = rb_next(pos)) {
1217 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
1126 sp->so_seqid.flags = 0; 1218 sp->so_seqid.flags = 0;
1127 spin_lock(&sp->so_lock); 1219 spin_lock(&sp->so_lock);
1128 list_for_each_entry(state, &sp->so_states, open_states) { 1220 list_for_each_entry(state, &sp->so_states, open_states) {
@@ -1131,6 +1223,18 @@ static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp, int (*mark_re
1131 } 1223 }
1132 spin_unlock(&sp->so_lock); 1224 spin_unlock(&sp->so_lock);
1133 } 1225 }
1226 spin_unlock(&clp->cl_lock);
1227}
1228
1229static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp,
1230 int (*mark_reclaim)(struct nfs_client *clp, struct nfs4_state *state))
1231{
1232 struct nfs_server *server;
1233
1234 rcu_read_lock();
1235 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1236 nfs4_reset_seqids(server, mark_reclaim);
1237 rcu_read_unlock();
1134} 1238}
1135 1239
1136static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp) 1240static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
@@ -1148,25 +1252,41 @@ static void nfs4_reclaim_complete(struct nfs_client *clp,
1148 (void)ops->reclaim_complete(clp); 1252 (void)ops->reclaim_complete(clp);
1149} 1253}
1150 1254
1151static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp) 1255static void nfs4_clear_reclaim_server(struct nfs_server *server)
1152{ 1256{
1257 struct nfs_client *clp = server->nfs_client;
1153 struct nfs4_state_owner *sp; 1258 struct nfs4_state_owner *sp;
1154 struct rb_node *pos; 1259 struct rb_node *pos;
1155 struct nfs4_state *state; 1260 struct nfs4_state *state;
1156 1261
1157 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) 1262 spin_lock(&clp->cl_lock);
1158 return 0; 1263 for (pos = rb_first(&server->state_owners);
1159 1264 pos != NULL;
1160 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1265 pos = rb_next(pos)) {
1161 sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1266 sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
1162 spin_lock(&sp->so_lock); 1267 spin_lock(&sp->so_lock);
1163 list_for_each_entry(state, &sp->so_states, open_states) { 1268 list_for_each_entry(state, &sp->so_states, open_states) {
1164 if (!test_and_clear_bit(NFS_STATE_RECLAIM_REBOOT, &state->flags)) 1269 if (!test_and_clear_bit(NFS_STATE_RECLAIM_REBOOT,
1270 &state->flags))
1165 continue; 1271 continue;
1166 nfs4_state_mark_reclaim_nograce(clp, state); 1272 nfs4_state_mark_reclaim_nograce(clp, state);
1167 } 1273 }
1168 spin_unlock(&sp->so_lock); 1274 spin_unlock(&sp->so_lock);
1169 } 1275 }
1276 spin_unlock(&clp->cl_lock);
1277}
1278
1279static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp)
1280{
1281 struct nfs_server *server;
1282
1283 if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
1284 return 0;
1285
1286 rcu_read_lock();
1287 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
1288 nfs4_clear_reclaim_server(server);
1289 rcu_read_unlock();
1170 1290
1171 nfs_delegation_reap_unclaimed(clp); 1291 nfs_delegation_reap_unclaimed(clp);
1172 return 1; 1292 return 1;
@@ -1238,27 +1358,40 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1238 1358
1239static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) 1359static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops)
1240{ 1360{
1361 struct nfs4_state_owner *sp;
1362 struct nfs_server *server;
1241 struct rb_node *pos; 1363 struct rb_node *pos;
1242 int status = 0; 1364 int status = 0;
1243 1365
1244restart: 1366restart:
1245 spin_lock(&clp->cl_lock); 1367 rcu_read_lock();
1246 for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { 1368 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
1247 struct nfs4_state_owner *sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); 1369 spin_lock(&clp->cl_lock);
1248 if (!test_and_clear_bit(ops->owner_flag_bit, &sp->so_flags)) 1370 for (pos = rb_first(&server->state_owners);
1249 continue; 1371 pos != NULL;
1250 atomic_inc(&sp->so_count); 1372 pos = rb_next(pos)) {
1251 spin_unlock(&clp->cl_lock); 1373 sp = rb_entry(pos,
1252 status = nfs4_reclaim_open_state(sp, ops); 1374 struct nfs4_state_owner, so_server_node);
1253 if (status < 0) { 1375 if (!test_and_clear_bit(ops->owner_flag_bit,
1254 set_bit(ops->owner_flag_bit, &sp->so_flags); 1376 &sp->so_flags))
1377 continue;
1378 atomic_inc(&sp->so_count);
1379 spin_unlock(&clp->cl_lock);
1380 rcu_read_unlock();
1381
1382 status = nfs4_reclaim_open_state(sp, ops);
1383 if (status < 0) {
1384 set_bit(ops->owner_flag_bit, &sp->so_flags);
1385 nfs4_put_state_owner(sp);
1386 return nfs4_recovery_handle_error(clp, status);
1387 }
1388
1255 nfs4_put_state_owner(sp); 1389 nfs4_put_state_owner(sp);
1256 return nfs4_recovery_handle_error(clp, status); 1390 goto restart;
1257 } 1391 }
1258 nfs4_put_state_owner(sp); 1392 spin_unlock(&clp->cl_lock);
1259 goto restart;
1260 } 1393 }
1261 spin_unlock(&clp->cl_lock); 1394 rcu_read_unlock();
1262 return status; 1395 return status;
1263} 1396}
1264 1397