diff options
-rw-r--r-- | fs/nfs/super.c | 21 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 2 |
2 files changed, 21 insertions, 2 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index c97f30967955..d1b4a5b36e33 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -658,11 +658,19 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned | |||
658 | static struct rpc_clnt * | 658 | static struct rpc_clnt * |
659 | nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | 659 | nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) |
660 | { | 660 | { |
661 | struct nfs_client *clp; | ||
661 | struct rpc_timeout timeparms; | 662 | struct rpc_timeout timeparms; |
662 | struct rpc_xprt *xprt = NULL; | 663 | struct rpc_xprt *xprt = NULL; |
663 | struct rpc_clnt *clnt = NULL; | 664 | struct rpc_clnt *clnt = NULL; |
664 | int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; | 665 | int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; |
665 | 666 | ||
667 | clp = nfs_get_client(server->hostname, &server->addr, | ||
668 | server->rpc_ops->version); | ||
669 | if (!clp) { | ||
670 | dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__); | ||
671 | return ERR_PTR(PTR_ERR(clp)); | ||
672 | } | ||
673 | |||
666 | nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans); | 674 | nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans); |
667 | 675 | ||
668 | server->retrans_timeo = timeparms.to_initval; | 676 | server->retrans_timeo = timeparms.to_initval; |
@@ -673,6 +681,8 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | |||
673 | if (IS_ERR(xprt)) { | 681 | if (IS_ERR(xprt)) { |
674 | dprintk("%s: cannot create RPC transport. Error = %ld\n", | 682 | dprintk("%s: cannot create RPC transport. Error = %ld\n", |
675 | __FUNCTION__, PTR_ERR(xprt)); | 683 | __FUNCTION__, PTR_ERR(xprt)); |
684 | nfs_mark_client_ready(clp, PTR_ERR(xprt)); | ||
685 | nfs_put_client(clp); | ||
676 | return (struct rpc_clnt *)xprt; | 686 | return (struct rpc_clnt *)xprt; |
677 | } | 687 | } |
678 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, | 688 | clnt = rpc_create_client(xprt, server->hostname, &nfs_program, |
@@ -686,9 +696,13 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) | |||
686 | clnt->cl_intr = 1; | 696 | clnt->cl_intr = 1; |
687 | clnt->cl_softrtry = 1; | 697 | clnt->cl_softrtry = 1; |
688 | 698 | ||
699 | nfs_mark_client_ready(clp, 0); | ||
700 | server->nfs_client = clp; | ||
689 | return clnt; | 701 | return clnt; |
690 | 702 | ||
691 | out_fail: | 703 | out_fail: |
704 | nfs_mark_client_ready(clp, PTR_ERR(xprt)); | ||
705 | nfs_put_client(clp); | ||
692 | return clnt; | 706 | return clnt; |
693 | } | 707 | } |
694 | 708 | ||
@@ -764,6 +778,7 @@ static int nfs_clone_generic_sb(struct nfs_clone_mount *data, | |||
764 | if (server == NULL) | 778 | if (server == NULL) |
765 | goto out_err; | 779 | goto out_err; |
766 | memcpy(server, parent, sizeof(*server)); | 780 | memcpy(server, parent, sizeof(*server)); |
781 | atomic_inc(&server->nfs_client->cl_count); | ||
767 | hostname = (data->hostname != NULL) ? data->hostname : parent->hostname; | 782 | hostname = (data->hostname != NULL) ? data->hostname : parent->hostname; |
768 | len = strlen(hostname) + 1; | 783 | len = strlen(hostname) + 1; |
769 | server->hostname = kmalloc(len, GFP_KERNEL); | 784 | server->hostname = kmalloc(len, GFP_KERNEL); |
@@ -796,6 +811,7 @@ out_deactivate: | |||
796 | out_rpciod_down: | 811 | out_rpciod_down: |
797 | rpciod_down(); | 812 | rpciod_down(); |
798 | kfree(server->hostname); | 813 | kfree(server->hostname); |
814 | nfs_put_client(server->nfs_client); | ||
799 | kfree(server); | 815 | kfree(server); |
800 | return simple_set_mnt(mnt, sb); | 816 | return simple_set_mnt(mnt, sb); |
801 | kill_rpciod: | 817 | kill_rpciod: |
@@ -803,6 +819,7 @@ kill_rpciod: | |||
803 | free_hostname: | 819 | free_hostname: |
804 | kfree(server->hostname); | 820 | kfree(server->hostname); |
805 | free_server: | 821 | free_server: |
822 | nfs_put_client(server->nfs_client); | ||
806 | kfree(server); | 823 | kfree(server); |
807 | out_err: | 824 | out_err: |
808 | return error; | 825 | return error; |
@@ -1071,6 +1088,7 @@ static void nfs_kill_super(struct super_block *s) | |||
1071 | 1088 | ||
1072 | nfs_free_iostats(server->io_stats); | 1089 | nfs_free_iostats(server->io_stats); |
1073 | kfree(server->hostname); | 1090 | kfree(server->hostname); |
1091 | nfs_put_client(server->nfs_client); | ||
1074 | kfree(server); | 1092 | kfree(server); |
1075 | nfs_release_automount_timer(); | 1093 | nfs_release_automount_timer(); |
1076 | } | 1094 | } |
@@ -1421,7 +1439,6 @@ static struct super_block *nfs4_clone_sb(struct nfs_server *server, struct nfs_c | |||
1421 | nfs4_server_capabilities(server, &server->fh); | 1439 | nfs4_server_capabilities(server, &server->fh); |
1422 | 1440 | ||
1423 | down_write(&clp->cl_sem); | 1441 | down_write(&clp->cl_sem); |
1424 | atomic_inc(&clp->cl_count); | ||
1425 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); | 1442 | list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks); |
1426 | up_write(&clp->cl_sem); | 1443 | up_write(&clp->cl_sem); |
1427 | return sb; | 1444 | return sb; |
@@ -1476,6 +1493,8 @@ static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nf | |||
1476 | retrans = 1; | 1493 | retrans = 1; |
1477 | nfs_init_timeout_values(&timeparms, proto, timeo, retrans); | 1494 | nfs_init_timeout_values(&timeparms, proto, timeo, retrans); |
1478 | 1495 | ||
1496 | nfs_put_client(server->nfs_client); | ||
1497 | server->nfs_client = NULL; | ||
1479 | server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor); | 1498 | server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor); |
1480 | if (IS_ERR((err = server->client))) | 1499 | if (IS_ERR((err = server->client))) |
1481 | goto out_err; | 1500 | goto out_err; |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 95f32d5f6e9c..e7d7662f51fd 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -70,6 +70,7 @@ struct nfs_client { | |||
70 | * NFS client parameters stored in the superblock. | 70 | * NFS client parameters stored in the superblock. |
71 | */ | 71 | */ |
72 | struct nfs_server { | 72 | struct nfs_server { |
73 | struct nfs_client * nfs_client; /* shared client and NFS4 state */ | ||
73 | struct rpc_clnt * client; /* RPC client handle */ | 74 | struct rpc_clnt * client; /* RPC client handle */ |
74 | struct rpc_clnt * client_sys; /* 2nd handle for FSINFO */ | 75 | struct rpc_clnt * client_sys; /* 2nd handle for FSINFO */ |
75 | struct rpc_clnt * client_acl; /* ACL RPC client handle */ | 76 | struct rpc_clnt * client_acl; /* ACL RPC client handle */ |
@@ -103,7 +104,6 @@ struct nfs_server { | |||
103 | */ | 104 | */ |
104 | char ip_addr[16]; | 105 | char ip_addr[16]; |
105 | char * mnt_path; | 106 | char * mnt_path; |
106 | struct nfs_client * nfs_client; /* all NFSv4 state starts here */ | ||
107 | struct list_head nfs4_siblings; /* List of other nfs_server structs | 107 | struct list_head nfs4_siblings; /* List of other nfs_server structs |
108 | * that share the same clientid | 108 | * that share the same clientid |
109 | */ | 109 | */ |