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.c878
1 files changed, 606 insertions, 272 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 614efeed5437..47cf83e917be 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
@@ -514,13 +520,13 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
514 if (nfss->bsize != 0) 520 if (nfss->bsize != 0)
515 seq_printf(m, ",bsize=%u", nfss->bsize); 521 seq_printf(m, ",bsize=%u", nfss->bsize);
516 seq_printf(m, ",namlen=%u", nfss->namelen); 522 seq_printf(m, ",namlen=%u", nfss->namelen);
517 if (nfss->acregmin != 3*HZ || showdefaults) 523 if (nfss->acregmin != NFS_DEF_ACREGMIN*HZ || showdefaults)
518 seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ); 524 seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ);
519 if (nfss->acregmax != 60*HZ || showdefaults) 525 if (nfss->acregmax != NFS_DEF_ACREGMAX*HZ || showdefaults)
520 seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ); 526 seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ);
521 if (nfss->acdirmin != 30*HZ || showdefaults) 527 if (nfss->acdirmin != NFS_DEF_ACDIRMIN*HZ || showdefaults)
522 seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ); 528 seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ);
523 if (nfss->acdirmax != 60*HZ || showdefaults) 529 if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults)
524 seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ); 530 seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ);
525 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { 531 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
526 if (nfss->flags & nfs_infop->flag) 532 if (nfss->flags & nfs_infop->flag)
@@ -702,49 +708,233 @@ static int nfs_verify_server_address(struct sockaddr *addr)
702 return 0; 708 return 0;
703} 709}
704 710
711static void nfs_parse_ipv4_address(char *string, size_t str_len,
712 struct sockaddr *sap, size_t *addr_len)
713{
714 struct sockaddr_in *sin = (struct sockaddr_in *)sap;
715 u8 *addr = (u8 *)&sin->sin_addr.s_addr;
716
717 if (str_len <= INET_ADDRSTRLEN) {
718 dfprintk(MOUNT, "NFS: parsing IPv4 address %*s\n",
719 (int)str_len, string);
720
721 sin->sin_family = AF_INET;
722 *addr_len = sizeof(*sin);
723 if (in4_pton(string, str_len, addr, '\0', NULL))
724 return;
725 }
726
727 sap->sa_family = AF_UNSPEC;
728 *addr_len = 0;
729}
730
731#define IPV6_SCOPE_DELIMITER '%'
732
733#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
734static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
735 const char *delim,
736 struct sockaddr_in6 *sin6)
737{
738 char *p;
739 size_t len;
740
741 if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
742 return ;
743 if (*delim != IPV6_SCOPE_DELIMITER)
744 return;
745
746 len = (string + str_len) - delim - 1;
747 p = kstrndup(delim + 1, len, GFP_KERNEL);
748 if (p) {
749 unsigned long scope_id = 0;
750 struct net_device *dev;
751
752 dev = dev_get_by_name(&init_net, p);
753 if (dev != NULL) {
754 scope_id = dev->ifindex;
755 dev_put(dev);
756 } else {
757 /* scope_id is set to zero on error */
758 strict_strtoul(p, 10, &scope_id);
759 }
760
761 kfree(p);
762 sin6->sin6_scope_id = scope_id;
763 dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id);
764 }
765}
766
767static void nfs_parse_ipv6_address(char *string, size_t str_len,
768 struct sockaddr *sap, size_t *addr_len)
769{
770 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
771 u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
772 const char *delim;
773
774 if (str_len <= INET6_ADDRSTRLEN) {
775 dfprintk(MOUNT, "NFS: parsing IPv6 address %*s\n",
776 (int)str_len, string);
777
778 sin6->sin6_family = AF_INET6;
779 *addr_len = sizeof(*sin6);
780 if (in6_pton(string, str_len, addr, IPV6_SCOPE_DELIMITER, &delim)) {
781 nfs_parse_ipv6_scope_id(string, str_len, delim, sin6);
782 return;
783 }
784 }
785
786 sap->sa_family = AF_UNSPEC;
787 *addr_len = 0;
788}
789#else
790static void nfs_parse_ipv6_address(char *string, size_t str_len,
791 struct sockaddr *sap, size_t *addr_len)
792{
793 sap->sa_family = AF_UNSPEC;
794 *addr_len = 0;
795}
796#endif
797
705/* 798/*
706 * Parse string addresses passed in via a mount option, 799 * Construct a sockaddr based on the contents of a string that contains
707 * and construct a sockaddr based on the result. 800 * an IP address in presentation format.
708 * 801 *
709 * If address parsing fails, set the sockaddr's address 802 * If there is a problem constructing the new sockaddr, set the address
710 * family to AF_UNSPEC to force nfs_verify_server_address() 803 * family to AF_UNSPEC.
711 * to punt the mount.
712 */ 804 */
713static void nfs_parse_server_address(char *value, 805static void nfs_parse_ip_address(char *string, size_t str_len,
714 struct sockaddr *sap, 806 struct sockaddr *sap, size_t *addr_len)
715 size_t *len)
716{ 807{
717 if (strchr(value, ':')) { 808 unsigned int i, colons;
718 struct sockaddr_in6 *ap = (struct sockaddr_in6 *)sap;
719 u8 *addr = (u8 *)&ap->sin6_addr.in6_u;
720 809
721 ap->sin6_family = AF_INET6; 810 colons = 0;
722 *len = sizeof(*ap); 811 for (i = 0; i < str_len; i++)
723 if (in6_pton(value, -1, addr, '\0', NULL)) 812 if (string[i] == ':')
724 return; 813 colons++;
725 } else {
726 struct sockaddr_in *ap = (struct sockaddr_in *)sap;
727 u8 *addr = (u8 *)&ap->sin_addr.s_addr;
728 814
729 ap->sin_family = AF_INET; 815 if (colons >= 2)
730 *len = sizeof(*ap); 816 nfs_parse_ipv6_address(string, str_len, sap, addr_len);
731 if (in4_pton(value, -1, addr, '\0', NULL)) 817 else
818 nfs_parse_ipv4_address(string, str_len, sap, addr_len);
819}
820
821/*
822 * Sanity check the NFS transport protocol.
823 *
824 */
825static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt)
826{
827 switch (mnt->nfs_server.protocol) {
828 case XPRT_TRANSPORT_UDP:
829 case XPRT_TRANSPORT_TCP:
830 case XPRT_TRANSPORT_RDMA:
831 break;
832 default:
833 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
834 }
835}
836
837/*
838 * For text based NFSv2/v3 mounts, the mount protocol transport default
839 * settings should depend upon the specified NFS transport.
840 */
841static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt)
842{
843 nfs_validate_transport_protocol(mnt);
844
845 if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP ||
846 mnt->mount_server.protocol == XPRT_TRANSPORT_TCP)
732 return; 847 return;
848 switch (mnt->nfs_server.protocol) {
849 case XPRT_TRANSPORT_UDP:
850 mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
851 break;
852 case XPRT_TRANSPORT_TCP:
853 case XPRT_TRANSPORT_RDMA:
854 mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
733 } 855 }
856}
734 857
735 sap->sa_family = AF_UNSPEC; 858/*
736 *len = 0; 859 * Parse the value of the 'sec=' option.
860 *
861 * The flavor_len setting is for v4 mounts.
862 */
863static int nfs_parse_security_flavors(char *value,
864 struct nfs_parsed_mount_data *mnt)
865{
866 substring_t args[MAX_OPT_ARGS];
867
868 dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value);
869
870 switch (match_token(value, nfs_secflavor_tokens, args)) {
871 case Opt_sec_none:
872 mnt->auth_flavor_len = 0;
873 mnt->auth_flavors[0] = RPC_AUTH_NULL;
874 break;
875 case Opt_sec_sys:
876 mnt->auth_flavor_len = 0;
877 mnt->auth_flavors[0] = RPC_AUTH_UNIX;
878 break;
879 case Opt_sec_krb5:
880 mnt->auth_flavor_len = 1;
881 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5;
882 break;
883 case Opt_sec_krb5i:
884 mnt->auth_flavor_len = 1;
885 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I;
886 break;
887 case Opt_sec_krb5p:
888 mnt->auth_flavor_len = 1;
889 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P;
890 break;
891 case Opt_sec_lkey:
892 mnt->auth_flavor_len = 1;
893 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY;
894 break;
895 case Opt_sec_lkeyi:
896 mnt->auth_flavor_len = 1;
897 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI;
898 break;
899 case Opt_sec_lkeyp:
900 mnt->auth_flavor_len = 1;
901 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP;
902 break;
903 case Opt_sec_spkm:
904 mnt->auth_flavor_len = 1;
905 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM;
906 break;
907 case Opt_sec_spkmi:
908 mnt->auth_flavor_len = 1;
909 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI;
910 break;
911 case Opt_sec_spkmp:
912 mnt->auth_flavor_len = 1;
913 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP;
914 break;
915 default:
916 return 0;
917 }
918
919 return 1;
920}
921
922static void nfs_parse_invalid_value(const char *option)
923{
924 dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option);
737} 925}
738 926
739/* 927/*
740 * Error-check and convert a string of mount options from user space into 928 * Error-check and convert a string of mount options from user space into
741 * a data structure 929 * a data structure. The whole mount string is processed; bad options are
930 * skipped as they are encountered. If there were no errors, return 1;
931 * otherwise return 0 (zero).
742 */ 932 */
743static int nfs_parse_mount_options(char *raw, 933static int nfs_parse_mount_options(char *raw,
744 struct nfs_parsed_mount_data *mnt) 934 struct nfs_parsed_mount_data *mnt)
745{ 935{
746 char *p, *string, *secdata; 936 char *p, *string, *secdata;
747 int rc; 937 int rc, sloppy = 0, errors = 0;
748 938
749 if (!raw) { 939 if (!raw) {
750 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 940 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -777,15 +967,16 @@ static int nfs_parse_mount_options(char *raw,
777 967
778 token = match_token(p, nfs_mount_option_tokens, args); 968 token = match_token(p, nfs_mount_option_tokens, args);
779 switch (token) { 969 switch (token) {
970
971 /*
972 * boolean options: foo/nofoo
973 */
780 case Opt_soft: 974 case Opt_soft:
781 mnt->flags |= NFS_MOUNT_SOFT; 975 mnt->flags |= NFS_MOUNT_SOFT;
782 break; 976 break;
783 case Opt_hard: 977 case Opt_hard:
784 mnt->flags &= ~NFS_MOUNT_SOFT; 978 mnt->flags &= ~NFS_MOUNT_SOFT;
785 break; 979 break;
786 case Opt_intr:
787 case Opt_nointr:
788 break;
789 case Opt_posix: 980 case Opt_posix:
790 mnt->flags |= NFS_MOUNT_POSIX; 981 mnt->flags |= NFS_MOUNT_POSIX;
791 break; 982 break;
@@ -819,20 +1010,14 @@ static int nfs_parse_mount_options(char *raw,
819 case Opt_udp: 1010 case Opt_udp:
820 mnt->flags &= ~NFS_MOUNT_TCP; 1011 mnt->flags &= ~NFS_MOUNT_TCP;
821 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1012 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
822 mnt->timeo = 7;
823 mnt->retrans = 5;
824 break; 1013 break;
825 case Opt_tcp: 1014 case Opt_tcp:
826 mnt->flags |= NFS_MOUNT_TCP; 1015 mnt->flags |= NFS_MOUNT_TCP;
827 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1016 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
828 mnt->timeo = 600;
829 mnt->retrans = 2;
830 break; 1017 break;
831 case Opt_rdma: 1018 case Opt_rdma:
832 mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */ 1019 mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */
833 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1020 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
834 mnt->timeo = 600;
835 mnt->retrans = 2;
836 break; 1021 break;
837 case Opt_acl: 1022 case Opt_acl:
838 mnt->flags &= ~NFS_MOUNT_NOACL; 1023 mnt->flags &= ~NFS_MOUNT_NOACL;
@@ -853,165 +1038,144 @@ static int nfs_parse_mount_options(char *raw,
853 mnt->flags |= NFS_MOUNT_UNSHARED; 1038 mnt->flags |= NFS_MOUNT_UNSHARED;
854 break; 1039 break;
855 1040
1041 /*
1042 * options that take numeric values
1043 */
856 case Opt_port: 1044 case Opt_port:
857 if (match_int(args, &option)) 1045 if (match_int(args, &option) ||
858 return 0; 1046 option < 0 || option > USHORT_MAX) {
859 if (option < 0 || option > 65535) 1047 errors++;
860 return 0; 1048 nfs_parse_invalid_value("port");
861 mnt->nfs_server.port = option; 1049 } else
1050 mnt->nfs_server.port = option;
862 break; 1051 break;
863 case Opt_rsize: 1052 case Opt_rsize:
864 if (match_int(args, &mnt->rsize)) 1053 if (match_int(args, &option) || option < 0) {
865 return 0; 1054 errors++;
1055 nfs_parse_invalid_value("rsize");
1056 } else
1057 mnt->rsize = option;
866 break; 1058 break;
867 case Opt_wsize: 1059 case Opt_wsize:
868 if (match_int(args, &mnt->wsize)) 1060 if (match_int(args, &option) || option < 0) {
869 return 0; 1061 errors++;
1062 nfs_parse_invalid_value("wsize");
1063 } else
1064 mnt->wsize = option;
870 break; 1065 break;
871 case Opt_bsize: 1066 case Opt_bsize:
872 if (match_int(args, &option)) 1067 if (match_int(args, &option) || option < 0) {
873 return 0; 1068 errors++;
874 if (option < 0) 1069 nfs_parse_invalid_value("bsize");
875 return 0; 1070 } else
876 mnt->bsize = option; 1071 mnt->bsize = option;
877 break; 1072 break;
878 case Opt_timeo: 1073 case Opt_timeo:
879 if (match_int(args, &mnt->timeo)) 1074 if (match_int(args, &option) || option <= 0) {
880 return 0; 1075 errors++;
1076 nfs_parse_invalid_value("timeo");
1077 } else
1078 mnt->timeo = option;
881 break; 1079 break;
882 case Opt_retrans: 1080 case Opt_retrans:
883 if (match_int(args, &mnt->retrans)) 1081 if (match_int(args, &option) || option <= 0) {
884 return 0; 1082 errors++;
1083 nfs_parse_invalid_value("retrans");
1084 } else
1085 mnt->retrans = option;
885 break; 1086 break;
886 case Opt_acregmin: 1087 case Opt_acregmin:
887 if (match_int(args, &mnt->acregmin)) 1088 if (match_int(args, &option) || option < 0) {
888 return 0; 1089 errors++;
1090 nfs_parse_invalid_value("acregmin");
1091 } else
1092 mnt->acregmin = option;
889 break; 1093 break;
890 case Opt_acregmax: 1094 case Opt_acregmax:
891 if (match_int(args, &mnt->acregmax)) 1095 if (match_int(args, &option) || option < 0) {
892 return 0; 1096 errors++;
1097 nfs_parse_invalid_value("acregmax");
1098 } else
1099 mnt->acregmax = option;
893 break; 1100 break;
894 case Opt_acdirmin: 1101 case Opt_acdirmin:
895 if (match_int(args, &mnt->acdirmin)) 1102 if (match_int(args, &option) || option < 0) {
896 return 0; 1103 errors++;
1104 nfs_parse_invalid_value("acdirmin");
1105 } else
1106 mnt->acdirmin = option;
897 break; 1107 break;
898 case Opt_acdirmax: 1108 case Opt_acdirmax:
899 if (match_int(args, &mnt->acdirmax)) 1109 if (match_int(args, &option) || option < 0) {
900 return 0; 1110 errors++;
1111 nfs_parse_invalid_value("acdirmax");
1112 } else
1113 mnt->acdirmax = option;
901 break; 1114 break;
902 case Opt_actimeo: 1115 case Opt_actimeo:
903 if (match_int(args, &option)) 1116 if (match_int(args, &option) || option < 0) {
904 return 0; 1117 errors++;
905 if (option < 0) 1118 nfs_parse_invalid_value("actimeo");
906 return 0; 1119 } else
907 mnt->acregmin = 1120 mnt->acregmin = mnt->acregmax =
908 mnt->acregmax = 1121 mnt->acdirmin = mnt->acdirmax = option;
909 mnt->acdirmin =
910 mnt->acdirmax = option;
911 break; 1122 break;
912 case Opt_namelen: 1123 case Opt_namelen:
913 if (match_int(args, &mnt->namlen)) 1124 if (match_int(args, &option) || option < 0) {
914 return 0; 1125 errors++;
1126 nfs_parse_invalid_value("namlen");
1127 } else
1128 mnt->namlen = option;
915 break; 1129 break;
916 case Opt_mountport: 1130 case Opt_mountport:
917 if (match_int(args, &option)) 1131 if (match_int(args, &option) ||
918 return 0; 1132 option < 0 || option > USHORT_MAX) {
919 if (option < 0 || option > 65535) 1133 errors++;
920 return 0; 1134 nfs_parse_invalid_value("mountport");
921 mnt->mount_server.port = option; 1135 } else
1136 mnt->mount_server.port = option;
922 break; 1137 break;
923 case Opt_mountvers: 1138 case Opt_mountvers:
924 if (match_int(args, &option)) 1139 if (match_int(args, &option) ||
925 return 0; 1140 option < NFS_MNT_VERSION ||
926 if (option < 0) 1141 option > NFS_MNT3_VERSION) {
927 return 0; 1142 errors++;
928 mnt->mount_server.version = option; 1143 nfs_parse_invalid_value("mountvers");
1144 } else
1145 mnt->mount_server.version = option;
929 break; 1146 break;
930 case Opt_nfsvers: 1147 case Opt_nfsvers:
931 if (match_int(args, &option)) 1148 if (match_int(args, &option)) {
932 return 0; 1149 errors++;
1150 nfs_parse_invalid_value("nfsvers");
1151 break;
1152 }
933 switch (option) { 1153 switch (option) {
934 case 2: 1154 case NFS2_VERSION:
935 mnt->flags &= ~NFS_MOUNT_VER3; 1155 mnt->flags &= ~NFS_MOUNT_VER3;
936 break; 1156 break;
937 case 3: 1157 case NFS3_VERSION:
938 mnt->flags |= NFS_MOUNT_VER3; 1158 mnt->flags |= NFS_MOUNT_VER3;
939 break; 1159 break;
940 default: 1160 default:
941 goto out_unrec_vers; 1161 errors++;
1162 nfs_parse_invalid_value("nfsvers");
942 } 1163 }
943 break; 1164 break;
944 1165
1166 /*
1167 * options that take text values
1168 */
945 case Opt_sec: 1169 case Opt_sec:
946 string = match_strdup(args); 1170 string = match_strdup(args);
947 if (string == NULL) 1171 if (string == NULL)
948 goto out_nomem; 1172 goto out_nomem;
949 token = match_token(string, nfs_secflavor_tokens, args); 1173 rc = nfs_parse_security_flavors(string, mnt);
950 kfree(string); 1174 kfree(string);
951 1175 if (!rc) {
952 /* 1176 errors++;
953 * The flags setting is for v2/v3. The flavor_len 1177 dfprintk(MOUNT, "NFS: unrecognized "
954 * setting is for v4. v2/v3 also need to know the 1178 "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 } 1179 }
1016 break; 1180 break;
1017 case Opt_proto: 1181 case Opt_proto:
@@ -1026,24 +1190,20 @@ static int nfs_parse_mount_options(char *raw,
1026 case Opt_xprt_udp: 1190 case Opt_xprt_udp:
1027 mnt->flags &= ~NFS_MOUNT_TCP; 1191 mnt->flags &= ~NFS_MOUNT_TCP;
1028 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1192 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1029 mnt->timeo = 7;
1030 mnt->retrans = 5;
1031 break; 1193 break;
1032 case Opt_xprt_tcp: 1194 case Opt_xprt_tcp:
1033 mnt->flags |= NFS_MOUNT_TCP; 1195 mnt->flags |= NFS_MOUNT_TCP;
1034 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1196 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1035 mnt->timeo = 600;
1036 mnt->retrans = 2;
1037 break; 1197 break;
1038 case Opt_xprt_rdma: 1198 case Opt_xprt_rdma:
1039 /* vector side protocols to TCP */ 1199 /* vector side protocols to TCP */
1040 mnt->flags |= NFS_MOUNT_TCP; 1200 mnt->flags |= NFS_MOUNT_TCP;
1041 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1201 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
1042 mnt->timeo = 600;
1043 mnt->retrans = 2;
1044 break; 1202 break;
1045 default: 1203 default:
1046 goto out_unrec_xprt; 1204 errors++;
1205 dfprintk(MOUNT, "NFS: unrecognized "
1206 "transport protocol\n");
1047 } 1207 }
1048 break; 1208 break;
1049 case Opt_mountproto: 1209 case Opt_mountproto:
@@ -1063,16 +1223,19 @@ static int nfs_parse_mount_options(char *raw,
1063 break; 1223 break;
1064 case Opt_xprt_rdma: /* not used for side protocols */ 1224 case Opt_xprt_rdma: /* not used for side protocols */
1065 default: 1225 default:
1066 goto out_unrec_xprt; 1226 errors++;
1227 dfprintk(MOUNT, "NFS: unrecognized "
1228 "transport protocol\n");
1067 } 1229 }
1068 break; 1230 break;
1069 case Opt_addr: 1231 case Opt_addr:
1070 string = match_strdup(args); 1232 string = match_strdup(args);
1071 if (string == NULL) 1233 if (string == NULL)
1072 goto out_nomem; 1234 goto out_nomem;
1073 nfs_parse_server_address(string, (struct sockaddr *) 1235 nfs_parse_ip_address(string, strlen(string),
1074 &mnt->nfs_server.address, 1236 (struct sockaddr *)
1075 &mnt->nfs_server.addrlen); 1237 &mnt->nfs_server.address,
1238 &mnt->nfs_server.addrlen);
1076 kfree(string); 1239 kfree(string);
1077 break; 1240 break;
1078 case Opt_clientaddr: 1241 case Opt_clientaddr:
@@ -1093,24 +1256,33 @@ static int nfs_parse_mount_options(char *raw,
1093 string = match_strdup(args); 1256 string = match_strdup(args);
1094 if (string == NULL) 1257 if (string == NULL)
1095 goto out_nomem; 1258 goto out_nomem;
1096 nfs_parse_server_address(string, (struct sockaddr *) 1259 nfs_parse_ip_address(string, strlen(string),
1097 &mnt->mount_server.address, 1260 (struct sockaddr *)
1098 &mnt->mount_server.addrlen); 1261 &mnt->mount_server.address,
1262 &mnt->mount_server.addrlen);
1099 kfree(string); 1263 kfree(string);
1100 break; 1264 break;
1101 1265
1266 /*
1267 * Special options
1268 */
1269 case Opt_sloppy:
1270 sloppy = 1;
1271 dfprintk(MOUNT, "NFS: relaxing parsing rules\n");
1272 break;
1102 case Opt_userspace: 1273 case Opt_userspace:
1103 case Opt_deprecated: 1274 case Opt_deprecated:
1275 dfprintk(MOUNT, "NFS: ignoring mount option "
1276 "'%s'\n", p);
1104 break; 1277 break;
1105 1278
1106 default: 1279 default:
1107 goto out_unknown; 1280 errors++;
1281 dfprintk(MOUNT, "NFS: unrecognized mount option "
1282 "'%s'\n", p);
1108 } 1283 }
1109 } 1284 }
1110 1285
1111 nfs_set_port((struct sockaddr *)&mnt->nfs_server.address,
1112 mnt->nfs_server.port);
1113
1114 return 1; 1286 return 1;
1115 1287
1116out_nomem: 1288out_nomem:
@@ -1120,21 +1292,6 @@ out_security_failure:
1120 free_secdata(secdata); 1292 free_secdata(secdata);
1121 printk(KERN_INFO "NFS: security options invalid: %d\n", rc); 1293 printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
1122 return 0; 1294 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} 1295}
1139 1296
1140/* 1297/*
@@ -1188,11 +1345,146 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1188 if (status == 0) 1345 if (status == 0)
1189 return 0; 1346 return 0;
1190 1347
1191 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d", 1348 dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
1192 hostname, status); 1349 hostname, status);
1193 return status; 1350 return status;
1194} 1351}
1195 1352
1353static int nfs_parse_simple_hostname(const char *dev_name,
1354 char **hostname, size_t maxnamlen,
1355 char **export_path, size_t maxpathlen)
1356{
1357 size_t len;
1358 char *colon, *comma;
1359
1360 colon = strchr(dev_name, ':');
1361 if (colon == NULL)
1362 goto out_bad_devname;
1363
1364 len = colon - dev_name;
1365 if (len > maxnamlen)
1366 goto out_hostname;
1367
1368 /* N.B. caller will free nfs_server.hostname in all cases */
1369 *hostname = kstrndup(dev_name, len, GFP_KERNEL);
1370 if (!*hostname)
1371 goto out_nomem;
1372
1373 /* kill possible hostname list: not supported */
1374 comma = strchr(*hostname, ',');
1375 if (comma != NULL) {
1376 if (comma == *hostname)
1377 goto out_bad_devname;
1378 *comma = '\0';
1379 }
1380
1381 colon++;
1382 len = strlen(colon);
1383 if (len > maxpathlen)
1384 goto out_path;
1385 *export_path = kstrndup(colon, len, GFP_KERNEL);
1386 if (!*export_path)
1387 goto out_nomem;
1388
1389 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path);
1390 return 0;
1391
1392out_bad_devname:
1393 dfprintk(MOUNT, "NFS: device name not in host:path format\n");
1394 return -EINVAL;
1395
1396out_nomem:
1397 dfprintk(MOUNT, "NFS: not enough memory to parse device name\n");
1398 return -ENOMEM;
1399
1400out_hostname:
1401 dfprintk(MOUNT, "NFS: server hostname too long\n");
1402 return -ENAMETOOLONG;
1403
1404out_path:
1405 dfprintk(MOUNT, "NFS: export pathname too long\n");
1406 return -ENAMETOOLONG;
1407}
1408
1409/*
1410 * Hostname has square brackets around it because it contains one or
1411 * more colons. We look for the first closing square bracket, and a
1412 * colon must follow it.
1413 */
1414static int nfs_parse_protected_hostname(const char *dev_name,
1415 char **hostname, size_t maxnamlen,
1416 char **export_path, size_t maxpathlen)
1417{
1418 size_t len;
1419 char *start, *end;
1420
1421 start = (char *)(dev_name + 1);
1422
1423 end = strchr(start, ']');
1424 if (end == NULL)
1425 goto out_bad_devname;
1426 if (*(end + 1) != ':')
1427 goto out_bad_devname;
1428
1429 len = end - start;
1430 if (len > maxnamlen)
1431 goto out_hostname;
1432
1433 /* N.B. caller will free nfs_server.hostname in all cases */
1434 *hostname = kstrndup(start, len, GFP_KERNEL);
1435 if (*hostname == NULL)
1436 goto out_nomem;
1437
1438 end += 2;
1439 len = strlen(end);
1440 if (len > maxpathlen)
1441 goto out_path;
1442 *export_path = kstrndup(end, len, GFP_KERNEL);
1443 if (!*export_path)
1444 goto out_nomem;
1445
1446 return 0;
1447
1448out_bad_devname:
1449 dfprintk(MOUNT, "NFS: device name not in host:path format\n");
1450 return -EINVAL;
1451
1452out_nomem:
1453 dfprintk(MOUNT, "NFS: not enough memory to parse device name\n");
1454 return -ENOMEM;
1455
1456out_hostname:
1457 dfprintk(MOUNT, "NFS: server hostname too long\n");
1458 return -ENAMETOOLONG;
1459
1460out_path:
1461 dfprintk(MOUNT, "NFS: export pathname too long\n");
1462 return -ENAMETOOLONG;
1463}
1464
1465/*
1466 * Split "dev_name" into "hostname:export_path".
1467 *
1468 * The leftmost colon demarks the split between the server's hostname
1469 * and the export path. If the hostname starts with a left square
1470 * bracket, then it may contain colons.
1471 *
1472 * Note: caller frees hostname and export path, even on error.
1473 */
1474static int nfs_parse_devname(const char *dev_name,
1475 char **hostname, size_t maxnamlen,
1476 char **export_path, size_t maxpathlen)
1477{
1478 if (*dev_name == '[')
1479 return nfs_parse_protected_hostname(dev_name,
1480 hostname, maxnamlen,
1481 export_path, maxpathlen);
1482
1483 return nfs_parse_simple_hostname(dev_name,
1484 hostname, maxnamlen,
1485 export_path, maxpathlen);
1486}
1487
1196/* 1488/*
1197 * Validate the NFS2/NFS3 mount data 1489 * Validate the NFS2/NFS3 mount data
1198 * - fills in the mount root filehandle 1490 * - fills in the mount root filehandle
@@ -1222,16 +1514,14 @@ static int nfs_validate_mount_data(void *options,
1222 args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP); 1514 args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
1223 args->rsize = NFS_MAX_FILE_IO_SIZE; 1515 args->rsize = NFS_MAX_FILE_IO_SIZE;
1224 args->wsize = NFS_MAX_FILE_IO_SIZE; 1516 args->wsize = NFS_MAX_FILE_IO_SIZE;
1225 args->timeo = 600; 1517 args->acregmin = NFS_DEF_ACREGMIN;
1226 args->retrans = 2; 1518 args->acregmax = NFS_DEF_ACREGMAX;
1227 args->acregmin = 3; 1519 args->acdirmin = NFS_DEF_ACDIRMIN;
1228 args->acregmax = 60; 1520 args->acdirmax = NFS_DEF_ACDIRMAX;
1229 args->acdirmin = 30;
1230 args->acdirmax = 60;
1231 args->mount_server.port = 0; /* autobind unless user sets port */ 1521 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 */ 1522 args->nfs_server.port = 0; /* autobind unless user sets port */
1234 args->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1523 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1524 args->auth_flavors[0] = RPC_AUTH_UNIX;
1235 1525
1236 switch (data->version) { 1526 switch (data->version) {
1237 case 1: 1527 case 1:
@@ -1289,7 +1579,9 @@ static int nfs_validate_mount_data(void *options,
1289 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); 1579 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
1290 args->namlen = data->namlen; 1580 args->namlen = data->namlen;
1291 args->bsize = data->bsize; 1581 args->bsize = data->bsize;
1292 args->auth_flavors[0] = data->pseudoflavor; 1582
1583 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1584 args->auth_flavors[0] = data->pseudoflavor;
1293 if (!args->nfs_server.hostname) 1585 if (!args->nfs_server.hostname)
1294 goto out_nomem; 1586 goto out_nomem;
1295 1587
@@ -1321,8 +1613,6 @@ static int nfs_validate_mount_data(void *options,
1321 1613
1322 break; 1614 break;
1323 default: { 1615 default: {
1324 unsigned int len;
1325 char *c;
1326 int status; 1616 int status;
1327 1617
1328 if (nfs_parse_mount_options((char *)options, args) == 0) 1618 if (nfs_parse_mount_options((char *)options, args) == 0)
@@ -1332,21 +1622,22 @@ static int nfs_validate_mount_data(void *options,
1332 &args->nfs_server.address)) 1622 &args->nfs_server.address))
1333 goto out_no_address; 1623 goto out_no_address;
1334 1624
1335 c = strchr(dev_name, ':'); 1625 nfs_set_port((struct sockaddr *)&args->nfs_server.address,
1336 if (c == NULL) 1626 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 1627
1344 c++; 1628 nfs_set_mount_transport_protocol(args);
1345 if (strlen(c) > NFS_MAXPATHLEN) 1629
1346 return -ENAMETOOLONG; 1630 status = nfs_parse_devname(dev_name,
1347 args->nfs_server.export_path = c; 1631 &args->nfs_server.hostname,
1632 PAGE_SIZE,
1633 &args->nfs_server.export_path,
1634 NFS_MAXPATHLEN);
1635 if (!status)
1636 status = nfs_try_mount(args, mntfh);
1637
1638 kfree(args->nfs_server.export_path);
1639 args->nfs_server.export_path = NULL;
1348 1640
1349 status = nfs_try_mount(args, mntfh);
1350 if (status) 1641 if (status)
1351 return status; 1642 return status;
1352 1643
@@ -1354,9 +1645,6 @@ static int nfs_validate_mount_data(void *options,
1354 } 1645 }
1355 } 1646 }
1356 1647
1357 if (!(args->flags & NFS_MOUNT_SECFLAVOUR))
1358 args->auth_flavors[0] = RPC_AUTH_UNIX;
1359
1360#ifndef CONFIG_NFS_V3 1648#ifndef CONFIG_NFS_V3
1361 if (args->flags & NFS_MOUNT_VER3) 1649 if (args->flags & NFS_MOUNT_VER3)
1362 goto out_v3_not_compiled; 1650 goto out_v3_not_compiled;
@@ -1396,6 +1684,80 @@ out_invalid_fh:
1396 return -EINVAL; 1684 return -EINVAL;
1397} 1685}
1398 1686
1687static int
1688nfs_compare_remount_data(struct nfs_server *nfss,
1689 struct nfs_parsed_mount_data *data)
1690{
1691 if (data->flags != nfss->flags ||
1692 data->rsize != nfss->rsize ||
1693 data->wsize != nfss->wsize ||
1694 data->retrans != nfss->client->cl_timeout->to_retries ||
1695 data->auth_flavors[0] != nfss->client->cl_auth->au_flavor ||
1696 data->acregmin != nfss->acregmin / HZ ||
1697 data->acregmax != nfss->acregmax / HZ ||
1698 data->acdirmin != nfss->acdirmin / HZ ||
1699 data->acdirmax != nfss->acdirmax / HZ ||
1700 data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
1701 data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
1702 memcmp(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
1703 data->nfs_server.addrlen) != 0)
1704 return -EINVAL;
1705
1706 return 0;
1707}
1708
1709static int
1710nfs_remount(struct super_block *sb, int *flags, char *raw_data)
1711{
1712 int error;
1713 struct nfs_server *nfss = sb->s_fs_info;
1714 struct nfs_parsed_mount_data *data;
1715 struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data;
1716 struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
1717 u32 nfsvers = nfss->nfs_client->rpc_ops->version;
1718
1719 /*
1720 * Userspace mount programs that send binary options generally send
1721 * them populated with default values. We have no way to know which
1722 * ones were explicitly specified. Fall back to legacy behavior and
1723 * just return success.
1724 */
1725 if ((nfsvers == 4 && options4->version == 1) ||
1726 (nfsvers <= 3 && options->version >= 1 &&
1727 options->version <= 6))
1728 return 0;
1729
1730 data = kzalloc(sizeof(*data), GFP_KERNEL);
1731 if (data == NULL)
1732 return -ENOMEM;
1733
1734 /* fill out struct with values from existing mount */
1735 data->flags = nfss->flags;
1736 data->rsize = nfss->rsize;
1737 data->wsize = nfss->wsize;
1738 data->retrans = nfss->client->cl_timeout->to_retries;
1739 data->auth_flavors[0] = nfss->client->cl_auth->au_flavor;
1740 data->acregmin = nfss->acregmin / HZ;
1741 data->acregmax = nfss->acregmax / HZ;
1742 data->acdirmin = nfss->acdirmin / HZ;
1743 data->acdirmax = nfss->acdirmax / HZ;
1744 data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
1745 data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
1746 memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
1747 data->nfs_server.addrlen);
1748
1749 /* overwrite those values with any that were specified */
1750 error = nfs_parse_mount_options((char *)options, data);
1751 if (error < 0)
1752 goto out;
1753
1754 /* compare new mount options with old ones */
1755 error = nfs_compare_remount_data(nfss, data);
1756out:
1757 kfree(data);
1758 return error;
1759}
1760
1399/* 1761/*
1400 * Initialise the common bits of the superblock 1762 * Initialise the common bits of the superblock
1401 */ 1763 */
@@ -1811,14 +2173,13 @@ static int nfs4_validate_mount_data(void *options,
1811 2173
1812 args->rsize = NFS_MAX_FILE_IO_SIZE; 2174 args->rsize = NFS_MAX_FILE_IO_SIZE;
1813 args->wsize = NFS_MAX_FILE_IO_SIZE; 2175 args->wsize = NFS_MAX_FILE_IO_SIZE;
1814 args->timeo = 600; 2176 args->acregmin = NFS_DEF_ACREGMIN;
1815 args->retrans = 2; 2177 args->acregmax = NFS_DEF_ACREGMAX;
1816 args->acregmin = 3; 2178 args->acdirmin = NFS_DEF_ACDIRMIN;
1817 args->acregmax = 60; 2179 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= */ 2180 args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
1821 args->nfs_server.protocol = XPRT_TRANSPORT_TCP; 2181 args->auth_flavors[0] = RPC_AUTH_UNIX;
2182 args->auth_flavor_len = 0;
1822 2183
1823 switch (data->version) { 2184 switch (data->version) {
1824 case 1: 2185 case 1:
@@ -1834,18 +2195,13 @@ static int nfs4_validate_mount_data(void *options,
1834 &args->nfs_server.address)) 2195 &args->nfs_server.address))
1835 goto out_no_address; 2196 goto out_no_address;
1836 2197
1837 switch (data->auth_flavourlen) { 2198 if (data->auth_flavourlen) {
1838 case 0: 2199 if (data->auth_flavourlen > 1)
1839 args->auth_flavors[0] = RPC_AUTH_UNIX; 2200 goto out_inval_auth;
1840 break;
1841 case 1:
1842 if (copy_from_user(&args->auth_flavors[0], 2201 if (copy_from_user(&args->auth_flavors[0],
1843 data->auth_flavours, 2202 data->auth_flavours,
1844 sizeof(args->auth_flavors[0]))) 2203 sizeof(args->auth_flavors[0])))
1845 return -EFAULT; 2204 return -EFAULT;
1846 break;
1847 default:
1848 goto out_inval_auth;
1849 } 2205 }
1850 2206
1851 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 2207 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
@@ -1879,10 +2235,11 @@ static int nfs4_validate_mount_data(void *options,
1879 args->acdirmin = data->acdirmin; 2235 args->acdirmin = data->acdirmin;
1880 args->acdirmax = data->acdirmax; 2236 args->acdirmax = data->acdirmax;
1881 args->nfs_server.protocol = data->proto; 2237 args->nfs_server.protocol = data->proto;
2238 nfs_validate_transport_protocol(args);
1882 2239
1883 break; 2240 break;
1884 default: { 2241 default: {
1885 unsigned int len; 2242 int status;
1886 2243
1887 if (nfs_parse_mount_options((char *)options, args) == 0) 2244 if (nfs_parse_mount_options((char *)options, args) == 0)
1888 return -EINVAL; 2245 return -EINVAL;
@@ -1891,44 +2248,25 @@ static int nfs4_validate_mount_data(void *options,
1891 &args->nfs_server.address)) 2248 &args->nfs_server.address))
1892 return -EINVAL; 2249 return -EINVAL;
1893 2250
1894 switch (args->auth_flavor_len) { 2251 nfs_set_port((struct sockaddr *)&args->nfs_server.address,
1895 case 0: 2252 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 2253
1904 /* 2254 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 2255
1927 dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path); 2256 if (args->auth_flavor_len > 1)
2257 goto out_inval_auth;
1928 2258
1929 if (args->client_address == NULL) 2259 if (args->client_address == NULL)
1930 goto out_no_client_address; 2260 goto out_no_client_address;
1931 2261
2262 status = nfs_parse_devname(dev_name,
2263 &args->nfs_server.hostname,
2264 NFS4_MAXNAMLEN,
2265 &args->nfs_server.export_path,
2266 NFS4_MAXPATHLEN);
2267 if (status < 0)
2268 return status;
2269
1932 break; 2270 break;
1933 } 2271 }
1934 } 2272 }
@@ -1944,10 +2282,6 @@ out_inval_auth:
1944 data->auth_flavourlen); 2282 data->auth_flavourlen);
1945 return -EINVAL; 2283 return -EINVAL;
1946 2284
1947out_nomem:
1948 dfprintk(MOUNT, "NFS4: not enough memory to handle mount options\n");
1949 return -ENOMEM;
1950
1951out_no_address: 2285out_no_address:
1952 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 2286 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
1953 return -EINVAL; 2287 return -EINVAL;