fs_context.c (e38bb238ed8ce280a217629294ba51dc217c5a2c) | fs_context.c (f2aedb713c284429987dc66c7aaf38decfc8da2a) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/fs/nfs/fs_context.c 4 * 5 * Copyright (C) 1992 Rick Sladkey | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/fs/nfs/fs_context.c 4 * 5 * Copyright (C) 1992 Rick Sladkey |
6 * Conversion to new mount api Copyright (C) David Howells |
|
6 * 7 * NFS mount handling. 8 * 9 * Split from fs/nfs/super.c by David Howells <dhowells@redhat.com> 10 */ 11 12#include <linux/module.h> 13#include <linux/fs.h> --- 448 unchanged lines hidden (view full) --- 462 return -EINVAL; 463 } 464 return 0; 465} 466 467/* 468 * Parse a single mount parameter. 469 */ | 7 * 8 * NFS mount handling. 9 * 10 * Split from fs/nfs/super.c by David Howells <dhowells@redhat.com> 11 */ 12 13#include <linux/module.h> 14#include <linux/fs.h> --- 448 unchanged lines hidden (view full) --- 463 return -EINVAL; 464 } 465 return 0; 466} 467 468/* 469 * Parse a single mount parameter. 470 */ |
470static int nfs_fs_context_parse_param(struct nfs_fs_context *ctx, | 471static int nfs_fs_context_parse_param(struct fs_context *fc, |
471 struct fs_parameter *param) 472{ 473 struct fs_parse_result result; | 472 struct fs_parameter *param) 473{ 474 struct fs_parse_result result; |
475 struct nfs_fs_context *ctx = nfs_fc2context(fc); |
|
474 unsigned short protofamily, mountfamily; 475 unsigned int len; 476 int ret, opt; 477 478 dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key); 479 | 476 unsigned short protofamily, mountfamily; 477 unsigned int len; 478 int ret, opt; 479 480 dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key); 481 |
480 opt = fs_parse(NULL, &nfs_fs_parameters, param, &result); | 482 opt = fs_parse(fc, &nfs_fs_parameters, param, &result); |
481 if (opt < 0) 482 return ctx->sloppy ? 1 : opt; 483 484 switch (opt) { | 483 if (opt < 0) 484 return ctx->sloppy ? 1 : opt; 485 486 switch (opt) { |
487 case Opt_source: 488 if (fc->source) { 489 dfprintk(MOUNT, "NFS: Multiple sources not supported\n"); 490 return -EINVAL; 491 } 492 fc->source = param->string; 493 param->string = NULL; 494 break; 495 |
|
485 /* 486 * boolean options: foo/nofoo 487 */ 488 case Opt_soft: 489 ctx->flags |= NFS_MOUNT_SOFT; 490 ctx->flags &= ~NFS_MOUNT_SOFTERR; 491 break; 492 case Opt_softerr: --- 309 unchanged lines hidden (view full) --- 802out_invalid_address: 803 printk(KERN_INFO "NFS: Bad IP address specified\n"); 804 return -EINVAL; 805out_of_bounds: 806 printk(KERN_INFO "NFS: Value for '%s' out of range\n", param->key); 807 return -ERANGE; 808} 809 | 496 /* 497 * boolean options: foo/nofoo 498 */ 499 case Opt_soft: 500 ctx->flags |= NFS_MOUNT_SOFT; 501 ctx->flags &= ~NFS_MOUNT_SOFTERR; 502 break; 503 case Opt_softerr: --- 309 unchanged lines hidden (view full) --- 813out_invalid_address: 814 printk(KERN_INFO "NFS: Bad IP address specified\n"); 815 return -EINVAL; 816out_of_bounds: 817 printk(KERN_INFO "NFS: Value for '%s' out of range\n", param->key); 818 return -ERANGE; 819} 820 |
810/* cribbed from generic_parse_monolithic and vfs_parse_fs_string */ 811static int nfs_fs_context_parse_option(struct nfs_fs_context *ctx, char *p) 812{ 813 int ret; 814 char *key = p, *value; 815 size_t v_size = 0; 816 struct fs_parameter param; 817 818 memset(¶m, 0, sizeof(param)); 819 value = strchr(key, '='); 820 if (value && value != key) { 821 *value++ = 0; 822 v_size = strlen(value); 823 } 824 param.key = key; 825 param.type = fs_value_is_flag; 826 param.size = v_size; 827 if (v_size > 0) { 828 param.type = fs_value_is_string; 829 param.string = kmemdup_nul(value, v_size, GFP_KERNEL); 830 if (!param.string) 831 return -ENOMEM; 832 } 833 ret = nfs_fs_context_parse_param(ctx, ¶m); 834 kfree(param.string); 835 return ret; 836} 837 | |
838/* | 821/* |
839 * Error-check and convert a string of mount options from user space into 840 * a data structure. The whole mount string is processed; bad options are 841 * skipped as they are encountered. If there were no errors, return 1; 842 * otherwise return 0 (zero). 843 */ 844int nfs_parse_mount_options(char *raw, struct nfs_fs_context *ctx) 845{ 846 char *p; 847 int rc, sloppy = 0, invalid_option = 0; 848 849 if (!raw) { 850 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 851 return 1; 852 } 853 dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); 854 855 rc = security_sb_eat_lsm_opts(raw, &ctx->lsm_opts); 856 if (rc) 857 goto out_security_failure; 858 859 while ((p = strsep(&raw, ",")) != NULL) { 860 if (!*p) 861 continue; 862 if (nfs_fs_context_parse_option(ctx, p) < 0) 863 invalid_option = true; 864 } 865 866 if (!sloppy && invalid_option) 867 return 0; 868 869 if (ctx->minorversion && ctx->version != 4) 870 goto out_minorversion_mismatch; 871 872 if (ctx->options & NFS_OPTION_MIGRATION && 873 (ctx->version != 4 || ctx->minorversion != 0)) 874 goto out_migration_misuse; 875 876 /* 877 * verify that any proto=/mountproto= options match the address 878 * families in the addr=/mountaddr= options. 879 */ 880 if (ctx->protofamily != AF_UNSPEC && 881 ctx->protofamily != ctx->nfs_server.address.sa_family) 882 goto out_proto_mismatch; 883 884 if (ctx->mountfamily != AF_UNSPEC) { 885 if (ctx->mount_server.addrlen) { 886 if (ctx->mountfamily != ctx->mount_server.address.sa_family) 887 goto out_mountproto_mismatch; 888 } else { 889 if (ctx->mountfamily != ctx->nfs_server.address.sa_family) 890 goto out_mountproto_mismatch; 891 } 892 } 893 894 return 1; 895 896out_minorversion_mismatch: 897 printk(KERN_INFO "NFS: mount option vers=%u does not support " 898 "minorversion=%u\n", ctx->version, ctx->minorversion); 899 return 0; 900out_mountproto_mismatch: 901 printk(KERN_INFO "NFS: mount server address does not match mountproto= " 902 "option\n"); 903 return 0; 904out_proto_mismatch: 905 printk(KERN_INFO "NFS: server address does not match proto= option\n"); 906 return 0; 907out_migration_misuse: 908 printk(KERN_INFO 909 "NFS: 'migration' not supported for this NFS version\n"); 910 return -EINVAL; 911out_security_failure: 912 printk(KERN_INFO "NFS: security options invalid: %d\n", rc); 913 return 0; 914} 915 916/* | |
917 * Split "dev_name" into "hostname:export_path". 918 * 919 * The leftmost colon demarks the split between the server's hostname 920 * and the export path. If the hostname starts with a left square 921 * bracket, then it may contain colons. 922 * 923 * Note: caller frees hostname and export path, even on error. 924 */ --- 60 unchanged lines hidden (view full) --- 985 dfprintk(MOUNT, "NFS: server hostname too long\n"); 986 return -ENAMETOOLONG; 987 988out_path: 989 dfprintk(MOUNT, "NFS: export pathname too long\n"); 990 return -ENAMETOOLONG; 991} 992 | 822 * Split "dev_name" into "hostname:export_path". 823 * 824 * The leftmost colon demarks the split between the server's hostname 825 * and the export path. If the hostname starts with a left square 826 * bracket, then it may contain colons. 827 * 828 * Note: caller frees hostname and export path, even on error. 829 */ --- 60 unchanged lines hidden (view full) --- 890 dfprintk(MOUNT, "NFS: server hostname too long\n"); 891 return -ENAMETOOLONG; 892 893out_path: 894 dfprintk(MOUNT, "NFS: export pathname too long\n"); 895 return -ENAMETOOLONG; 896} 897 |
898static inline bool is_remount_fc(struct fs_context *fc) 899{ 900 return fc->root != NULL; 901} 902 |
|
993/* 994 * Parse monolithic NFS2/NFS3 mount data 995 * - fills in the mount root filehandle 996 * 997 * For option strings, user space handles the following behaviors: 998 * 999 * + DNS: mapping server host name to IP address ("addr=" option) 1000 * 1001 * + failure mode: how to behave if a mount request can't be handled 1002 * immediately ("fg/bg" option) 1003 * 1004 * + retry: how often to retry a mount request ("retry=" option) 1005 * 1006 * + breaking back: trying proto=udp after proto=tcp, v2 after v3, 1007 * mountproto=tcp after mountproto=udp, and so on 1008 */ | 903/* 904 * Parse monolithic NFS2/NFS3 mount data 905 * - fills in the mount root filehandle 906 * 907 * For option strings, user space handles the following behaviors: 908 * 909 * + DNS: mapping server host name to IP address ("addr=" option) 910 * 911 * + failure mode: how to behave if a mount request can't be handled 912 * immediately ("fg/bg" option) 913 * 914 * + retry: how often to retry a mount request ("retry=" option) 915 * 916 * + breaking back: trying proto=udp after proto=tcp, v2 after v3, 917 * mountproto=tcp after mountproto=udp, and so on 918 */ |
1009static int nfs23_validate_mount_data(void *options, 1010 struct nfs_fs_context *ctx, 1011 struct nfs_fh *mntfh, 1012 const char *dev_name) | 919static int nfs23_parse_monolithic(struct fs_context *fc, 920 struct nfs_mount_data *data) |
1013{ | 921{ |
1014 struct nfs_mount_data *data = (struct nfs_mount_data *)options; | 922 struct nfs_fs_context *ctx = nfs_fc2context(fc); 923 struct nfs_fh *mntfh = ctx->mount_info.mntfh; |
1015 struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; 1016 int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; 1017 1018 if (data == NULL) 1019 goto out_no_data; 1020 1021 ctx->version = NFS_DEFAULT_VERSION; 1022 switch (data->version) { --- 55 unchanged lines hidden (view full) --- 1078 if (sap->sa_family != AF_INET || 1079 !nfs_verify_server_address(sap)) 1080 goto out_no_address; 1081 1082 if (!(data->flags & NFS_MOUNT_TCP)) 1083 ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1084 /* N.B. caller will free nfs_server.hostname in all cases */ 1085 ctx->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); | 924 struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; 925 int extra_flags = NFS_MOUNT_LEGACY_INTERFACE; 926 927 if (data == NULL) 928 goto out_no_data; 929 930 ctx->version = NFS_DEFAULT_VERSION; 931 switch (data->version) { --- 55 unchanged lines hidden (view full) --- 987 if (sap->sa_family != AF_INET || 988 !nfs_verify_server_address(sap)) 989 goto out_no_address; 990 991 if (!(data->flags & NFS_MOUNT_TCP)) 992 ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP; 993 /* N.B. caller will free nfs_server.hostname in all cases */ 994 ctx->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); |
995 if (!ctx->nfs_server.hostname) 996 goto out_nomem; 997 |
|
1086 ctx->namlen = data->namlen; 1087 ctx->bsize = data->bsize; 1088 1089 if (data->flags & NFS_MOUNT_SECFLAVOUR) 1090 ctx->selected_flavor = data->pseudoflavor; 1091 else 1092 ctx->selected_flavor = RPC_AUTH_UNIX; | 998 ctx->namlen = data->namlen; 999 ctx->bsize = data->bsize; 1000 1001 if (data->flags & NFS_MOUNT_SECFLAVOUR) 1002 ctx->selected_flavor = data->pseudoflavor; 1003 else 1004 ctx->selected_flavor = RPC_AUTH_UNIX; |
1093 if (!ctx->nfs_server.hostname) 1094 goto out_nomem; | |
1095 1096 if (!(data->flags & NFS_MOUNT_NONLM)) 1097 ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| 1098 NFS_MOUNT_LOCAL_FCNTL); 1099 else 1100 ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK| 1101 NFS_MOUNT_LOCAL_FCNTL); 1102 /* 1103 * The legacy version 6 binary mount data from userspace has a 1104 * field used only to transport selinux information into the 1105 * the kernel. To continue to support that functionality we 1106 * have a touch of selinux knowledge here in the NFS code. The 1107 * userspace code converted context=blah to just blah so we are 1108 * converting back to the full string selinux understands. 1109 */ 1110 if (data->context[0]){ 1111#ifdef CONFIG_SECURITY_SELINUX | 1005 1006 if (!(data->flags & NFS_MOUNT_NONLM)) 1007 ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK| 1008 NFS_MOUNT_LOCAL_FCNTL); 1009 else 1010 ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK| 1011 NFS_MOUNT_LOCAL_FCNTL); 1012 /* 1013 * The legacy version 6 binary mount data from userspace has a 1014 * field used only to transport selinux information into the 1015 * the kernel. To continue to support that functionality we 1016 * have a touch of selinux knowledge here in the NFS code. The 1017 * userspace code converted context=blah to just blah so we are 1018 * converting back to the full string selinux understands. 1019 */ 1020 if (data->context[0]){ 1021#ifdef CONFIG_SECURITY_SELINUX |
1112 int rc; | 1022 int ret; 1023 |
1113 data->context[NFS_MAX_CONTEXT_LEN] = '\0'; | 1024 data->context[NFS_MAX_CONTEXT_LEN] = '\0'; |
1114 rc = security_add_mnt_opt("context", data->context, 1115 strlen(data->context), ctx->lsm_opts); 1116 if (rc) 1117 return rc; | 1025 ret = vfs_parse_fs_string(fc, "context", 1026 data->context, strlen(data->context)); 1027 if (ret < 0) 1028 return ret; |
1118#else 1119 return -EINVAL; 1120#endif 1121 } 1122 1123 break; 1124 default: | 1029#else 1030 return -EINVAL; 1031#endif 1032 } 1033 1034 break; 1035 default: |
1125 return NFS_TEXT_DATA; | 1036 goto generic; |
1126 } 1127 | 1037 } 1038 |
1039 ctx->skip_reconfig_option_check = true; |
|
1128 return 0; 1129 | 1040 return 0; 1041 |
1042generic: 1043 return generic_parse_monolithic(fc, data); 1044 |
|
1130out_no_data: | 1045out_no_data: |
1046 if (is_remount_fc(fc)) { 1047 ctx->skip_reconfig_option_check = true; 1048 return 0; 1049 } |
|
1131 dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n"); 1132 return -EINVAL; 1133 1134out_no_v3: 1135 dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n", 1136 data->version); 1137 return -EINVAL; 1138 --- 19 unchanged lines hidden (view full) --- 1158{ 1159 ctx->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3| 1160 NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL); 1161} 1162 1163/* 1164 * Validate NFSv4 mount options 1165 */ | 1050 dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n"); 1051 return -EINVAL; 1052 1053out_no_v3: 1054 dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n", 1055 data->version); 1056 return -EINVAL; 1057 --- 19 unchanged lines hidden (view full) --- 1077{ 1078 ctx->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3| 1079 NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL); 1080} 1081 1082/* 1083 * Validate NFSv4 mount options 1084 */ |
1166static int nfs4_validate_mount_data(void *options, 1167 struct nfs_fs_context *ctx, 1168 const char *dev_name) | 1085static int nfs4_parse_monolithic(struct fs_context *fc, 1086 struct nfs4_mount_data *data) |
1169{ | 1087{ |
1088 struct nfs_fs_context *ctx = nfs_fc2context(fc); |
|
1170 struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; | 1089 struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; |
1171 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; | |
1172 char *c; 1173 1174 if (data == NULL) 1175 goto out_no_data; 1176 1177 ctx->version = 4; 1178 1179 switch (data->version) { --- 33 unchanged lines hidden (view full) --- 1213 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); 1214 1215 c = strndup_user(data->client_addr.data, 16); 1216 if (IS_ERR(c)) 1217 return PTR_ERR(c); 1218 ctx->client_address = c; 1219 1220 /* | 1090 char *c; 1091 1092 if (data == NULL) 1093 goto out_no_data; 1094 1095 ctx->version = 4; 1096 1097 switch (data->version) { --- 33 unchanged lines hidden (view full) --- 1131 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c); 1132 1133 c = strndup_user(data->client_addr.data, 16); 1134 if (IS_ERR(c)) 1135 return PTR_ERR(c); 1136 ctx->client_address = c; 1137 1138 /* |
1221 * Translate to nfs_fs_context, which nfs4_fill_super | 1139 * Translate to nfs_fs_context, which nfs_fill_super |
1222 * can deal with. 1223 */ 1224 1225 ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK; 1226 ctx->rsize = data->rsize; 1227 ctx->wsize = data->wsize; 1228 ctx->timeo = data->timeo; 1229 ctx->retrans = data->retrans; 1230 ctx->acregmin = data->acregmin; 1231 ctx->acregmax = data->acregmax; 1232 ctx->acdirmin = data->acdirmin; 1233 ctx->acdirmax = data->acdirmax; 1234 ctx->nfs_server.protocol = data->proto; 1235 nfs_validate_transport_protocol(ctx); 1236 if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1237 goto out_invalid_transport_udp; 1238 1239 break; 1240 default: | 1140 * can deal with. 1141 */ 1142 1143 ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK; 1144 ctx->rsize = data->rsize; 1145 ctx->wsize = data->wsize; 1146 ctx->timeo = data->timeo; 1147 ctx->retrans = data->retrans; 1148 ctx->acregmin = data->acregmin; 1149 ctx->acregmax = data->acregmax; 1150 ctx->acdirmin = data->acdirmin; 1151 ctx->acdirmax = data->acdirmax; 1152 ctx->nfs_server.protocol = data->proto; 1153 nfs_validate_transport_protocol(ctx); 1154 if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP) 1155 goto out_invalid_transport_udp; 1156 1157 break; 1158 default: |
1241 return NFS_TEXT_DATA; | 1159 goto generic; |
1242 } 1243 | 1160 } 1161 |
1162 ctx->skip_reconfig_option_check = true; |
|
1244 return 0; 1245 | 1163 return 0; 1164 |
1165generic: 1166 return generic_parse_monolithic(fc, data); 1167 |
|
1246out_no_data: | 1168out_no_data: |
1169 if (is_remount_fc(fc)) { 1170 ctx->skip_reconfig_option_check = true; 1171 return 0; 1172 } |
|
1247 dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n"); 1248 return -EINVAL; 1249 1250out_inval_auth: 1251 dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n", 1252 data->auth_flavourlen); 1253 return -EINVAL; 1254 1255out_no_address: 1256 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 1257 return -EINVAL; 1258 1259out_invalid_transport_udp: 1260 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); 1261 return -EINVAL; 1262} | 1173 dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n"); 1174 return -EINVAL; 1175 1176out_inval_auth: 1177 dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n", 1178 data->auth_flavourlen); 1179 return -EINVAL; 1180 1181out_no_address: 1182 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); 1183 return -EINVAL; 1184 1185out_invalid_transport_udp: 1186 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); 1187 return -EINVAL; 1188} |
1189#endif |
|
1263 | 1190 |
1264int nfs_validate_mount_data(struct file_system_type *fs_type, 1265 void *options, 1266 struct nfs_fs_context *ctx, 1267 struct nfs_fh *mntfh, 1268 const char *dev_name) | 1191/* 1192 * Parse a monolithic block of data from sys_mount(). 1193 */ 1194static int nfs_fs_context_parse_monolithic(struct fs_context *fc, 1195 void *data) |
1269{ | 1196{ |
1270 if (fs_type == &nfs_fs_type) 1271 return nfs23_validate_mount_data(options, ctx, mntfh, dev_name); 1272 return nfs4_validate_mount_data(options, ctx, dev_name); 1273} 1274#else 1275int nfs_validate_mount_data(struct file_system_type *fs_type, 1276 void *options, 1277 struct nfs_fs_context *ctx, 1278 struct nfs_fh *mntfh, 1279 const char *dev_name) 1280{ 1281 return nfs23_validate_mount_data(options, ctx, mntfh, dev_name); 1282} | 1197 if (fc->fs_type == &nfs_fs_type) 1198 return nfs23_parse_monolithic(fc, data); 1199 1200#if IS_ENABLED(CONFIG_NFS_V4) 1201 if (fc->fs_type == &nfs4_fs_type) 1202 return nfs4_parse_monolithic(fc, data); |
1283#endif 1284 | 1203#endif 1204 |
1285int nfs_validate_text_mount_data(void *options, 1286 struct nfs_fs_context *ctx, 1287 const char *dev_name) | 1205 dfprintk(MOUNT, "NFS: Unsupported monolithic data version\n"); 1206 return -EINVAL; 1207} 1208 1209/* 1210 * Validate the preparsed information in the config. 1211 */ 1212static int nfs_fs_context_validate(struct fs_context *fc) |
1288{ | 1213{ |
1289 int port = 0; | 1214 struct nfs_fs_context *ctx = nfs_fc2context(fc); 1215 struct nfs_subversion *nfs_mod; 1216 struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; |
1290 int max_namelen = PAGE_SIZE; 1291 int max_pathlen = NFS_MAXPATHLEN; | 1217 int max_namelen = PAGE_SIZE; 1218 int max_pathlen = NFS_MAXPATHLEN; |
1292 struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address; | 1219 int port = 0; 1220 int ret; |
1293 | 1221 |
1294 if (nfs_parse_mount_options((char *)options, ctx) == 0) 1295 return -EINVAL; | 1222 if (!fc->source) 1223 goto out_no_device_name; |
1296 | 1224 |
1225 /* Check for sanity first. */ 1226 if (ctx->minorversion && ctx->version != 4) 1227 goto out_minorversion_mismatch; 1228 1229 if (ctx->options & NFS_OPTION_MIGRATION && 1230 (ctx->version != 4 || ctx->minorversion != 0)) 1231 goto out_migration_misuse; 1232 1233 /* Verify that any proto=/mountproto= options match the address 1234 * families in the addr=/mountaddr= options. 1235 */ 1236 if (ctx->protofamily != AF_UNSPEC && 1237 ctx->protofamily != ctx->nfs_server.address.sa_family) 1238 goto out_proto_mismatch; 1239 1240 if (ctx->mountfamily != AF_UNSPEC) { 1241 if (ctx->mount_server.addrlen) { 1242 if (ctx->mountfamily != ctx->mount_server.address.sa_family) 1243 goto out_mountproto_mismatch; 1244 } else { 1245 if (ctx->mountfamily != ctx->nfs_server.address.sa_family) 1246 goto out_mountproto_mismatch; 1247 } 1248 } 1249 |
|
1297 if (!nfs_verify_server_address(sap)) 1298 goto out_no_address; 1299 1300 if (ctx->version == 4) { 1301#if IS_ENABLED(CONFIG_NFS_V4) 1302 if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1303 port = NFS_RDMA_PORT; 1304 else --- 10 unchanged lines hidden (view full) --- 1315 } else { 1316 nfs_set_mount_transport_protocol(ctx); 1317 if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1318 port = NFS_RDMA_PORT; 1319 } 1320 1321 nfs_set_port(sap, &ctx->nfs_server.port, port); 1322 | 1250 if (!nfs_verify_server_address(sap)) 1251 goto out_no_address; 1252 1253 if (ctx->version == 4) { 1254#if IS_ENABLED(CONFIG_NFS_V4) 1255 if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1256 port = NFS_RDMA_PORT; 1257 else --- 10 unchanged lines hidden (view full) --- 1268 } else { 1269 nfs_set_mount_transport_protocol(ctx); 1270 if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA) 1271 port = NFS_RDMA_PORT; 1272 } 1273 1274 nfs_set_port(sap, &ctx->nfs_server.port, port); 1275 |
1323 return nfs_parse_devname(ctx, dev_name, max_namelen, max_pathlen); | 1276 ret = nfs_parse_devname(ctx, fc->source, max_namelen, max_pathlen); 1277 if (ret < 0) 1278 return ret; |
1324 | 1279 |
1280 /* Load the NFS protocol module if we haven't done so yet */ 1281 if (!ctx->mount_info.nfs_mod) { 1282 nfs_mod = get_nfs_version(ctx->version); 1283 if (IS_ERR(nfs_mod)) { 1284 ret = PTR_ERR(nfs_mod); 1285 goto out_version_unavailable; 1286 } 1287 ctx->mount_info.nfs_mod = nfs_mod; 1288 } 1289 return 0; 1290 1291out_no_device_name: 1292 dfprintk(MOUNT, "NFS: Device name not specified\n"); 1293 return -EINVAL; |
|
1325#if !IS_ENABLED(CONFIG_NFS_V4) 1326out_v4_not_compiled: 1327 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); 1328 return -EPROTONOSUPPORT; 1329#else 1330out_invalid_transport_udp: 1331 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); 1332 return -EINVAL; 1333#endif /* !CONFIG_NFS_V4 */ | 1294#if !IS_ENABLED(CONFIG_NFS_V4) 1295out_v4_not_compiled: 1296 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); 1297 return -EPROTONOSUPPORT; 1298#else 1299out_invalid_transport_udp: 1300 dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n"); 1301 return -EINVAL; 1302#endif /* !CONFIG_NFS_V4 */ |
1334 | |
1335out_no_address: 1336 dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); 1337 return -EINVAL; | 1303out_no_address: 1304 dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); 1305 return -EINVAL; |
1306out_mountproto_mismatch: 1307 dfprintk(MOUNT, "NFS: Mount server address does not match mountproto= option\n"); 1308 return -EINVAL; 1309out_proto_mismatch: 1310 dfprintk(MOUNT, "NFS: Server address does not match proto= option\n"); 1311 return -EINVAL; 1312out_minorversion_mismatch: 1313 dfprintk(MOUNT, "NFS: Mount option vers=%u does not support minorversion=%u\n", 1314 ctx->version, ctx->minorversion); 1315 return -EINVAL; 1316out_migration_misuse: 1317 dfprintk(MOUNT, "NFS: 'Migration' not supported for this NFS version\n"); 1318 return -EINVAL; 1319out_version_unavailable: 1320 dfprintk(MOUNT, "NFS: Version unavailable\n"); 1321 return ret; |
|
1338} | 1322} |
1323 1324/* 1325 * Create an NFS superblock by the appropriate method. 1326 */ 1327static int nfs_get_tree(struct fs_context *fc) 1328{ 1329 struct nfs_fs_context *ctx = nfs_fc2context(fc); 1330 int err = nfs_fs_context_validate(fc); 1331 1332 if (err) 1333 return err; 1334 if (!ctx->internal) 1335 return ctx->mount_info.nfs_mod->rpc_ops->try_get_tree(fc); 1336 else 1337 return nfs_get_tree_common(fc); 1338} 1339 1340/* 1341 * Handle duplication of a configuration. The caller copied *src into *sc, but 1342 * it can't deal with resource pointers in the filesystem context, so we have 1343 * to do that. We need to clear pointers, copy data or get extra refs as 1344 * appropriate. 1345 */ 1346static int nfs_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) 1347{ 1348 struct nfs_fs_context *src = nfs_fc2context(src_fc), *ctx; 1349 1350 ctx = kmemdup(src, sizeof(struct nfs_fs_context), GFP_KERNEL); 1351 if (!ctx) 1352 return -ENOMEM; 1353 1354 ctx->mount_info.mntfh = nfs_alloc_fhandle(); 1355 if (!ctx->mount_info.mntfh) { 1356 kfree(ctx); 1357 return -ENOMEM; 1358 } 1359 nfs_copy_fh(ctx->mount_info.mntfh, src->mount_info.mntfh); 1360 1361 __module_get(ctx->mount_info.nfs_mod->owner); 1362 ctx->client_address = NULL; 1363 ctx->mount_server.hostname = NULL; 1364 ctx->nfs_server.export_path = NULL; 1365 ctx->nfs_server.hostname = NULL; 1366 ctx->fscache_uniq = NULL; 1367 ctx->clone_data.addr = NULL; 1368 ctx->clone_data.fattr = NULL; 1369 fc->fs_private = ctx; 1370 return 0; 1371} 1372 1373static void nfs_fs_context_free(struct fs_context *fc) 1374{ 1375 struct nfs_fs_context *ctx = nfs_fc2context(fc); 1376 1377 if (ctx) { 1378 if (ctx->mount_info.server) 1379 nfs_free_server(ctx->mount_info.server); 1380 if (ctx->mount_info.nfs_mod) 1381 put_nfs_version(ctx->mount_info.nfs_mod); 1382 kfree(ctx->client_address); 1383 kfree(ctx->mount_server.hostname); 1384 kfree(ctx->nfs_server.export_path); 1385 kfree(ctx->nfs_server.hostname); 1386 kfree(ctx->fscache_uniq); 1387 nfs_free_fhandle(ctx->mount_info.mntfh); 1388 kfree(ctx->clone_data.addr); 1389 nfs_free_fattr(ctx->clone_data.fattr); 1390 kfree(ctx); 1391 } 1392} 1393 1394static const struct fs_context_operations nfs_fs_context_ops = { 1395 .free = nfs_fs_context_free, 1396 .dup = nfs_fs_context_dup, 1397 .parse_param = nfs_fs_context_parse_param, 1398 .parse_monolithic = nfs_fs_context_parse_monolithic, 1399 .get_tree = nfs_get_tree, 1400 .reconfigure = nfs_reconfigure, 1401}; 1402 1403/* 1404 * Prepare superblock configuration. We use the namespaces attached to the 1405 * context. This may be the current process's namespaces, or it may be a 1406 * container's namespaces. 1407 */ 1408static int nfs_init_fs_context(struct fs_context *fc) 1409{ 1410 struct nfs_fs_context *ctx; 1411 1412 ctx = kzalloc(sizeof(struct nfs_fs_context), GFP_KERNEL); 1413 if (unlikely(!ctx)) 1414 return -ENOMEM; 1415 1416 ctx->mount_info.ctx = ctx; 1417 ctx->mount_info.mntfh = nfs_alloc_fhandle(); 1418 if (unlikely(!ctx->mount_info.mntfh)) { 1419 kfree(ctx); 1420 return -ENOMEM; 1421 } 1422 1423 ctx->protofamily = AF_UNSPEC; 1424 ctx->mountfamily = AF_UNSPEC; 1425 ctx->mount_server.port = NFS_UNSPEC_PORT; 1426 1427 if (fc->root) { 1428 /* reconfigure, start with the current config */ 1429 struct nfs_server *nfss = fc->root->d_sb->s_fs_info; 1430 struct net *net = nfss->nfs_client->cl_net; 1431 1432 ctx->flags = nfss->flags; 1433 ctx->rsize = nfss->rsize; 1434 ctx->wsize = nfss->wsize; 1435 ctx->retrans = nfss->client->cl_timeout->to_retries; 1436 ctx->selected_flavor = nfss->client->cl_auth->au_flavor; 1437 ctx->acregmin = nfss->acregmin / HZ; 1438 ctx->acregmax = nfss->acregmax / HZ; 1439 ctx->acdirmin = nfss->acdirmin / HZ; 1440 ctx->acdirmax = nfss->acdirmax / HZ; 1441 ctx->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; 1442 ctx->nfs_server.port = nfss->port; 1443 ctx->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; 1444 ctx->version = nfss->nfs_client->rpc_ops->version; 1445 ctx->minorversion = nfss->nfs_client->cl_minorversion; 1446 1447 memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr, 1448 ctx->nfs_server.addrlen); 1449 1450 if (fc->net_ns != net) { 1451 put_net(fc->net_ns); 1452 fc->net_ns = get_net(net); 1453 } 1454 1455 ctx->mount_info.nfs_mod = nfss->nfs_client->cl_nfs_mod; 1456 __module_get(ctx->mount_info.nfs_mod->owner); 1457 } else { 1458 /* defaults */ 1459 ctx->timeo = NFS_UNSPEC_TIMEO; 1460 ctx->retrans = NFS_UNSPEC_RETRANS; 1461 ctx->acregmin = NFS_DEF_ACREGMIN; 1462 ctx->acregmax = NFS_DEF_ACREGMAX; 1463 ctx->acdirmin = NFS_DEF_ACDIRMIN; 1464 ctx->acdirmax = NFS_DEF_ACDIRMAX; 1465 ctx->nfs_server.port = NFS_UNSPEC_PORT; 1466 ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1467 ctx->selected_flavor = RPC_AUTH_MAXFLAVOR; 1468 ctx->minorversion = 0; 1469 ctx->need_mount = true; 1470 } 1471 ctx->net = fc->net_ns; 1472 fc->fs_private = ctx; 1473 fc->ops = &nfs_fs_context_ops; 1474 return 0; 1475} 1476 1477struct file_system_type nfs_fs_type = { 1478 .owner = THIS_MODULE, 1479 .name = "nfs", 1480 .init_fs_context = nfs_init_fs_context, 1481 .parameters = &nfs_fs_parameters, 1482 .kill_sb = nfs_kill_super, 1483 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 1484}; 1485MODULE_ALIAS_FS("nfs"); 1486EXPORT_SYMBOL_GPL(nfs_fs_type); 1487 1488#if IS_ENABLED(CONFIG_NFS_V4) 1489struct file_system_type nfs4_fs_type = { 1490 .owner = THIS_MODULE, 1491 .name = "nfs4", 1492 .init_fs_context = nfs_init_fs_context, 1493 .parameters = &nfs_fs_parameters, 1494 .kill_sb = nfs_kill_super, 1495 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, 1496}; 1497MODULE_ALIAS_FS("nfs4"); 1498MODULE_ALIAS("nfs4"); 1499EXPORT_SYMBOL_GPL(nfs4_fs_type); 1500#endif /* CONFIG_NFS_V4 */ |
|