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.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index f4d4d4ec6bf7..947b0c908aa9 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -201,7 +201,9 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp,
201 if (clp->cl_minorversion != 0) 201 if (clp->cl_minorversion != 0)
202 __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags); 202 __set_bit(NFS_CS_INFINITE_SLOTS, &clp->cl_flags);
203 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); 203 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
204 error = nfs_create_rpc_client(clp, timeparms, authflavour); 204 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I);
205 if (error == -EINVAL)
206 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_NULL);
205 if (error < 0) 207 if (error < 0)
206 goto error; 208 goto error;
207 209
@@ -302,7 +304,7 @@ int nfs40_walk_client_list(struct nfs_client *new,
302 struct rpc_cred *cred) 304 struct rpc_cred *cred)
303{ 305{
304 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); 306 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
305 struct nfs_client *pos, *n, *prev = NULL; 307 struct nfs_client *pos, *prev = NULL;
306 struct nfs4_setclientid_res clid = { 308 struct nfs4_setclientid_res clid = {
307 .clientid = new->cl_clientid, 309 .clientid = new->cl_clientid,
308 .confirm = new->cl_confirm, 310 .confirm = new->cl_confirm,
@@ -310,10 +312,23 @@ int nfs40_walk_client_list(struct nfs_client *new,
310 int status = -NFS4ERR_STALE_CLIENTID; 312 int status = -NFS4ERR_STALE_CLIENTID;
311 313
312 spin_lock(&nn->nfs_client_lock); 314 spin_lock(&nn->nfs_client_lock);
313 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { 315 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
314 /* If "pos" isn't marked ready, we can't trust the 316 /* If "pos" isn't marked ready, we can't trust the
315 * remaining fields in "pos" */ 317 * remaining fields in "pos" */
316 if (pos->cl_cons_state < NFS_CS_READY) 318 if (pos->cl_cons_state > NFS_CS_READY) {
319 atomic_inc(&pos->cl_count);
320 spin_unlock(&nn->nfs_client_lock);
321
322 if (prev)
323 nfs_put_client(prev);
324 prev = pos;
325
326 status = nfs_wait_client_init_complete(pos);
327 spin_lock(&nn->nfs_client_lock);
328 if (status < 0)
329 continue;
330 }
331 if (pos->cl_cons_state != NFS_CS_READY)
317 continue; 332 continue;
318 333
319 if (pos->rpc_ops != new->rpc_ops) 334 if (pos->rpc_ops != new->rpc_ops)
@@ -425,16 +440,16 @@ int nfs41_walk_client_list(struct nfs_client *new,
425 struct rpc_cred *cred) 440 struct rpc_cred *cred)
426{ 441{
427 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); 442 struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
428 struct nfs_client *pos, *n, *prev = NULL; 443 struct nfs_client *pos, *prev = NULL;
429 int status = -NFS4ERR_STALE_CLIENTID; 444 int status = -NFS4ERR_STALE_CLIENTID;
430 445
431 spin_lock(&nn->nfs_client_lock); 446 spin_lock(&nn->nfs_client_lock);
432 list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { 447 list_for_each_entry(pos, &nn->nfs_client_list, cl_share_link) {
433 /* If "pos" isn't marked ready, we can't trust the 448 /* If "pos" isn't marked ready, we can't trust the
434 * remaining fields in "pos", especially the client 449 * remaining fields in "pos", especially the client
435 * ID and serverowner fields. Wait for CREATE_SESSION 450 * ID and serverowner fields. Wait for CREATE_SESSION
436 * to finish. */ 451 * to finish. */
437 if (pos->cl_cons_state < NFS_CS_READY) { 452 if (pos->cl_cons_state > NFS_CS_READY) {
438 atomic_inc(&pos->cl_count); 453 atomic_inc(&pos->cl_count);
439 spin_unlock(&nn->nfs_client_lock); 454 spin_unlock(&nn->nfs_client_lock);
440 455
@@ -442,18 +457,17 @@ int nfs41_walk_client_list(struct nfs_client *new,
442 nfs_put_client(prev); 457 nfs_put_client(prev);
443 prev = pos; 458 prev = pos;
444 459
445 nfs4_schedule_lease_recovery(pos);
446 status = nfs_wait_client_init_complete(pos); 460 status = nfs_wait_client_init_complete(pos);
447 if (status < 0) { 461 if (status == 0) {
448 nfs_put_client(pos); 462 nfs4_schedule_lease_recovery(pos);
449 spin_lock(&nn->nfs_client_lock); 463 status = nfs4_wait_clnt_recover(pos);
450 continue;
451 } 464 }
452 status = pos->cl_cons_state;
453 spin_lock(&nn->nfs_client_lock); 465 spin_lock(&nn->nfs_client_lock);
454 if (status < 0) 466 if (status < 0)
455 continue; 467 continue;
456 } 468 }
469 if (pos->cl_cons_state != NFS_CS_READY)
470 continue;
457 471
458 if (pos->rpc_ops != new->rpc_ops) 472 if (pos->rpc_ops != new->rpc_ops)
459 continue; 473 continue;
@@ -471,17 +485,18 @@ int nfs41_walk_client_list(struct nfs_client *new,
471 continue; 485 continue;
472 486
473 atomic_inc(&pos->cl_count); 487 atomic_inc(&pos->cl_count);
474 spin_unlock(&nn->nfs_client_lock); 488 *result = pos;
489 status = 0;
475 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", 490 dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
476 __func__, pos, atomic_read(&pos->cl_count)); 491 __func__, pos, atomic_read(&pos->cl_count));
477 492 break;
478 *result = pos;
479 return 0;
480 } 493 }
481 494
482 /* No matching nfs_client found. */ 495 /* No matching nfs_client found. */
483 spin_unlock(&nn->nfs_client_lock); 496 spin_unlock(&nn->nfs_client_lock);
484 dprintk("NFS: <-- %s status = %d\n", __func__, status); 497 dprintk("NFS: <-- %s status = %d\n", __func__, status);
498 if (prev)
499 nfs_put_client(prev);
485 return status; 500 return status;
486} 501}
487#endif /* CONFIG_NFS_V4_1 */ 502#endif /* CONFIG_NFS_V4_1 */