diff options
Diffstat (limited to 'fs/nfs/nfs4client.c')
-rw-r--r-- | fs/nfs/nfs4client.c | 49 |
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 */ |