aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4client.c')
-rw-r--r--fs/nfs/nfs4client.c62
1 files changed, 26 insertions, 36 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index acc347268124..2e9779b58b7a 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -236,11 +236,10 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
236 error = nfs4_discover_server_trunking(clp, &old); 236 error = nfs4_discover_server_trunking(clp, &old);
237 if (error < 0) 237 if (error < 0)
238 goto error; 238 goto error;
239 nfs_put_client(clp);
239 if (clp != old) { 240 if (clp != old) {
240 clp->cl_preserve_clid = true; 241 clp->cl_preserve_clid = true;
241 nfs_put_client(clp);
242 clp = old; 242 clp = old;
243 atomic_inc(&clp->cl_count);
244 } 243 }
245 244
246 return clp; 245 return clp;
@@ -306,7 +305,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
306 .clientid = new->cl_clientid, 305 .clientid = new->cl_clientid,
307 .confirm = new->cl_confirm, 306 .confirm = new->cl_confirm,
308 }; 307 };
309 int status; 308 int status = -NFS4ERR_STALE_CLIENTID;
310 309
311 spin_lock(&nn->nfs_client_lock); 310 spin_lock(&nn->nfs_client_lock);
312 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { 311 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
@@ -332,40 +331,33 @@ int nfs40_walk_client_list(struct nfs_client *new,
332 331
333 if (prev) 332 if (prev)
334 nfs_put_client(prev); 333 nfs_put_client(prev);
334 prev = pos;
335 335
336 status = nfs4_proc_setclientid_confirm(pos, &clid, cred); 336 status = nfs4_proc_setclientid_confirm(pos, &clid, cred);
337 if (status == 0) { 337 switch (status) {
338 case -NFS4ERR_STALE_CLIENTID:
339 break;
340 case 0:
338 nfs4_swap_callback_idents(pos, new); 341 nfs4_swap_callback_idents(pos, new);
339 342
340 nfs_put_client(pos); 343 prev = NULL;
341 *result = pos; 344 *result = pos;
342 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", 345 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
343 __func__, pos, atomic_read(&pos->cl_count)); 346 __func__, pos, atomic_read(&pos->cl_count));
344 return 0; 347 default:
345 } 348 goto out;
346 if (status != -NFS4ERR_STALE_CLIENTID) {
347 nfs_put_client(pos);
348 dprintk("NFS: <-- %s status = %d, no result\n",
349 __func__, status);
350 return status;
351 } 349 }
352 350
353 spin_lock(&nn->nfs_client_lock); 351 spin_lock(&nn->nfs_client_lock);
354 prev = pos;
355 } 352 }
353 spin_unlock(&nn->nfs_client_lock);
356 354
357 /* 355 /* No match found. The server lost our clientid */
358 * No matching nfs_client found. This should be impossible, 356out:
359 * because the new nfs_client has already been added to
360 * nfs_client_list by nfs_get_client().
361 *
362 * Don't BUG(), since the caller is holding a mutex.
363 */
364 if (prev) 357 if (prev)
365 nfs_put_client(prev); 358 nfs_put_client(prev);
366 spin_unlock(&nn->nfs_client_lock); 359 dprintk("NFS: <-- %s status = %d\n", __func__, status);
367 pr_err("NFS: %s Error: no matching nfs_client found\n", __func__); 360 return status;
368 return -NFS4ERR_STALE_CLIENTID;
369} 361}
370 362
371#ifdef CONFIG_NFS_V4_1 363#ifdef CONFIG_NFS_V4_1
@@ -432,7 +424,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
432{ 424{
433 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); 425 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
434 struct nfs_client *pos, *n, *prev = NULL; 426 struct nfs_client *pos, *n, *prev = NULL;
435 int error; 427 int status = -NFS4ERR_STALE_CLIENTID;
436 428
437 spin_lock(&nn->nfs_client_lock); 429 spin_lock(&nn->nfs_client_lock);
438 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { 430 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
@@ -448,14 +440,17 @@ int nfs41_walk_client_list(struct nfs_client *new,
448 nfs_put_client(prev); 440 nfs_put_client(prev);
449 prev = pos; 441 prev = pos;
450 442
451 error = nfs_wait_client_init_complete(pos); 443 nfs4_schedule_lease_recovery(pos);
452 if (error < 0) { 444 status = nfs_wait_client_init_complete(pos);
445 if (status < 0) {
453 nfs_put_client(pos); 446 nfs_put_client(pos);
454 spin_lock(&nn->nfs_client_lock); 447 spin_lock(&nn->nfs_client_lock);
455 continue; 448 continue;
456 } 449 }
457 450 status = pos->cl_cons_state;
458 spin_lock(&nn->nfs_client_lock); 451 spin_lock(&nn->nfs_client_lock);
452 if (status < 0)
453 continue;
459 } 454 }
460 455
461 if (pos->rpc_ops != new->rpc_ops) 456 if (pos->rpc_ops != new->rpc_ops)
@@ -473,6 +468,7 @@ int nfs41_walk_client_list(struct nfs_client *new,
473 if (!nfs4_match_serverowners(pos, new)) 468 if (!nfs4_match_serverowners(pos, new))
474 continue; 469 continue;
475 470
471 atomic_inc(&pos->cl_count);
476 spin_unlock(&nn->nfs_client_lock); 472 spin_unlock(&nn->nfs_client_lock);
477 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", 473 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
478 __func__, pos, atomic_read(&pos->cl_count)); 474 __func__, pos, atomic_read(&pos->cl_count));
@@ -481,16 +477,10 @@ int nfs41_walk_client_list(struct nfs_client *new,
481 return 0; 477 return 0;
482 } 478 }
483 479
484 /* 480 /* No matching nfs_client found. */
485 * No matching nfs_client found. This should be impossible,
486 * because the new nfs_client has already been added to
487 * nfs_client_list by nfs_get_client().
488 *
489 * Don't BUG(), since the caller is holding a mutex.
490 */
491 spin_unlock(&nn->nfs_client_lock); 481 spin_unlock(&nn->nfs_client_lock);
492 pr_err("NFS: %s Error: no matching nfs_client found\n", __func__); 482 dprintk("NFS: <-- %s status = %d\n", __func__, status);
493 return -NFS4ERR_STALE_CLIENTID; 483 return status;
494} 484}
495#endif /* CONFIG_NFS_V4_1 */ 485#endif /* CONFIG_NFS_V4_1 */
496 486