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.c882
1 files changed, 606 insertions, 276 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 614efeed5437..1b94e3650f5c 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -47,6 +47,7 @@
47#include <linux/inet.h> 47#include <linux/inet.h>
48#include <linux/in6.h> 48#include <linux/in6.h>
49#include <net/ipv6.h> 49#include <net/ipv6.h>
50#include <linux/netdevice.h>
50#include <linux/nfs_xdr.h> 51#include <linux/nfs_xdr.h>
51#include <linux/magic.h> 52#include <linux/magic.h>
52#include <linux/parser.h> 53#include <linux/parser.h>
@@ -65,7 +66,6 @@
65enum { 66enum {
66 /* Mount options that take no arguments */ 67 /* Mount options that take no arguments */
67 Opt_soft, Opt_hard, 68 Opt_soft, Opt_hard,
68 Opt_intr, Opt_nointr,
69 Opt_posix, Opt_noposix, 69 Opt_posix, Opt_noposix,
70 Opt_cto, Opt_nocto, 70 Opt_cto, Opt_nocto,
71 Opt_ac, Opt_noac, 71 Opt_ac, Opt_noac,
@@ -92,8 +92,8 @@ enum {
92 Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost, 92 Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
93 Opt_addr, Opt_mountaddr, Opt_clientaddr, 93 Opt_addr, Opt_mountaddr, Opt_clientaddr,
94 94
95 /* Mount options that are ignored */ 95 /* Special mount options */
96 Opt_userspace, Opt_deprecated, 96 Opt_userspace, Opt_deprecated, Opt_sloppy,
97 97
98 Opt_err 98 Opt_err
99}; 99};
@@ -101,10 +101,14 @@ enum {
101static match_table_t nfs_mount_option_tokens = { 101static match_table_t nfs_mount_option_tokens = {
102 { Opt_userspace, "bg" }, 102 { Opt_userspace, "bg" },
103 { Opt_userspace, "fg" }, 103 { Opt_userspace, "fg" },
104 { Opt_userspace, "retry=%s" },
105
106 { Opt_sloppy, "sloppy" },
107
104 { Opt_soft, "soft" }, 108 { Opt_soft, "soft" },
105 { Opt_hard, "hard" }, 109 { Opt_hard, "hard" },
106 { Opt_intr, "intr" }, 110 { Opt_deprecated, "intr" },
107 { Opt_nointr, "nointr" }, 111 { Opt_deprecated, "nointr" },
108 { Opt_posix, "posix" }, 112 { Opt_posix, "posix" },
109 { Opt_noposix, "noposix" }, 113 { Opt_noposix, "noposix" },
110 { Opt_cto, "cto" }, 114 { Opt_cto, "cto" },
@@ -136,7 +140,6 @@ static match_table_t nfs_mount_option_tokens = {
136 { Opt_acdirmin, "acdirmin=%u" }, 140 { Opt_acdirmin, "acdirmin=%u" },
137 { Opt_acdirmax, "acdirmax=%u" }, 141 { Opt_acdirmax, "acdirmax=%u" },
138 { Opt_actimeo, "actimeo=%u" }, 142 { Opt_actimeo, "actimeo=%u" },
139 { Opt_userspace, "retry=%u" },
140 { Opt_namelen, "namlen=%u" }, 143 { Opt_namelen, "namlen=%u" },
141 { Opt_mountport, "mountport=%u" }, 144 { Opt_mountport, "mountport=%u" },
142 { Opt_mountvers, "mountvers=%u" }, 145 { Opt_mountvers, "mountvers=%u" },
@@ -207,6 +210,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type,
207 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt); 210 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
208static void nfs_kill_super(struct super_block *); 211static void nfs_kill_super(struct super_block *);
209static void nfs_put_super(struct super_block *); 212static void nfs_put_super(struct super_block *);
213static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
210 214
211static struct file_system_type nfs_fs_type = { 215static struct file_system_type nfs_fs_type = {
212 .owner = THIS_MODULE, 216 .owner = THIS_MODULE,
@@ -234,6 +238,7 @@ static const struct super_operations nfs_sops = {
234 .umount_begin = nfs_umount_begin, 238 .umount_begin = nfs_umount_begin,
235 .show_options = nfs_show_options, 239 .show_options = nfs_show_options,
236 .show_stats = nfs_show_stats, 240 .show_stats = nfs_show_stats,
241 .remount_fs = nfs_remount,
237}; 242};
238 243
239#ifdef CONFIG_NFS_V4 244#ifdef CONFIG_NFS_V4
@@ -278,6 +283,7 @@ static const struct super_operations nfs4_sops = {
278 .umount_begin = nfs_umount_begin, 283 .umount_begin = nfs_umount_begin,
279 .show_options = nfs_show_options, 284 .show_options = nfs_show_options,
280 .show_stats = nfs_show_stats, 285 .show_stats = nfs_show_stats,
286 .remount_fs = nfs_remount,
281}; 287};
282#endif 288#endif
283 289
@@ -368,8 +374,6 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
368 }; 374 };
369 int error; 375 int error;
370 376
371 lock_kernel();
372
373 error = server->nfs_client->rpc_ops->statfs(server, fh, &res); 377 error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
374 if (error < 0) 378 if (error < 0)
375 goto out_err; 379 goto out_err;
@@ -401,12 +405,10 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
401 405
402 buf->f_namelen = server->namelen; 406 buf->f_namelen = server->namelen;
403 407
404 unlock_kernel();
405 return 0; 408 return 0;
406 409
407 out_err: 410 out_err:
408 dprintk("%s: statfs error = %d\n", __func__, -error); 411 dprintk("%s: statfs error = %d\n", __func__, -error);
409 unlock_kernel();
410 return error; 412 return error;
411} 413}
412 414
@@ -514,13 +516,13 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
514 if (nfss->bsize != 0) 516 if (nfss->bsize != 0)
515 seq_printf(m, ",bsize=%u", nfss->bsize); 517 seq_printf(m, ",bsize=%u", nfss->bsize);
516 seq_printf(m, ",namlen=%u", nfss->namelen); 518 seq_printf(m, ",namlen=%u", nfss->namelen);
517 if (nfss->acregmin != 3*HZ || showdefaults) 519 if (nfss->acregmin != NFS_DEF_ACREGMIN*HZ || showdefaults)
518 seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ); 520 seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ);
519 if (nfss->acregmax != 60*HZ || showdefaults) 521 if (nfss->acregmax != NFS_DEF_ACREGMAX*HZ || showdefaults)
520 seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ); 522 seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ);
521 if (nfss->acdirmin != 30*HZ || showdefaults) 523 if (nfss->acdirmin != NFS_DEF_ACDIRMIN*HZ || showdefaults)
522 seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ); 524 seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ);
523 if (nfss->acdirmax != 60*HZ || showdefaults) 525 if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults)
524 seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ); 526 seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ);
525 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { 527 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
526 if (nfss->flags & nfs_infop->flag) 528 if (nfss->flags & nfs_infop->flag)
@@ -702,49 +704,233 @@ static int nfs_verify_server_address(struct sockaddr *addr)
702 return 0; 704 return 0;
703} 705}
704 706
707static void nfs_parse_ipv4_address(char *string, size_t str_len,
708 struct sockaddr *sap, size_t *addr_len)
709{
710 struct sockaddr_in *sin = (struct sockaddr_in *)sap;
711 u8 *addr = (u8 *)&sin->sin_addr.s_addr;
712
713 if (str_len <= INET_ADDRSTRLEN) {
714 dfprintk(MOUNT, "NFS: parsing IPv4 address %*s\n",
715 (int)str_len, string);
716
717 sin->sin_family = AF_INET;
718 *addr_len = sizeof(*sin);
719 if (in4_pton(string, str_len, addr, '\0', NULL))
720 return;
721 }
722
723 sap->sa_family = AF_UNSPEC;
724 *addr_len = 0;
725}
726
727#define IPV6_SCOPE_DELIMITER '%'
728
729#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
730static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
731 const char *delim,
732 struct sockaddr_in6 *sin6)
733{
734 char *p;
735 size_t len;
736
737 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
738 return ;
739 if (*delim != IPV6_SCOPE_DELIMITER)
740 return;
741
742 len = (string + str_len) - delim - 1;
743 p = kstrndup(delim + 1, len, GFP_KERNEL);
744 if (p) {
745 unsigned long scope_id = 0;
746 struct net_device *dev;
747
748 dev = dev_get_by_name(&init_net, p);
749 if (dev != NULL) {
750 scope_id = dev->ifindex;
751 dev_put(dev);
752 } else {
753 /* scope_id is set to zero on error */
754 strict_strtoul(p, 10, &scope_id);
755 }
756
757 kfree(p);
758 sin6->sin6_scope_id = scope_id;
759 dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id);
760 }
761}
762
763static void nfs_parse_ipv6_address(char *string, size_t str_len,
764 struct sockaddr *sap, size_t *addr_len)
765{
766 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
767 u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
768 const char *delim;
769
770 if (str_len <= INET6_ADDRSTRLEN) {
771 dfprintk(MOUNT, "NFS: parsing IPv6 address %*s\n",
772 (int)str_len, string);
773
774 sin6->sin6_family = AF_INET6;
775 *addr_len = sizeof(*sin6);
776 if (in6_pton(string, str_len, addr, IPV6_SCOPE_DELIMITER, &delim)) {
777 nfs_parse_ipv6_scope_id(string, str_len, delim, sin6);
778 return;
779 }
780 }
781
782 sap->sa_family = AF_UNSPEC;
783 *addr_len = 0;
784}
785#else
786static void nfs_parse_ipv6_address(char *string, size_t str_len,
787 struct sockaddr *sap, size_t *addr_len)
788{
789 sap->sa_family = AF_UNSPEC;
790 *addr_len = 0;
791}
792#endif
793
705/* 794/*
706 * Parse string addresses passed in via a mount option, 795 * Construct a sockaddr based on the contents of a string that contains
707 * and construct a sockaddr based on the result. 796 * an IP address in presentation format.
708 * 797 *
709 * If address parsing fails, set the sockaddr's address 798 * If there is a problem constructing the new sockaddr, set the address
710 * family to AF_UNSPEC to force nfs_verify_server_address() 799 * family to AF_UNSPEC.
711 * to punt the mount.
712 */ 800 */
713static void nfs_parse_server_address(char *value, 801static void nfs_parse_ip_address(char *string, size_t str_len,
714 struct sockaddr *sap, 802 struct sockaddr *sap, size_t *addr_len)
715 size_t *len)
716{ 803{
717 if (strchr(value, ':')) { 804 unsigned int i, colons;
718 struct sockaddr_in6 *ap = (struct sockaddr_in6 *)sap;
719 u8 *addr = (u8 *)&ap->sin6_addr.in6_u;
720 805
721 ap->sin6_family = AF_INET6; 806 colons = 0;
722 *len = sizeof(*ap); 807 for (i = 0; i < str_len; i++)
723 if (in6_pton(value, -1, addr, '\0', NULL)) 808 if (string[i] == ':')
724 return; 809 colons++;
725 } else { 810
726 struct sockaddr_in *ap = (struct sockaddr_in *)sap; 811 if (colons >= 2)
727 u8 *addr = (u8 *)&ap->sin_addr.s_addr; 812 nfs_parse_ipv6_address(string, str_len, sap, addr_len);
813 else
814 nfs_parse_ipv4_address(string, str_len, sap, addr_len);
815}
816
817/*
818 * Sanity check the NFS transport protocol.
819 *
820 */
821static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt)
822{
823 switch (mnt->nfs_server.protocol) {
824 case XPRT_TRANSPORT_UDP:
825 case XPRT_TRANSPORT_TCP:
826 case XPRT_TRANSPORT_RDMA:
827 break;
828 default:
829 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
830 }
831}
832
833/*
834 * For text based NFSv2/v3 mounts, the mount protocol transport default
835 * settings should depend upon the specified NFS transport.
836 */
837static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt)
838{
839 nfs_validate_transport_protocol(mnt);
728 840
729 ap->sin_family = AF_INET; 841 if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP ||
730 *len = sizeof(*ap); 842 mnt->mount_server.protocol == XPRT_TRANSPORT_TCP)
731 if (in4_pton(value, -1, addr, '\0', NULL))
732 return; 843 return;
844 switch (mnt->nfs_server.protocol) {
845 case XPRT_TRANSPORT_UDP:
846 mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
847 break;
848 case XPRT_TRANSPORT_TCP:
849 case XPRT_TRANSPORT_RDMA:
850 mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
733 } 851 }
852}
734 853
735 sap->sa_family = AF_UNSPEC; 854/*
736 *len = 0; 855 * Parse the value of the 'sec=' option.
856 *
857 * The flavor_len setting is for v4 mounts.
858 */
859static int nfs_parse_security_flavors(char *value,
860 struct nfs_parsed_mount_data *mnt)
861{
862 substring_t args[MAX_OPT_ARGS];
863
864 dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value);
865
866 switch (match_token(value, nfs_secflavor_tokens, args)) {
867 case Opt_sec_none:
868 mnt->auth_flavor_len = 0;
869 mnt->auth_flavors[0] = RPC_AUTH_NULL;
870 break;
871 case Opt_sec_sys:
872 mnt->auth_flavor_len = 0;
873 mnt->auth_flavors[0] = RPC_AUTH_UNIX;
874 break;
875 case Opt_sec_krb5:
876 mnt->auth_flavor_len = 1;
877 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5;
878 break;
879 case Opt_sec_krb5i:
880 mnt->auth_flavor_len = 1;
881 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I;
882 break;
883 case Opt_sec_krb5p:
884 mnt->auth_flavor_len = 1;
885 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P;
886 break;
887 case Opt_sec_lkey:
888 mnt->auth_flavor_len = 1;
889 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY;
890 break;
891 case Opt_sec_lkeyi:
892 mnt->auth_flavor_len = 1;
893 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI;
894 break;
895 case Opt_sec_lkeyp:
896 mnt->auth_flavor_len = 1;
897 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP;
898 break;
899 case Opt_sec_spkm:
900 mnt->auth_flavor_len = 1;
901 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM;
902 break;
903 case Opt_sec_spkmi:
904 mnt->auth_flavor_len = 1;
905 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI;
906 break;
907 case Opt_sec_spkmp:
908 mnt->auth_flavor_len = 1;
909 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP;
910 break;
911 default:
912 return 0;
913 }
914
915 return 1;
916}
917
918static void nfs_parse_invalid_value(const char *option)
919{
920 dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option);
737} 921}
738 922
739/* 923/*
740 * Error-check and convert a string of mount options from user space into 924 * Error-check and convert a string of mount options from user space into
741 * a data structure 925 * a data structure. The whole mount string is processed; bad options are
926 * skipped as they are encountered. If there were no errors, return 1;
927 * otherwise return 0 (zero).
742 */ 928 */
743static int nfs_parse_mount_options(char *raw, 929static int nfs_parse_mount_options(char *raw,
744 struct nfs_parsed_mount_data *mnt) 930 struct nfs_parsed_mount_data *mnt)
745{ 931{
746 char *p, *string, *secdata; 932 char *p, *string, *secdata;
747 int rc; 933 int rc, sloppy = 0, errors = 0;
748 934
749 if (!raw) { 935 if (!raw) {
750 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 936 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -777,15 +963,16 @@ static int nfs_parse_mount_options(char *raw,
777 963
778 token = match_token(p, nfs_mount_option_tokens, args); 964 token = match_token(p, nfs_mount_option_tokens, args);
779 switch (token) { 965 switch (token) {
966
967 /*
968 * boolean options: foo/nofoo
969 */
780 case Opt_soft: 970 case Opt_soft:
781 mnt->flags |= NFS_MOUNT_SOFT; 971 mnt->flags |= NFS_MOUNT_SOFT;
782 break; 972 break;
783 case Opt_hard: 973 case Opt_hard:
784 mnt->flags &= ~NFS_MOUNT_SOFT; 974 mnt->flags &= ~NFS_MOUNT_SOFT;
785 break; 975 break;
786 case Opt_intr:
787 case Opt_nointr:
788 break;
789 case Opt_posix: 976 case Opt_posix:
790 mnt->flags |= NFS_MOUNT_POSIX; 977 mnt->flags |= NFS_MOUNT_POSIX;
791 break; 978 break;
@@ -819,20 +1006,14 @@ static int nfs_parse_mount_options(char *raw,
819 case Opt_udp: 1006 case Opt_udp:
820 mnt->flags &= ~NFS_MOUNT_TCP; 1007 mnt->flags &= ~NFS_MOUNT_TCP;
821 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1008 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
822 mnt->timeo = 7;
823 mnt->retrans = 5;
824 break; 1009 break;
825 case Opt_tcp: 1010 case Opt_tcp:
826 mnt->flags |= NFS_MOUNT_TCP; 1011 mnt->flags |= NFS_MOUNT_TCP;
827 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1012 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
828 mnt->timeo = 600;
829 mnt->retrans = 2;
830 break; 1013 break;
831 case Opt_rdma: 1014 case Opt_rdma:
832 mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */ 1015 mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */
833 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1016 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
834 mnt->timeo = 600;
835 mnt->retrans = 2;
836 break; 1017 break;
837 case Opt_acl: 1018 case Opt_acl:
838 mnt->flags &= ~NFS_MOUNT_NOACL; 1019 mnt->flags &= ~NFS_MOUNT_NOACL;
@@ -853,165 +1034,144 @@ static int nfs_parse_mount_options(char *raw,
853 mnt->flags |= NFS_MOUNT_UNSHARED; 1034 mnt->flags |= NFS_MOUNT_UNSHARED;
854 break; 1035 break;
855 1036
1037 /*
1038 * options that take numeric values
1039 */
856 case Opt_port: 1040 case Opt_port:
857 if (match_int(args, &option)) 1041 if (match_int(args, &option) ||
858 return 0; 1042 option < 0 || option > USHORT_MAX) {
859 if (option < 0 || option > 65535) 1043 errors++;
860 return 0; 1044 nfs_parse_invalid_value("port");
861 mnt->nfs_server.port = option; 1045 } else
1046 mnt->nfs_server.port = option;
862 break; 1047 break;
863 case Opt_rsize: 1048 case Opt_rsize:
864 if (match_int(args, &mnt->rsize)) 1049 if (match_int(args, &option) || option < 0) {
865 return 0; 1050 errors++;
1051 nfs_parse_invalid_value("rsize");
1052 } else
1053 mnt->rsize = option;
866 break; 1054 break;
867 case Opt_wsize: 1055 case Opt_wsize:
868 if (match_int(args, &mnt->wsize)) 1056 if (match_int(args, &option) || option < 0) {
869 return 0; 1057 errors++;
1058 nfs_parse_invalid_value("wsize");
1059 } else
1060 mnt->wsize = option;
870 break; 1061 break;
871 case Opt_bsize: 1062 case Opt_bsize:
872 if (match_int(args, &option)) 1063 if (match_int(args, &option) || option < 0) {
873 return 0; 1064 errors++;
874 if (option < 0) 1065 nfs_parse_invalid_value("bsize");
875 return 0; 1066 } else
876 mnt->bsize = option; 1067 mnt->bsize = option;
877 break; 1068 break;
878 case Opt_timeo: 1069 case Opt_timeo:
879 if (match_int(args, &mnt->timeo)) 1070 if (match_int(args, &option) || option <= 0) {
880 return 0; 1071 errors++;
1072 nfs_parse_invalid_value("timeo");
1073 } else
1074 mnt->timeo = option;
881 break; 1075 break;
882 case Opt_retrans: 1076 case Opt_retrans:
883 if (match_int(args, &mnt->retrans)) 1077 if (match_int(args, &option) || option <= 0) {
884 return 0; 1078 errors++;
1079 nfs_parse_invalid_value("retrans");
1080 } else
1081 mnt->retrans = option;
885 break; 1082 break;
886 case Opt_acregmin: 1083 case Opt_acregmin:
887 if (match_int(args, &mnt->acregmin)) 1084 if (match_int(args, &option) || option < 0) {
888 return 0; 1085 errors++;
1086 nfs_parse_invalid_value("acregmin");
1087 } else
1088 mnt->acregmin = option;
889 break; 1089 break;
890 case Opt_acregmax: 1090 case Opt_acregmax:
891 if (match_int(args, &mnt->acregmax)) 1091 if (match_int(args, &option) || option < 0) {
892 return 0; 1092 errors++;
1093 nfs_parse_invalid_value("acregmax");
1094 } else
1095 mnt->acregmax = option;
893 break; 1096 break;
894 case Opt_acdirmin: 1097 case Opt_acdirmin:
895 if (match_int(args, &mnt->acdirmin)) 1098 if (match_int(args, &option) || option < 0) {
896 return 0; 1099 errors++;
1100 nfs_parse_invalid_value("acdirmin");
1101 } else
1102 mnt->acdirmin = option;
897 break; 1103 break;
898 case Opt_acdirmax: 1104 case Opt_acdirmax:
899 if (match_int(args, &mnt->acdirmax)) 1105 if (match_int(args, &option) || option < 0) {
900 return 0; 1106 errors++;
1107 nfs_parse_invalid_value("acdirmax");
1108 } else
1109 mnt->acdirmax = option;
901 break; 1110 break;
902 case Opt_actimeo: 1111 case Opt_actimeo:
903 if (match_int(args, &option)) 1112 if (match_int(args, &option) || option < 0) {
904 return 0; 1113 errors++;
905 if (option < 0) 1114 nfs_parse_invalid_value("actimeo");
906 return 0; 1115 } else
907 mnt->acregmin = 1116 mnt->acregmin = mnt->acregmax =
908 mnt->acregmax = 1117 mnt->acdirmin = mnt->acdirmax = option;
909 mnt->acdirmin =
910 mnt->acdirmax = option;
911 break; 1118 break;
912 case Opt_namelen: 1119 case Opt_namelen:
913 if (match_int(args, &mnt->namlen)) 1120 if (match_int(args, &option) || option < 0) {
914 return 0; 1121 errors++;
1122 nfs_parse_invalid_value("namlen");
1123 } else
1124 mnt->namlen = option;
915 break; 1125 break;
916 case Opt_mountport: 1126 case Opt_mountport:
917 if (match_int(args, &option)) 1127 if (match_int(args, &option) ||
918 return 0; 1128 option < 0 || option > USHORT_MAX) {
919 if (option < 0 || option > 65535) 1129 errors++;
920 return 0; 1130 nfs_parse_invalid_value("mountport");
921 mnt->mount_server.port = option; 1131 } else
1132 mnt->mount_server.port = option;
922 break; 1133 break;
923 case Opt_mountvers: 1134 case Opt_mountvers:
924 if (match_int(args, &option)) 1135 if (match_int(args, &option) ||
925 return 0; 1136 option < NFS_MNT_VERSION ||
926 if (option < 0) 1137 option > NFS_MNT3_VERSION) {
927 return 0; 1138 errors++;
928 mnt->mount_server.version = option; 1139 nfs_parse_invalid_value("mountvers");
1140 } else
1141 mnt->mount_server.version = option;
929 break; 1142 break;
930 case Opt_nfsvers: 1143 case Opt_nfsvers:
931 if (match_int(args, &option)) 1144 if (match_int(args, &option)) {
932 return 0; 1145 errors++;
1146 nfs_parse_invalid_value("nfsvers");
1147 break;
1148 }
933 switch (option) { 1149 switch (option) {
934 case 2: 1150 case NFS2_VERSION:
935 mnt->flags &= ~NFS_MOUNT_VER3; 1151 mnt->flags &= ~NFS_MOUNT_VER3;
936 break; 1152 break;
937 case 3: 1153 case NFS3_VERSION:
938 mnt->flags |= NFS_MOUNT_VER3; 1154 mnt->flags |= NFS_MOUNT_VER3;
939 break; 1155 break;
940 default: 1156 default:
941 goto out_unrec_vers; 1157 errors++;
1158 nfs_parse_invalid_value("nfsvers");
942 } 1159 }
943 break; 1160 break;
944 1161
1162 /*
1163 * options that take text values
1164 */
945 case Opt_sec: 1165 case Opt_sec:
946 string = match_strdup(args); 1166 string = match_strdup(args);
947 if (string == NULL) 1167 if (string == NULL)
948 goto out_nomem; 1168 goto out_nomem;
949 token = match_token(string, nfs_secflavor_tokens, args); 1169 rc = nfs_parse_security_flavors(string, mnt);
950 kfree(string); 1170 kfree(string);
951 1171 if (!rc) {
952 /* 1172 errors++;
953 * The flags setting is for v2/v3. The flavor_len 1173 dfprintk(MOUNT, "NFS: unrecognized "
954 * setting is for v4. v2/v3 also need to know the 1174 "security flavor\n");
955 * difference between NULL and UNIX.
956 */
957 switch (token) {
958 case Opt_sec_none:
959 mnt->flags &= ~NFS_MOUNT_SECFLAVOUR;
960 mnt->auth_flavor_len = 0;
961 mnt->auth_flavors[0] = RPC_AUTH_NULL;
962 break;
963 case Opt_sec_sys:
964 mnt->flags &= ~NFS_MOUNT_SECFLAVOUR;
965 mnt->auth_flavor_len = 0;
966 mnt->auth_flavors[0] = RPC_AUTH_UNIX;
967 break;
968 case Opt_sec_krb5:
969 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
970 mnt->auth_flavor_len = 1;
971 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5;
972 break;
973 case Opt_sec_krb5i:
974 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
975 mnt->auth_flavor_len = 1;
976 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I;
977 break;
978 case Opt_sec_krb5p:
979 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
980 mnt->auth_flavor_len = 1;
981 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P;
982 break;
983 case Opt_sec_lkey:
984 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
985 mnt->auth_flavor_len = 1;
986 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY;
987 break;
988 case Opt_sec_lkeyi:
989 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
990 mnt->auth_flavor_len = 1;
991 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI;
992 break;
993 case Opt_sec_lkeyp:
994 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
995 mnt->auth_flavor_len = 1;
996 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP;
997 break;
998 case Opt_sec_spkm:
999 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
1000 mnt->auth_flavor_len = 1;
1001 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM;
1002 break;
1003 case Opt_sec_spkmi:
1004 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
1005 mnt->auth_flavor_len = 1;
1006 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI;
1007 break;
1008 case Opt_sec_spkmp:
1009 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
1010 mnt->auth_flavor_len = 1;
1011 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP;
1012 break;
1013 default:
1014 goto out_unrec_sec;
1015 } 1175 }
1016 break; 1176 break;
1017 case Opt_proto: 1177 case Opt_proto:
@@ -1026,24 +1186,20 @@ static int nfs_parse_mount_options(char *raw,
1026 case Opt_xprt_udp: 1186 case Opt_xprt_udp:
1027 mnt->flags &= ~NFS_MOUNT_TCP; 1187 mnt->flags &= ~NFS_MOUNT_TCP;
1028 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1188 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1029 mnt->timeo = 7;
1030 mnt->retrans = 5;
1031 break; 1189 break;
1032 case Opt_xprt_tcp: 1190 case Opt_xprt_tcp:
1033 mnt->flags |= NFS_MOUNT_TCP; 1191 mnt->flags |= NFS_MOUNT_TCP;
1034 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1192 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1035 mnt->timeo = 600;
1036 mnt->retrans = 2;
1037 break; 1193 break;
1038 case Opt_xprt_rdma: 1194 case Opt_xprt_rdma:
1039 /* vector side protocols to TCP */ 1195 /* vector side protocols to TCP */
1040 mnt->flags |= NFS_MOUNT_TCP; 1196 mnt->flags |= NFS_MOUNT_TCP;
1041 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1197 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
1042 mnt->timeo = 600;
1043 mnt->retrans = 2;
1044 break; 1198 break;
1045 default: 1199 default:
1046 goto out_unrec_xprt; 1200 errors++;
1201 dfprintk(MOUNT, "NFS: unrecognized "
1202 "transport protocol\n");
1047 } 1203 }
1048 break; 1204 break;
1049 case Opt_mountproto: 1205 case Opt_mountproto:
@@ -1063,16 +1219,19 @@ static int nfs_parse_mount_options(char *raw,
1063 break; 1219 break;
1064 case Opt_xprt_rdma: /* not used for side protocols */ 1220 case Opt_xprt_rdma: /* not used for side protocols */
1065 default: 1221 default:
1066 goto out_unrec_xprt; 1222 errors++;
1223 dfprintk(MOUNT, "NFS: unrecognized "
1224 "transport protocol\n");
1067 } 1225 }
1068 break; 1226 break;
1069 case Opt_addr: 1227 case Opt_addr:
1070 string = match_strdup(args); 1228 string = match_strdup(args);
1071 if (string == NULL) 1229 if (string == NULL)
1072 goto out_nomem; 1230 goto out_nomem;
1073 nfs_parse_server_address(string, (struct sockaddr *) 1231 nfs_parse_ip_address(string, strlen(string),
1074 &mnt->nfs_server.address, 1232 (struct sockaddr *)
1075 &mnt->nfs_server.addrlen); 1233 &mnt->nfs_server.address,
1234 &mnt->nfs_server.addrlen);
1076 kfree(string); 1235 kfree(string);
1077 break; 1236 break;
1078 case Opt_clientaddr: 1237 case Opt_clientaddr:
@@ -1093,24 +1252,33 @@ static int nfs_parse_mount_options(char *raw,
1093 string = match_strdup(args); 1252 string = match_strdup(args);
1094 if (string == NULL) 1253 if (string == NULL)
1095 goto out_nomem; 1254 goto out_nomem;
1096 nfs_parse_server_address(string, (struct sockaddr *) 1255 nfs_parse_ip_address(string, strlen(string),
1097 &mnt->mount_server.address, 1256 (struct sockaddr *)
1098 &mnt->mount_server.addrlen); 1257 &mnt->mount_server.address,
1258 &mnt->mount_server.addrlen);
1099 kfree(string); 1259 kfree(string);
1100 break; 1260 break;
1101 1261
1262 /*
1263 * Special options
1264 */
1265 case Opt_sloppy:
1266 sloppy = 1;
1267 dfprintk(MOUNT, "NFS: relaxing parsing rules\n");
1268 break;
1102 case Opt_userspace: 1269 case Opt_userspace:
1103 case Opt_deprecated: 1270 case Opt_deprecated:
1271 dfprintk(MOUNT, "NFS: ignoring mount option "
1272 "'%s'\n", p);
1104 break; 1273 break;
1105 1274
1106 default: 1275 default:
1107 goto out_unknown; 1276 errors++;
1277 dfprintk(MOUNT, "NFS: unrecognized mount option "
1278 "'%s'\n", p);
1108 } 1279 }
1109 } 1280 }
1110 1281
1111 nfs_set_port((struct sockaddr *)&mnt->nfs_server.address,
1112 mnt->nfs_server.port);
1113
1114 return 1; 1282 return 1;
1115 1283
1116out_nomem: 1284out_nomem:
@@ -1120,21 +1288,6 @@ out_security_failure:
1120 free_secdata(secdata); 1288 free_secdata(secdata);
1121 printk(KERN_INFO "NFS: security options invalid: %d\n", rc); 1289 printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
1122 return 0; 1290 return 0;
1123out_unrec_vers:
1124 printk(KERN_INFO "NFS: unrecognized NFS version number\n");
1125 return 0;
1126
1127out_unrec_xprt:
1128 printk(KERN_INFO "NFS: unrecognized transport protocol\n");
1129 return 0;
1130
1131out_unrec_sec:
1132 printk(KERN_INFO "NFS: unrecognized security flavor\n");
1133 return 0;
1134
1135out_unknown:
1136 printk(KERN_INFO "NFS: unknown mount option: %s\n", p);
1137 return 0;
1138} 1291}
1139 1292
1140/* 1293/*
@@ -1188,11 +1341,146 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1188 if (status == 0) 1341 if (status == 0)
1189 return 0; 1342 return 0;
1190 1343
1191 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d", 1344 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
1192 hostname, status); 1345 hostname, status);
1193 return status; 1346 return status;
1194} 1347}
1195 1348
1349static int nfs_parse_simple_hostname(const char *dev_name,
1350 char **hostname, size_t maxnamlen,
1351 char **export_path, size_t maxpathlen)
1352{
1353 size_t len;
1354 char *colon, *comma;
1355
1356 colon = strchr(dev_name, ':');
1357 if (colon == NULL)
1358 goto out_bad_devname;
1359
1360 len = colon - dev_name;
1361 if (len > maxnamlen)
1362 goto out_hostname;
1363
1364 /* N.B. caller will free nfs_server.hostname in all cases */
1365 *hostname = kstrndup(dev_name, len, GFP_KERNEL);
1366 if (!*hostname)
1367 goto out_nomem;
1368
1369 /* kill possible hostname list: not supported */
1370 comma = strchr(*hostname, ',');
1371 if (comma != NULL) {
1372 if (comma == *hostname)
1373 goto out_bad_devname;
1374 *comma = '\0';
1375 }
1376
1377 colon++;
1378 len = strlen(colon);
1379 if (len > maxpathlen)
1380 goto out_path;
1381 *export_path = kstrndup(colon, len, GFP_KERNEL);
1382 if (!*export_path)
1383 goto out_nomem;
1384
1385 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path);
1386 return 0;
1387
1388out_bad_devname:
1389 dfprintk(MOUNT, "NFS: device name not in host:path format\n");
1390 return -EINVAL;
1391
1392out_nomem:
1393 dfprintk(MOUNT, "NFS: not enough memory to parse device name\n");
1394 return -ENOMEM;
1395
1396out_hostname:
1397 dfprintk(MOUNT, "NFS: server hostname too long\n");
1398 return -ENAMETOOLONG;
1399
1400out_path:
1401 dfprintk(MOUNT, "NFS: export pathname too long\n");
1402 return -ENAMETOOLONG;
1403}
1404
1405/*
1406 * Hostname has square brackets around it because it contains one or
1407 * more colons. We look for the first closing square bracket, and a
1408 * colon must follow it.
1409 */
1410static int nfs_parse_protected_hostname(const char *dev_name,
1411 char **hostname, size_t maxnamlen,
1412 char **export_path, size_t maxpathlen)
1413{
1414 size_t len;
1415 char *start, *end;
1416
1417 start = (char *)(dev_name + 1);
1418
1419 end = strchr(start, ']');
1420 if (end == NULL)
1421 goto out_bad_devname;
1422 if (*(end + 1) != ':')
1423 goto out_bad_devname;
1424
1425 len = end - start;
1426 if (len > maxnamlen)
1427 goto out_hostname;
1428
1429 /* N.B. caller will free nfs_server.hostname in all cases */
1430 *hostname = kstrndup(start, len, GFP_KERNEL);
1431 if (*hostname == NULL)
1432 goto out_nomem;
1433
1434 end += 2;
1435 len = strlen(end);
1436 if (len > maxpathlen)
1437 goto out_path;
1438 *export_path = kstrndup(end, len, GFP_KERNEL);
1439 if (!*export_path)
1440 goto out_nomem;
1441
1442 return 0;
1443
1444out_bad_devname:
1445 dfprintk(MOUNT, "NFS: device name not in host:path format\n");
1446 return -EINVAL;
1447
1448out_nomem:
1449 dfprintk(MOUNT, "NFS: not enough memory to parse device name\n");
1450 return -ENOMEM;
1451
1452out_hostname:
1453 dfprintk(MOUNT, "NFS: server hostname too long\n");
1454 return -ENAMETOOLONG;
1455
1456out_path:
1457 dfprintk(MOUNT, "NFS: export pathname too long\n");
1458 return -ENAMETOOLONG;
1459}
1460
1461/*
1462 * Split "dev_name" into "hostname:export_path".
1463 *
1464 * The leftmost colon demarks the split between the server's hostname
1465 * and the export path. If the hostname starts with a left square
1466 * bracket, then it may contain colons.
1467 *
1468 * Note: caller frees hostname and export path, even on error.
1469 */
1470static int nfs_parse_devname(const char *dev_name,
1471 char **hostname, size_t maxnamlen,
1472 char **export_path, size_t maxpathlen)
1473{
1474 if (*dev_name == '[')
1475 return nfs_parse_protected_hostname(dev_name,
1476 hostname, maxnamlen,
1477 export_path, maxpathlen);
1478
1479 return nfs_parse_simple_hostname(dev_name,
1480 hostname, maxnamlen,
1481 export_path, maxpathlen);
1482}
1483
1196/* 1484/*
1197 * Validate the NFS2/NFS3 mount data 1485 * Validate the NFS2/NFS3 mount data
1198 * - fills in the mount root filehandle 1486 * - fills in the mount root filehandle
@@ -1222,16 +1510,14 @@ static int nfs_validate_mount_data(void *options,
1222 args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP); 1510 args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
1223 args->rsize = NFS_MAX_FILE_IO_SIZE; 1511 args->rsize = NFS_MAX_FILE_IO_SIZE;
1224 args->wsize = NFS_MAX_FILE_IO_SIZE; 1512 args->wsize = NFS_MAX_FILE_IO_SIZE;
1225 args->timeo = 600; 1513 args->acregmin = NFS_DEF_ACREGMIN;
1226 args->retrans = 2; 1514 args->acregmax = NFS_DEF_ACREGMAX;
1227 args->acregmin = 3; 1515 args->acdirmin = NFS_DEF_ACDIRMIN;
1228 args->acregmax = 60; 1516 args->acdirmax = NFS_DEF_ACDIRMAX;
1229 args->acdirmin = 30;
1230 args->acdirmax = 60;
1231 args->mount_server.port = 0; /* autobind unless user sets port */ 1517 args->mount_server.port = 0; /* autobind unless user sets port */
1232 args->mount_server.protocol = XPRT_TRANSPORT_UDP;
1233 args->nfs_server.port = 0; /* autobind unless user sets port */ 1518 args->nfs_server.port = 0; /* autobind unless user sets port */
1234 args->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1519 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1520 args->auth_flavors[0] = RPC_AUTH_UNIX;
1235 1521
1236 switch (data->version) { 1522 switch (data->version) {
1237 case 1: 1523 case 1:
@@ -1289,7 +1575,9 @@ static int nfs_validate_mount_data(void *options,
1289 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); 1575 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
1290 args->namlen = data->namlen; 1576 args->namlen = data->namlen;
1291 args->bsize = data->bsize; 1577 args->bsize = data->bsize;
1292 args->auth_flavors[0] = data->pseudoflavor; 1578
1579 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1580 args->auth_flavors[0] = data->pseudoflavor;
1293 if (!args->nfs_server.hostname) 1581 if (!args->nfs_server.hostname)
1294 goto out_nomem; 1582 goto out_nomem;
1295 1583
@@ -1321,8 +1609,6 @@ static int nfs_validate_mount_data(void *options,
1321 1609
1322 break; 1610 break;
1323 default: { 1611 default: {
1324 unsigned int len;
1325 char *c;
1326 int status; 1612 int status;
1327 1613
1328 if (nfs_parse_mount_options((char *)options, args) == 0) 1614 if (nfs_parse_mount_options((char *)options, args) == 0)
@@ -1332,21 +1618,22 @@ static int nfs_validate_mount_data(void *options,
1332 &args->nfs_server.address)) 1618 &args->nfs_server.address))
1333 goto out_no_address; 1619 goto out_no_address;
1334 1620
1335 c = strchr(dev_name, ':'); 1621 nfs_set_port((struct sockaddr *)&args->nfs_server.address,
1336 if (c == NULL) 1622 args->nfs_server.port);
1337 return -EINVAL;
1338 len = c - dev_name;
1339 /* N.B. caller will free nfs_server.hostname in all cases */
1340 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
1341 if (!args->nfs_server.hostname)
1342 goto out_nomem;
1343 1623
1344 c++; 1624 nfs_set_mount_transport_protocol(args);
1345 if (strlen(c) > NFS_MAXPATHLEN) 1625
1346 return -ENAMETOOLONG; 1626 status = nfs_parse_devname(dev_name,
1347 args->nfs_server.export_path = c; 1627 &args->nfs_server.hostname,
1628 PAGE_SIZE,
1629 &args->nfs_server.export_path,
1630 NFS_MAXPATHLEN);
1631 if (!status)
1632 status = nfs_try_mount(args, mntfh);
1633
1634 kfree(args->nfs_server.export_path);
1635 args->nfs_server.export_path = NULL;
1348 1636
1349 status = nfs_try_mount(args, mntfh);
1350 if (status) 1637 if (status)
1351 return status; 1638 return status;
1352 1639
@@ -1354,9 +1641,6 @@ static int nfs_validate_mount_data(void *options,
1354 } 1641 }
1355 } 1642 }
1356 1643
1357 if (!(args->flags & NFS_MOUNT_SECFLAVOUR))
1358 args->auth_flavors[0] = RPC_AUTH_UNIX;
1359
1360#ifndef CONFIG_NFS_V3 1644#ifndef CONFIG_NFS_V3
1361 if (args->flags & NFS_MOUNT_VER3) 1645 if (args->flags & NFS_MOUNT_VER3)
1362 goto out_v3_not_compiled; 1646 goto out_v3_not_compiled;
@@ -1396,6 +1680,80 @@ out_invalid_fh:
1396 return -EINVAL; 1680 return -EINVAL;
1397} 1681}
1398 1682
1683static int
1684nfs_compare_remount_data(struct nfs_server *nfss,
1685 struct nfs_parsed_mount_data *data)
1686{
1687 if (data->flags != nfss->flags ||
1688 data->rsize != nfss->rsize ||
1689 data->wsize != nfss->wsize ||
1690 data->retrans != nfss->client->cl_timeout->to_retries ||
1691 data->auth_flavors[0] != nfss->client->cl_auth->au_flavor ||
1692 data->acregmin != nfss->acregmin / HZ ||
1693 data->acregmax != nfss->acregmax / HZ ||
1694 data->acdirmin != nfss->acdirmin / HZ ||
1695 data->acdirmax != nfss->acdirmax / HZ ||
1696 data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
1697 data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
1698 memcmp(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
1699 data->nfs_server.addrlen) != 0)
1700 return -EINVAL;
1701
1702 return 0;
1703}
1704
1705static int
1706nfs_remount(struct super_block *sb, int *flags, char *raw_data)
1707{
1708 int error;
1709 struct nfs_server *nfss = sb->s_fs_info;
1710 struct nfs_parsed_mount_data *data;
1711 struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data;
1712 struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
1713 u32 nfsvers = nfss->nfs_client->rpc_ops->version;
1714
1715 /*
1716 * Userspace mount programs that send binary options generally send
1717 * them populated with default values. We have no way to know which
1718 * ones were explicitly specified. Fall back to legacy behavior and
1719 * just return success.
1720 */
1721 if ((nfsvers == 4 && options4->version == 1) ||
1722 (nfsvers <= 3 && options->version >= 1 &&
1723 options->version <= 6))
1724 return 0;
1725
1726 data = kzalloc(sizeof(*data), GFP_KERNEL);
1727 if (data == NULL)
1728 return -ENOMEM;
1729
1730 /* fill out struct with values from existing mount */
1731 data->flags = nfss->flags;
1732 data->rsize = nfss->rsize;
1733 data->wsize = nfss->wsize;
1734 data->retrans = nfss->client->cl_timeout->to_retries;
1735 data->auth_flavors[0] = nfss->client->cl_auth->au_flavor;
1736 data->acregmin = nfss->acregmin / HZ;
1737 data->acregmax = nfss->acregmax / HZ;
1738 data->acdirmin = nfss->acdirmin / HZ;
1739 data->acdirmax = nfss->acdirmax / HZ;
1740 data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
1741 data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
1742 memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
1743 data->nfs_server.addrlen);
1744
1745 /* overwrite those values with any that were specified */
1746 error = nfs_parse_mount_options((char *)options, data);
1747 if (error < 0)
1748 goto out;
1749
1750 /* compare new mount options with old ones */
1751 error = nfs_compare_remount_data(nfss, data);
1752out:
1753 kfree(data);
1754 return error;
1755}
1756
1399/* 1757/*
1400 * Initialise the common bits of the superblock 1758 * Initialise the common bits of the superblock
1401 */ 1759 */
@@ -1811,14 +2169,13 @@ static int nfs4_validate_mount_data(void *options,
1811 2169
1812 args->rsize = NFS_MAX_FILE_IO_SIZE; 2170 args->rsize = NFS_MAX_FILE_IO_SIZE;
1813 args->wsize = NFS_MAX_FILE_IO_SIZE; 2171 args->wsize = NFS_MAX_FILE_IO_SIZE;
1814 args->timeo = 600; 2172 args->acregmin = NFS_DEF_ACREGMIN;
1815 args->retrans = 2; 2173 args->acregmax = NFS_DEF_ACREGMAX;
1816 args->acregmin = 3; 2174 args->acdirmin = NFS_DEF_ACDIRMIN;
1817 args->acregmax = 60; 2175 args->acdirmax = NFS_DEF_ACDIRMAX;
1818 args->acdirmin = 30;
1819 args->acdirmax = 60;
1820 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ 2176 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
1821 args->nfs_server.protocol = XPRT_TRANSPORT_TCP; 2177 args->auth_flavors[0] = RPC_AUTH_UNIX;
2178 args->auth_flavor_len = 0;
1822 2179
1823 switch (data->version) { 2180 switch (data->version) {
1824 case 1: 2181 case 1:
@@ -1834,18 +2191,13 @@ static int nfs4_validate_mount_data(void *options,
1834 &args->nfs_server.address)) 2191 &args->nfs_server.address))
1835 goto out_no_address; 2192 goto out_no_address;
1836 2193
1837 switch (data->auth_flavourlen) { 2194 if (data->auth_flavourlen) {
1838 case 0: 2195 if (data->auth_flavourlen > 1)
1839 args->auth_flavors[0] = RPC_AUTH_UNIX; 2196 goto out_inval_auth;
1840 break;
1841 case 1:
1842 if (copy_from_user(&args->auth_flavors[0], 2197 if (copy_from_user(&args->auth_flavors[0],
1843 data->auth_flavours, 2198 data->auth_flavours,
1844 sizeof(args->auth_flavors[0]))) 2199 sizeof(args->auth_flavors[0])))
1845 return -EFAULT; 2200 return -EFAULT;
1846 break;
1847 default:
1848 goto out_inval_auth;
1849 } 2201 }
1850 2202
1851 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 2203 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
@@ -1879,10 +2231,11 @@ static int nfs4_validate_mount_data(void *options,
1879 args->acdirmin = data->acdirmin; 2231 args->acdirmin = data->acdirmin;
1880 args->acdirmax = data->acdirmax; 2232 args->acdirmax = data->acdirmax;
1881 args->nfs_server.protocol = data->proto; 2233 args->nfs_server.protocol = data->proto;
2234 nfs_validate_transport_protocol(args);
1882 2235
1883 break; 2236 break;
1884 default: { 2237 default: {
1885 unsigned int len; 2238 int status;
1886 2239
1887 if (nfs_parse_mount_options((char *)options, args) == 0) 2240 if (nfs_parse_mount_options((char *)options, args) == 0)
1888 return -EINVAL; 2241 return -EINVAL;
@@ -1891,44 +2244,25 @@ static int nfs4_validate_mount_data(void *options,
1891 &args->nfs_server.address)) 2244 &args->nfs_server.address))
1892 return -EINVAL; 2245 return -EINVAL;
1893 2246
1894 switch (args->auth_flavor_len) { 2247 nfs_set_port((struct sockaddr *)&args->nfs_server.address,
1895 case 0: 2248 args->nfs_server.port);
1896 args->auth_flavors[0] = RPC_AUTH_UNIX;
1897 break;
1898 case 1:
1899 break;
1900 default:
1901 goto out_inval_auth;
1902 }
1903 2249
1904 /* 2250 nfs_validate_transport_protocol(args);
1905 * Split "dev_name" into "hostname:mntpath".
1906 */
1907 c = strchr(dev_name, ':');
1908 if (c == NULL)
1909 return -EINVAL;
1910 /* while calculating len, pretend ':' is '\0' */
1911 len = c - dev_name;
1912 if (len > NFS4_MAXNAMLEN)
1913 return -ENAMETOOLONG;
1914 /* N.B. caller will free nfs_server.hostname in all cases */
1915 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
1916 if (!args->nfs_server.hostname)
1917 goto out_nomem;
1918
1919 c++; /* step over the ':' */
1920 len = strlen(c);
1921 if (len > NFS4_MAXPATHLEN)
1922 return -ENAMETOOLONG;
1923 args->nfs_server.export_path = kstrndup(c, len, GFP_KERNEL);
1924 if (!args->nfs_server.export_path)
1925 goto out_nomem;
1926 2251
1927 dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path); 2252 if (args->auth_flavor_len > 1)
2253 goto out_inval_auth;
1928 2254
1929 if (args->client_address == NULL) 2255 if (args->client_address == NULL)
1930 goto out_no_client_address; 2256 goto out_no_client_address;
1931 2257
2258 status = nfs_parse_devname(dev_name,
2259 &args->nfs_server.hostname,
2260 NFS4_MAXNAMLEN,
2261 &args->nfs_server.export_path,
2262 NFS4_MAXPATHLEN);
2263 if (status < 0)
2264 return status;
2265
1932 break; 2266 break;
1933 } 2267 }
1934 } 2268 }
@@ -1944,10 +2278,6 @@ out_inval_auth:
1944 data->auth_flavourlen); 2278 data->auth_flavourlen);
1945 return -EINVAL; 2279 return -EINVAL;
1946 2280
1947out_nomem:
1948 dfprintk(MOUNT, "NFS4: not enough memory to handle mount options\n");
1949 return -ENOMEM;
1950
1951out_no_address: 2281out_no_address:
1952 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 2282 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
1953 return -EINVAL; 2283 return -EINVAL;