aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
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