aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/client.c')
-rw-r--r--fs/nfs/client.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index af9b7e4b9df2..5f19f9577730 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -506,6 +506,35 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
506} 506}
507 507
508/* 508/*
509 * Found an existing client. Make sure it's ready before returning.
510 */
511static struct nfs_client *
512nfs_found_client(const struct nfs_client_initdata *cl_init,
513 struct nfs_client *clp)
514{
515 int error;
516
517 error = wait_event_killable(nfs_client_active_wq,
518 clp->cl_cons_state < NFS_CS_INITING);
519 if (error < 0) {
520 nfs_put_client(clp);
521 return ERR_PTR(-ERESTARTSYS);
522 }
523
524 if (clp->cl_cons_state < NFS_CS_READY) {
525 error = clp->cl_cons_state;
526 nfs_put_client(clp);
527 return ERR_PTR(error);
528 }
529
530 BUG_ON(clp->cl_cons_state != NFS_CS_READY);
531
532 dprintk("<-- %s found nfs_client %p for %s\n",
533 __func__, clp, cl_init->hostname ?: "");
534 return clp;
535}
536
537/*
509 * Look up a client by IP address and protocol version 538 * Look up a client by IP address and protocol version
510 * - creates a new record if one doesn't yet exist 539 * - creates a new record if one doesn't yet exist
511 */ 540 */
@@ -528,8 +557,12 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
528 spin_lock(&nn->nfs_client_lock); 557 spin_lock(&nn->nfs_client_lock);
529 558
530 clp = nfs_match_client(cl_init); 559 clp = nfs_match_client(cl_init);
531 if (clp) 560 if (clp) {
532 goto found_client; 561 spin_unlock(&nn->nfs_client_lock);
562 if (new)
563 nfs_free_client(new);
564 return nfs_found_client(cl_init, clp);
565 }
533 if (new) 566 if (new)
534 goto install_client; 567 goto install_client;
535 568
@@ -538,7 +571,8 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
538 new = nfs_alloc_client(cl_init); 571 new = nfs_alloc_client(cl_init);
539 } while (!IS_ERR(new)); 572 } while (!IS_ERR(new));
540 573
541 dprintk("--> nfs_get_client() = %ld [failed]\n", PTR_ERR(new)); 574 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n",
575 cl_init->hostname ?: "", PTR_ERR(new));
542 return new; 576 return new;
543 577
544 /* install a new client and return with it unready */ 578 /* install a new client and return with it unready */
@@ -555,33 +589,6 @@ install_client:
555 } 589 }
556 dprintk("--> nfs_get_client() = %p [new]\n", clp); 590 dprintk("--> nfs_get_client() = %p [new]\n", clp);
557 return clp; 591 return clp;
558
559 /* found an existing client
560 * - make sure it's ready before returning
561 */
562found_client:
563 spin_unlock(&nn->nfs_client_lock);
564
565 if (new)
566 nfs_free_client(new);
567
568 error = wait_event_killable(nfs_client_active_wq,
569 clp->cl_cons_state < NFS_CS_INITING);
570 if (error < 0) {
571 nfs_put_client(clp);
572 return ERR_PTR(-ERESTARTSYS);
573 }
574
575 if (clp->cl_cons_state < NFS_CS_READY) {
576 error = clp->cl_cons_state;
577 nfs_put_client(clp);
578 return ERR_PTR(error);
579 }
580
581 BUG_ON(clp->cl_cons_state != NFS_CS_READY);
582
583 dprintk("--> nfs_get_client() = %p [share]\n", clp);
584 return clp;
585} 592}
586 593
587/* 594/*