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.c99
1 files changed, 73 insertions, 26 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f6db66d8f647..5793f24613c8 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -923,7 +923,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
923 data->nfs_server.port = NFS_UNSPEC_PORT; 923 data->nfs_server.port = NFS_UNSPEC_PORT;
924 data->nfs_server.protocol = XPRT_TRANSPORT_TCP; 924 data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
925 data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR; 925 data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR;
926 data->auth_flavor_len = 1; 926 data->auth_flavor_len = 0;
927 data->minorversion = 0; 927 data->minorversion = 0;
928 data->need_mount = true; 928 data->need_mount = true;
929 data->net = current->nsproxy->net_ns; 929 data->net = current->nsproxy->net_ns;
@@ -1018,6 +1018,13 @@ static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt)
1018 } 1018 }
1019} 1019}
1020 1020
1021static void nfs_set_auth_parsed_mount_data(struct nfs_parsed_mount_data *data,
1022 rpc_authflavor_t pseudoflavor)
1023{
1024 data->auth_flavors[0] = pseudoflavor;
1025 data->auth_flavor_len = 1;
1026}
1027
1021/* 1028/*
1022 * Parse the value of the 'sec=' option. 1029 * Parse the value of the 'sec=' option.
1023 */ 1030 */
@@ -1025,49 +1032,50 @@ static int nfs_parse_security_flavors(char *value,
1025 struct nfs_parsed_mount_data *mnt) 1032 struct nfs_parsed_mount_data *mnt)
1026{ 1033{
1027 substring_t args[MAX_OPT_ARGS]; 1034 substring_t args[MAX_OPT_ARGS];
1035 rpc_authflavor_t pseudoflavor;
1028 1036
1029 dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value); 1037 dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value);
1030 1038
1031 switch (match_token(value, nfs_secflavor_tokens, args)) { 1039 switch (match_token(value, nfs_secflavor_tokens, args)) {
1032 case Opt_sec_none: 1040 case Opt_sec_none:
1033 mnt->auth_flavors[0] = RPC_AUTH_NULL; 1041 pseudoflavor = RPC_AUTH_NULL;
1034 break; 1042 break;
1035 case Opt_sec_sys: 1043 case Opt_sec_sys:
1036 mnt->auth_flavors[0] = RPC_AUTH_UNIX; 1044 pseudoflavor = RPC_AUTH_UNIX;
1037 break; 1045 break;
1038 case Opt_sec_krb5: 1046 case Opt_sec_krb5:
1039 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; 1047 pseudoflavor = RPC_AUTH_GSS_KRB5;
1040 break; 1048 break;
1041 case Opt_sec_krb5i: 1049 case Opt_sec_krb5i:
1042 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; 1050 pseudoflavor = RPC_AUTH_GSS_KRB5I;
1043 break; 1051 break;
1044 case Opt_sec_krb5p: 1052 case Opt_sec_krb5p:
1045 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; 1053 pseudoflavor = RPC_AUTH_GSS_KRB5P;
1046 break; 1054 break;
1047 case Opt_sec_lkey: 1055 case Opt_sec_lkey:
1048 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; 1056 pseudoflavor = RPC_AUTH_GSS_LKEY;
1049 break; 1057 break;
1050 case Opt_sec_lkeyi: 1058 case Opt_sec_lkeyi:
1051 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; 1059 pseudoflavor = RPC_AUTH_GSS_LKEYI;
1052 break; 1060 break;
1053 case Opt_sec_lkeyp: 1061 case Opt_sec_lkeyp:
1054 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; 1062 pseudoflavor = RPC_AUTH_GSS_LKEYP;
1055 break; 1063 break;
1056 case Opt_sec_spkm: 1064 case Opt_sec_spkm:
1057 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; 1065 pseudoflavor = RPC_AUTH_GSS_SPKM;
1058 break; 1066 break;
1059 case Opt_sec_spkmi: 1067 case Opt_sec_spkmi:
1060 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; 1068 pseudoflavor = RPC_AUTH_GSS_SPKMI;
1061 break; 1069 break;
1062 case Opt_sec_spkmp: 1070 case Opt_sec_spkmp:
1063 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; 1071 pseudoflavor = RPC_AUTH_GSS_SPKMP;
1064 break; 1072 break;
1065 default: 1073 default:
1066 return 0; 1074 return 0;
1067 } 1075 }
1068 1076
1069 mnt->flags |= NFS_MOUNT_SECFLAVOUR; 1077 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
1070 mnt->auth_flavor_len = 1; 1078 nfs_set_auth_parsed_mount_data(mnt, pseudoflavor);
1071 return 1; 1079 return 1;
1072} 1080}
1073 1081
@@ -1729,7 +1737,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
1729 * Was a sec= authflavor specified in the options? First, verify 1737 * Was a sec= authflavor specified in the options? First, verify
1730 * whether the server supports it, and then just try to use it if so. 1738 * whether the server supports it, and then just try to use it if so.
1731 */ 1739 */
1732 if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) { 1740 if (args->auth_flavor_len > 0) {
1733 status = nfs_verify_authflavor(args, authlist, authlist_len); 1741 status = nfs_verify_authflavor(args, authlist, authlist_len);
1734 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]); 1742 dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->auth_flavors[0]);
1735 if (status) 1743 if (status)
@@ -1760,7 +1768,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
1760 /* Fallthrough */ 1768 /* Fallthrough */
1761 } 1769 }
1762 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor); 1770 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
1763 args->auth_flavors[0] = flavor; 1771 nfs_set_auth_parsed_mount_data(args, flavor);
1764 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1772 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1765 if (!IS_ERR(server)) 1773 if (!IS_ERR(server))
1766 return server; 1774 return server;
@@ -1776,7 +1784,7 @@ static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_inf
1776 1784
1777 /* Last chance! Try AUTH_UNIX */ 1785 /* Last chance! Try AUTH_UNIX */
1778 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX); 1786 dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
1779 args->auth_flavors[0] = RPC_AUTH_UNIX; 1787 nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
1780 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod); 1788 return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1781} 1789}
1782 1790
@@ -1893,6 +1901,7 @@ static int nfs23_validate_mount_data(void *options,
1893{ 1901{
1894 struct nfs_mount_data *data = (struct nfs_mount_data *)options; 1902 struct nfs_mount_data *data = (struct nfs_mount_data *)options;
1895 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; 1903 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
1904 int extra_flags = NFS_MOUNT_LEGACY_INTERFACE;
1896 1905
1897 if (data == NULL) 1906 if (data == NULL)
1898 goto out_no_data; 1907 goto out_no_data;
@@ -1908,6 +1917,8 @@ static int nfs23_validate_mount_data(void *options,
1908 goto out_no_v3; 1917 goto out_no_v3;
1909 data->root.size = NFS2_FHSIZE; 1918 data->root.size = NFS2_FHSIZE;
1910 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE); 1919 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1920 /* Turn off security negotiation */
1921 extra_flags |= NFS_MOUNT_SECFLAVOUR;
1911 case 4: 1922 case 4:
1912 if (data->flags & NFS_MOUNT_SECFLAVOUR) 1923 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1913 goto out_no_sec; 1924 goto out_no_sec;
@@ -1935,7 +1946,7 @@ static int nfs23_validate_mount_data(void *options,
1935 * can deal with. 1946 * can deal with.
1936 */ 1947 */
1937 args->flags = data->flags & NFS_MOUNT_FLAGMASK; 1948 args->flags = data->flags & NFS_MOUNT_FLAGMASK;
1938 args->flags |= NFS_MOUNT_LEGACY_INTERFACE; 1949 args->flags |= extra_flags;
1939 args->rsize = data->rsize; 1950 args->rsize = data->rsize;
1940 args->wsize = data->wsize; 1951 args->wsize = data->wsize;
1941 args->timeo = data->timeo; 1952 args->timeo = data->timeo;
@@ -1959,9 +1970,10 @@ static int nfs23_validate_mount_data(void *options,
1959 args->namlen = data->namlen; 1970 args->namlen = data->namlen;
1960 args->bsize = data->bsize; 1971 args->bsize = data->bsize;
1961 1972
1962 args->auth_flavors[0] = RPC_AUTH_UNIX;
1963 if (data->flags & NFS_MOUNT_SECFLAVOUR) 1973 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1964 args->auth_flavors[0] = data->pseudoflavor; 1974 nfs_set_auth_parsed_mount_data(args, data->pseudoflavor);
1975 else
1976 nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
1965 if (!args->nfs_server.hostname) 1977 if (!args->nfs_server.hostname)
1966 goto out_nomem; 1978 goto out_nomem;
1967 1979
@@ -2084,6 +2096,8 @@ static int nfs_validate_text_mount_data(void *options,
2084 max_namelen = NFS4_MAXNAMLEN; 2096 max_namelen = NFS4_MAXNAMLEN;
2085 max_pathlen = NFS4_MAXPATHLEN; 2097 max_pathlen = NFS4_MAXPATHLEN;
2086 nfs_validate_transport_protocol(args); 2098 nfs_validate_transport_protocol(args);
2099 if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP)
2100 goto out_invalid_transport_udp;
2087 nfs4_validate_mount_flags(args); 2101 nfs4_validate_mount_flags(args);
2088#else 2102#else
2089 goto out_v4_not_compiled; 2103 goto out_v4_not_compiled;
@@ -2106,6 +2120,10 @@ static int nfs_validate_text_mount_data(void *options,
2106out_v4_not_compiled: 2120out_v4_not_compiled:
2107 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); 2121 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
2108 return -EPROTONOSUPPORT; 2122 return -EPROTONOSUPPORT;
2123#else
2124out_invalid_transport_udp:
2125 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n");
2126 return -EINVAL;
2109#endif /* !CONFIG_NFS_V4 */ 2127#endif /* !CONFIG_NFS_V4 */
2110 2128
2111out_no_address: 2129out_no_address:
@@ -2170,7 +2188,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
2170 data->rsize = nfss->rsize; 2188 data->rsize = nfss->rsize;
2171 data->wsize = nfss->wsize; 2189 data->wsize = nfss->wsize;
2172 data->retrans = nfss->client->cl_timeout->to_retries; 2190 data->retrans = nfss->client->cl_timeout->to_retries;
2173 data->auth_flavors[0] = nfss->client->cl_auth->au_flavor; 2191 nfs_set_auth_parsed_mount_data(data, nfss->client->cl_auth->au_flavor);
2174 data->acregmin = nfss->acregmin / HZ; 2192 data->acregmin = nfss->acregmin / HZ;
2175 data->acregmax = nfss->acregmax / HZ; 2193 data->acregmax = nfss->acregmax / HZ;
2176 data->acdirmin = nfss->acdirmin / HZ; 2194 data->acdirmin = nfss->acdirmin / HZ;
@@ -2277,6 +2295,18 @@ void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2277 nfs_initialise_sb(sb); 2295 nfs_initialise_sb(sb);
2278} 2296}
2279 2297
2298#define NFS_MOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \
2299 | NFS_MOUNT_SECURE \
2300 | NFS_MOUNT_TCP \
2301 | NFS_MOUNT_VER3 \
2302 | NFS_MOUNT_KERBEROS \
2303 | NFS_MOUNT_NONLM \
2304 | NFS_MOUNT_BROKEN_SUID \
2305 | NFS_MOUNT_STRICTLOCK \
2306 | NFS_MOUNT_UNSHARED \
2307 | NFS_MOUNT_NORESVPORT \
2308 | NFS_MOUNT_LEGACY_INTERFACE)
2309
2280static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags) 2310static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
2281{ 2311{
2282 const struct nfs_server *a = s->s_fs_info; 2312 const struct nfs_server *a = s->s_fs_info;
@@ -2287,7 +2317,7 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n
2287 goto Ebusy; 2317 goto Ebusy;
2288 if (a->nfs_client != b->nfs_client) 2318 if (a->nfs_client != b->nfs_client)
2289 goto Ebusy; 2319 goto Ebusy;
2290 if (a->flags != b->flags) 2320 if ((a->flags ^ b->flags) & NFS_MOUNT_CMP_FLAGMASK)
2291 goto Ebusy; 2321 goto Ebusy;
2292 if (a->wsize != b->wsize) 2322 if (a->wsize != b->wsize)
2293 goto Ebusy; 2323 goto Ebusy;
@@ -2301,7 +2331,8 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n
2301 goto Ebusy; 2331 goto Ebusy;
2302 if (a->acdirmax != b->acdirmax) 2332 if (a->acdirmax != b->acdirmax)
2303 goto Ebusy; 2333 goto Ebusy;
2304 if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor) 2334 if (b->flags & NFS_MOUNT_SECFLAVOUR &&
2335 clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
2305 goto Ebusy; 2336 goto Ebusy;
2306 return 1; 2337 return 1;
2307Ebusy: 2338Ebusy:
@@ -2673,15 +2704,17 @@ static int nfs4_validate_mount_data(void *options,
2673 goto out_no_address; 2704 goto out_no_address;
2674 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); 2705 args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
2675 2706
2676 args->auth_flavors[0] = RPC_AUTH_UNIX;
2677 if (data->auth_flavourlen) { 2707 if (data->auth_flavourlen) {
2708 rpc_authflavor_t pseudoflavor;
2678 if (data->auth_flavourlen > 1) 2709 if (data->auth_flavourlen > 1)
2679 goto out_inval_auth; 2710 goto out_inval_auth;
2680 if (copy_from_user(&args->auth_flavors[0], 2711 if (copy_from_user(&pseudoflavor,
2681 data->auth_flavours, 2712 data->auth_flavours,
2682 sizeof(args->auth_flavors[0]))) 2713 sizeof(pseudoflavor)))
2683 return -EFAULT; 2714 return -EFAULT;
2684 } 2715 nfs_set_auth_parsed_mount_data(args, pseudoflavor);
2716 } else
2717 nfs_set_auth_parsed_mount_data(args, RPC_AUTH_UNIX);
2685 2718
2686 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); 2719 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
2687 if (IS_ERR(c)) 2720 if (IS_ERR(c))
@@ -2715,6 +2748,8 @@ static int nfs4_validate_mount_data(void *options,
2715 args->acdirmax = data->acdirmax; 2748 args->acdirmax = data->acdirmax;
2716 args->nfs_server.protocol = data->proto; 2749 args->nfs_server.protocol = data->proto;
2717 nfs_validate_transport_protocol(args); 2750 nfs_validate_transport_protocol(args);
2751 if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP)
2752 goto out_invalid_transport_udp;
2718 2753
2719 break; 2754 break;
2720 default: 2755 default:
@@ -2735,6 +2770,10 @@ out_inval_auth:
2735out_no_address: 2770out_no_address:
2736 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 2771 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
2737 return -EINVAL; 2772 return -EINVAL;
2773
2774out_invalid_transport_udp:
2775 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n");
2776 return -EINVAL;
2738} 2777}
2739 2778
2740/* 2779/*
@@ -2750,6 +2789,7 @@ bool nfs4_disable_idmapping = true;
2750unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE; 2789unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
2751unsigned short send_implementation_id = 1; 2790unsigned short send_implementation_id = 1;
2752char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = ""; 2791char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = "";
2792bool recover_lost_locks = false;
2753 2793
2754EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport); 2794EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
2755EXPORT_SYMBOL_GPL(nfs_callback_tcpport); 2795EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
@@ -2758,6 +2798,7 @@ EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
2758EXPORT_SYMBOL_GPL(max_session_slots); 2798EXPORT_SYMBOL_GPL(max_session_slots);
2759EXPORT_SYMBOL_GPL(send_implementation_id); 2799EXPORT_SYMBOL_GPL(send_implementation_id);
2760EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier); 2800EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier);
2801EXPORT_SYMBOL_GPL(recover_lost_locks);
2761 2802
2762#define NFS_CALLBACK_MAXPORTNR (65535U) 2803#define NFS_CALLBACK_MAXPORTNR (65535U)
2763 2804
@@ -2795,4 +2836,10 @@ MODULE_PARM_DESC(send_implementation_id,
2795 "Send implementation ID with NFSv4.1 exchange_id"); 2836 "Send implementation ID with NFSv4.1 exchange_id");
2796MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string"); 2837MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
2797 2838
2839module_param(recover_lost_locks, bool, 0644);
2840MODULE_PARM_DESC(recover_lost_locks,
2841 "If the server reports that a lock might be lost, "
2842 "try to recover it risking data corruption.");
2843
2844
2798#endif /* CONFIG_NFS_V4 */ 2845#endif /* CONFIG_NFS_V4 */