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(&param, 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, &param);
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 */