aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-08-22 20:06:12 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-09-22 23:24:36 -0400
commit5006a76cca8f86c6975c16fcf67e83b8b0eee2b6 (patch)
treefbe711871729ddfc921e91ba86202a15c5a1a55f /fs/nfs/super.c
parent8fa5c000d7f986ef9cdc6d95f9f7fcee20e0a7d6 (diff)
NFS: Eliminate client_sys in favour of cl_rpcclient
Eliminate nfs_server::client_sys in favour of nfs_client::cl_rpcclient as we only really need one per server that we're talking to since it doesn't have any security on it. The retransmission management variables are also moved to the common struct as they're required to set up the cl_rpcclient connection. The NFS2/3 client and client_acl connections are thenceforth derived by cloning the cl_rpcclient connection and post-applying the authorisation flavour. The code for setting up the initial common connection has been moved to client.c as nfs_create_rpc_client(). All the NFS program definition tables are also moved there as that's where they're now required rather than super.c. Signed-Off-By: David Howells <dhowells@redhat.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c222
1 files changed, 51 insertions, 171 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index e1e5eab0259b..85583414a3ca 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -60,52 +60,6 @@
60 */ 60 */
61#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 61#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
62 62
63/*
64 * RPC cruft for NFS
65 */
66static struct rpc_version * nfs_version[] = {
67 NULL,
68 NULL,
69 &nfs_version2,
70#if defined(CONFIG_NFS_V3)
71 &nfs_version3,
72#elif defined(CONFIG_NFS_V4)
73 NULL,
74#endif
75#if defined(CONFIG_NFS_V4)
76 &nfs_version4,
77#endif
78};
79
80static struct rpc_program nfs_program = {
81 .name = "nfs",
82 .number = NFS_PROGRAM,
83 .nrvers = ARRAY_SIZE(nfs_version),
84 .version = nfs_version,
85 .stats = &nfs_rpcstat,
86 .pipe_dir_name = "/nfs",
87};
88
89struct rpc_stat nfs_rpcstat = {
90 .program = &nfs_program
91};
92
93
94#ifdef CONFIG_NFS_V3_ACL
95static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
96static struct rpc_version * nfsacl_version[] = {
97 [3] = &nfsacl_version3,
98};
99
100struct rpc_program nfsacl_program = {
101 .name = "nfsacl",
102 .number = NFS_ACL_PROGRAM,
103 .nrvers = ARRAY_SIZE(nfsacl_version),
104 .version = nfsacl_version,
105 .stats = &nfsacl_rpcstat,
106};
107#endif /* CONFIG_NFS_V3_ACL */
108
109static void nfs_umount_begin(struct vfsmount *, int); 63static void nfs_umount_begin(struct vfsmount *, int);
110static int nfs_statfs(struct dentry *, struct kstatfs *); 64static int nfs_statfs(struct dentry *, struct kstatfs *);
111static int nfs_show_options(struct seq_file *, struct vfsmount *); 65static int nfs_show_options(struct seq_file *, struct vfsmount *);
@@ -376,8 +330,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
376 proto = buf; 330 proto = buf;
377 } 331 }
378 seq_printf(m, ",proto=%s", proto); 332 seq_printf(m, ",proto=%s", proto);
379 seq_printf(m, ",timeo=%lu", 10U * nfss->retrans_timeo / HZ); 333 seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ);
380 seq_printf(m, ",retrans=%u", nfss->retrans_count); 334 seq_printf(m, ",retrans=%u", clp->retrans_count);
381 seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); 335 seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
382} 336}
383 337
@@ -622,49 +576,16 @@ out_no_root:
622} 576}
623 577
624/* 578/*
625 * Initialise the timeout values for a connection
626 */
627static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans)
628{
629 to->to_initval = timeo * HZ / 10;
630 to->to_retries = retrans;
631 if (!to->to_retries)
632 to->to_retries = 2;
633
634 switch (proto) {
635 case IPPROTO_TCP:
636 if (!to->to_initval)
637 to->to_initval = 60 * HZ;
638 if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
639 to->to_initval = NFS_MAX_TCP_TIMEOUT;
640 to->to_increment = to->to_initval;
641 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
642 to->to_exponential = 0;
643 break;
644 case IPPROTO_UDP:
645 default:
646 if (!to->to_initval)
647 to->to_initval = 11 * HZ / 10;
648 if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
649 to->to_initval = NFS_MAX_UDP_TIMEOUT;
650 to->to_maxval = NFS_MAX_UDP_TIMEOUT;
651 to->to_exponential = 1;
652 break;
653 }
654}
655
656/*
657 * Create an RPC client handle. 579 * Create an RPC client handle.
658 */ 580 */
659static struct rpc_clnt * 581static struct rpc_clnt *
660nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data) 582nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
661{ 583{
662 struct nfs_client *clp; 584 struct nfs_client *clp;
663 struct rpc_timeout timeparms; 585 struct rpc_clnt *clnt;
664 struct rpc_xprt *xprt = NULL;
665 struct rpc_clnt *clnt = NULL;
666 int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; 586 int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
667 int nfsversion = 2; 587 int nfsversion = 2;
588 int err;
668 589
669#ifdef CONFIG_NFS_V3 590#ifdef CONFIG_NFS_V3
670 if (server->flags & NFS_MOUNT_VER3) 591 if (server->flags & NFS_MOUNT_VER3)
@@ -677,52 +598,54 @@ nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
677 return ERR_PTR(PTR_ERR(clp)); 598 return ERR_PTR(PTR_ERR(clp));
678 } 599 }
679 600
680 nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans); 601 if (clp->cl_cons_state == NFS_CS_INITING) {
681 602 /* Check NFS protocol revision and initialize RPC op
682 server->retrans_timeo = timeparms.to_initval; 603 * vector and file handle pool. */
683 server->retrans_count = timeparms.to_retries;
684
685 /* Check NFS protocol revision and initialize RPC op vector
686 * and file handle pool. */
687#ifdef CONFIG_NFS_V3 604#ifdef CONFIG_NFS_V3
688 if (nfsversion == 3) { 605 if (nfsversion == 3) {
689 clp->rpc_ops = &nfs_v3_clientops; 606 clp->rpc_ops = &nfs_v3_clientops;
690 server->caps |= NFS_CAP_READDIRPLUS; 607 server->caps |= NFS_CAP_READDIRPLUS;
691 } else { 608 } else {
692 clp->rpc_ops = &nfs_v2_clientops; 609 clp->rpc_ops = &nfs_v2_clientops;
693 } 610 }
694#else 611#else
695 clp->rpc_ops = &nfs_v2_clientops; 612 clp->rpc_ops = &nfs_v2_clientops;
696#endif 613#endif
697 614
698 /* create transport and client */ 615 /* create transport and client */
699 xprt = xprt_create_proto(proto, &server->addr, &timeparms); 616 err = nfs_create_rpc_client(clp, proto, data->timeo,
700 if (IS_ERR(xprt)) { 617 data->retrans, RPC_AUTH_UNIX);
701 dprintk("%s: cannot create RPC transport. Error = %ld\n", 618 if (err < 0)
702 __FUNCTION__, PTR_ERR(xprt)); 619 goto client_init_error;
703 nfs_mark_client_ready(clp, PTR_ERR(xprt)); 620
704 nfs_put_client(clp); 621 nfs_mark_client_ready(clp, 0);
705 return (struct rpc_clnt *)xprt;
706 } 622 }
707 clnt = rpc_create_client(xprt, server->hostname, &nfs_program, 623
708 clp->cl_nfsversion, data->pseudoflavor); 624 /* create an nfs_server-specific client */
625 clnt = rpc_clone_client(clp->cl_rpcclient);
709 if (IS_ERR(clnt)) { 626 if (IS_ERR(clnt)) {
710 dprintk("%s: cannot create RPC client. Error = %ld\n", 627 dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__);
711 __FUNCTION__, PTR_ERR(xprt)); 628 nfs_put_client(clp);
712 goto out_fail; 629 return ERR_PTR(PTR_ERR(clnt));
713 } 630 }
714 631
715 clnt->cl_intr = 1; 632 if (data->pseudoflavor != clp->cl_rpcclient->cl_auth->au_flavor) {
716 clnt->cl_softrtry = 1; 633 struct rpc_auth *auth;
634
635 auth = rpcauth_create(data->pseudoflavor, server->client);
636 if (IS_ERR(auth)) {
637 dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
638 return ERR_PTR(PTR_ERR(auth));
639 }
640 }
717 641
718 nfs_mark_client_ready(clp, 0);
719 server->nfs_client = clp; 642 server->nfs_client = clp;
720 return clnt; 643 return clnt;
721 644
722out_fail: 645client_init_error:
723 nfs_mark_client_ready(clp, PTR_ERR(xprt)); 646 nfs_mark_client_ready(clp, err);
724 nfs_put_client(clp); 647 nfs_put_client(clp);
725 return clnt; 648 return ERR_PTR(err);
726} 649}
727 650
728/* 651/*
@@ -741,7 +664,7 @@ static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_cl
741 sb->s_blocksize_bits = data->sb->s_blocksize_bits; 664 sb->s_blocksize_bits = data->sb->s_blocksize_bits;
742 sb->s_maxbytes = data->sb->s_maxbytes; 665 sb->s_maxbytes = data->sb->s_maxbytes;
743 666
744 server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 667 server->client_acl = ERR_PTR(-EINVAL);
745 server->io_stats = nfs_alloc_iostats(); 668 server->io_stats = nfs_alloc_iostats();
746 if (server->io_stats == NULL) 669 if (server->io_stats == NULL)
747 goto out; 670 goto out;
@@ -750,11 +673,6 @@ static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_cl
750 if (IS_ERR((err = server->client))) 673 if (IS_ERR((err = server->client)))
751 goto out; 674 goto out;
752 675
753 if (!IS_ERR(parent->client_sys)) {
754 server->client_sys = rpc_clone_client(parent->client_sys);
755 if (IS_ERR((err = server->client_sys)))
756 goto out;
757 }
758 if (!IS_ERR(parent->client_acl)) { 676 if (!IS_ERR(parent->client_acl)) {
759 server->client_acl = rpc_clone_client(parent->client_acl); 677 server->client_acl = rpc_clone_client(parent->client_acl);
760 if (IS_ERR((err = server->client_acl))) 678 if (IS_ERR((err = server->client_acl)))
@@ -813,7 +731,7 @@ static int nfs_clone_generic_sb(struct nfs_clone_mount *data,
813 error = PTR_ERR(sb); 731 error = PTR_ERR(sb);
814 goto kill_rpciod; 732 goto kill_rpciod;
815 } 733 }
816 734
817 if (sb->s_root) 735 if (sb->s_root)
818 goto out_rpciod_down; 736 goto out_rpciod_down;
819 737
@@ -896,19 +814,6 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
896 return PTR_ERR(server->client); 814 return PTR_ERR(server->client);
897 815
898 /* RFC 2623, sec 2.3.2 */ 816 /* RFC 2623, sec 2.3.2 */
899 if (authflavor != RPC_AUTH_UNIX) {
900 struct rpc_auth *auth;
901
902 server->client_sys = rpc_clone_client(server->client);
903 if (IS_ERR(server->client_sys))
904 return PTR_ERR(server->client_sys);
905 auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys);
906 if (IS_ERR(auth))
907 return PTR_ERR(auth);
908 } else {
909 atomic_inc(&server->client->cl_count);
910 server->client_sys = server->client;
911 }
912 if (server->flags & NFS_MOUNT_VER3) { 817 if (server->flags & NFS_MOUNT_VER3) {
913#ifdef CONFIG_NFS_V3_ACL 818#ifdef CONFIG_NFS_V3_ACL
914 if (!(server->flags & NFS_MOUNT_NOACL)) { 819 if (!(server->flags & NFS_MOUNT_NOACL)) {
@@ -1012,7 +917,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
1012 goto out_err_noserver; 917 goto out_err_noserver;
1013 /* Zero out the NFS state stuff */ 918 /* Zero out the NFS state stuff */
1014 init_nfsv4_state(server); 919 init_nfsv4_state(server);
1015 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 920 server->client = server->client_acl = ERR_PTR(-EINVAL);
1016 921
1017 root = &server->fh; 922 root = &server->fh;
1018 if (data->flags & NFS_MOUNT_VER3) 923 if (data->flags & NFS_MOUNT_VER3)
@@ -1083,8 +988,6 @@ static void nfs_kill_super(struct super_block *s)
1083 988
1084 if (!IS_ERR(server->client)) 989 if (!IS_ERR(server->client))
1085 rpc_shutdown_client(server->client); 990 rpc_shutdown_client(server->client);
1086 if (!IS_ERR(server->client_sys))
1087 rpc_shutdown_client(server->client_sys);
1088 if (!IS_ERR(server->client_acl)) 991 if (!IS_ERR(server->client_acl))
1089 rpc_shutdown_client(server->client_acl); 992 rpc_shutdown_client(server->client_acl);
1090 993
@@ -1121,10 +1024,9 @@ static int nfs_clone_nfs_sb(struct file_system_type *fs_type,
1121 1024
1122#ifdef CONFIG_NFS_V4 1025#ifdef CONFIG_NFS_V4
1123static struct rpc_clnt *nfs4_create_client(struct nfs_server *server, 1026static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
1124 struct rpc_timeout *timeparms, int proto, rpc_authflavor_t flavor) 1027 int timeo, int retrans, int proto, rpc_authflavor_t flavor)
1125{ 1028{
1126 struct nfs_client *clp; 1029 struct nfs_client *clp;
1127 struct rpc_xprt *xprt = NULL;
1128 struct rpc_clnt *clnt = NULL; 1030 struct rpc_clnt *clnt = NULL;
1129 int err = -EIO; 1031 int err = -EIO;
1130 1032
@@ -1138,26 +1040,10 @@ static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
1138 if (clp->cl_cons_state == NFS_CS_INITING) { 1040 if (clp->cl_cons_state == NFS_CS_INITING) {
1139 clp->rpc_ops = &nfs_v4_clientops; 1041 clp->rpc_ops = &nfs_v4_clientops;
1140 1042
1141 xprt = xprt_create_proto(proto, &server->addr, timeparms); 1043 err = nfs_create_rpc_client(clp, proto, timeo, retrans, flavor);
1142 if (IS_ERR(xprt)) { 1044 if (err < 0)
1143 err = PTR_ERR(xprt);
1144 dprintk("%s: cannot create RPC transport. Error = %d\n",
1145 __FUNCTION__, err);
1146 goto client_init_error; 1045 goto client_init_error;
1147 } 1046
1148 /* Bind to a reserved port! */
1149 xprt->resvport = 1;
1150 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
1151 clp->cl_nfsversion, flavor);
1152 if (IS_ERR(clnt)) {
1153 err = PTR_ERR(clnt);
1154 dprintk("%s: cannot create RPC client. Error = %d\n",
1155 __FUNCTION__, err);
1156 goto client_init_error;
1157 }
1158 clnt->cl_intr = 1;
1159 clnt->cl_softrtry = 1;
1160 clp->cl_rpcclient = clnt;
1161 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr)); 1047 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
1162 err = nfs_idmap_new(clp); 1048 err = nfs_idmap_new(clp);
1163 if (err < 0) { 1049 if (err < 0) {
@@ -1205,7 +1091,6 @@ client_init_error:
1205static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent) 1091static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent)
1206{ 1092{
1207 struct nfs_server *server; 1093 struct nfs_server *server;
1208 struct rpc_timeout timeparms;
1209 rpc_authflavor_t authflavour; 1094 rpc_authflavor_t authflavour;
1210 int err = -EIO; 1095 int err = -EIO;
1211 1096
@@ -1224,11 +1109,6 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1224 server->acdirmin = data->acdirmin*HZ; 1109 server->acdirmin = data->acdirmin*HZ;
1225 server->acdirmax = data->acdirmax*HZ; 1110 server->acdirmax = data->acdirmax*HZ;
1226 1111
1227 nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
1228
1229 server->retrans_timeo = timeparms.to_initval;
1230 server->retrans_count = timeparms.to_retries;
1231
1232 /* Now create transport and client */ 1112 /* Now create transport and client */
1233 authflavour = RPC_AUTH_UNIX; 1113 authflavour = RPC_AUTH_UNIX;
1234 if (data->auth_flavourlen != 0) { 1114 if (data->auth_flavourlen != 0) {
@@ -1244,7 +1124,8 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
1244 } 1124 }
1245 } 1125 }
1246 1126
1247 server->client = nfs4_create_client(server, &timeparms, data->proto, authflavour); 1127 server->client = nfs4_create_client(server, data->timeo, data->retrans,
1128 data->proto, authflavour);
1248 if (IS_ERR(server->client)) { 1129 if (IS_ERR(server->client)) {
1249 err = PTR_ERR(server->client); 1130 err = PTR_ERR(server->client);
1250 dprintk("%s: cannot create RPC client. Error = %d\n", 1131 dprintk("%s: cannot create RPC client. Error = %d\n",
@@ -1318,7 +1199,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
1318 return -ENOMEM; 1199 return -ENOMEM;
1319 /* Zero out the NFS state stuff */ 1200 /* Zero out the NFS state stuff */
1320 init_nfsv4_state(server); 1201 init_nfsv4_state(server);
1321 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL); 1202 server->client = server->client_acl = ERR_PTR(-EINVAL);
1322 1203
1323 p = nfs_copy_user_string(NULL, &data->hostname, 256); 1204 p = nfs_copy_user_string(NULL, &data->hostname, 256);
1324 if (IS_ERR(p)) 1205 if (IS_ERR(p))
@@ -1489,7 +1370,6 @@ err:
1489static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data) 1370static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data)
1490{ 1371{
1491 struct nfs_server *server = NFS_SB(sb); 1372 struct nfs_server *server = NFS_SB(sb);
1492 struct rpc_timeout timeparms;
1493 int proto, timeo, retrans; 1373 int proto, timeo, retrans;
1494 void *err; 1374 void *err;
1495 1375
@@ -1498,11 +1378,11 @@ static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nf
1498 set the timeouts and retries to low values */ 1378 set the timeouts and retries to low values */
1499 timeo = 2; 1379 timeo = 2;
1500 retrans = 1; 1380 retrans = 1;
1501 nfs_init_timeout_values(&timeparms, proto, timeo, retrans);
1502 1381
1503 nfs_put_client(server->nfs_client); 1382 nfs_put_client(server->nfs_client);
1504 server->nfs_client = NULL; 1383 server->nfs_client = NULL;
1505 server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor); 1384 server->client = nfs4_create_client(server, timeo, retrans, proto,
1385 data->authflavor);
1506 if (IS_ERR((err = server->client))) 1386 if (IS_ERR((err = server->client)))
1507 goto out_err; 1387 goto out_err;
1508 1388