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.c203
1 files changed, 128 insertions, 75 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 4bbdbf6de417..47cf83e917be 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -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};
@@ -103,6 +103,8 @@ static match_table_t nfs_mount_option_tokens = {
103 { Opt_userspace, "fg" }, 103 { Opt_userspace, "fg" },
104 { Opt_userspace, "retry=%s" }, 104 { Opt_userspace, "retry=%s" },
105 105
106 { Opt_sloppy, "sloppy" },
107
106 { Opt_soft, "soft" }, 108 { Opt_soft, "soft" },
107 { Opt_hard, "hard" }, 109 { Opt_hard, "hard" },
108 { Opt_deprecated, "intr" }, 110 { Opt_deprecated, "intr" },
@@ -917,15 +919,22 @@ static int nfs_parse_security_flavors(char *value,
917 return 1; 919 return 1;
918} 920}
919 921
922static void nfs_parse_invalid_value(const char *option)
923{
924 dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option);
925}
926
920/* 927/*
921 * 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
922 * 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).
923 */ 932 */
924static int nfs_parse_mount_options(char *raw, 933static int nfs_parse_mount_options(char *raw,
925 struct nfs_parsed_mount_data *mnt) 934 struct nfs_parsed_mount_data *mnt)
926{ 935{
927 char *p, *string, *secdata; 936 char *p, *string, *secdata;
928 int rc; 937 int rc, sloppy = 0, errors = 0;
929 938
930 if (!raw) { 939 if (!raw) {
931 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 940 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -958,6 +967,10 @@ static int nfs_parse_mount_options(char *raw,
958 967
959 token = match_token(p, nfs_mount_option_tokens, args); 968 token = match_token(p, nfs_mount_option_tokens, args);
960 switch (token) { 969 switch (token) {
970
971 /*
972 * boolean options: foo/nofoo
973 */
961 case Opt_soft: 974 case Opt_soft:
962 mnt->flags |= NFS_MOUNT_SOFT; 975 mnt->flags |= NFS_MOUNT_SOFT;
963 break; 976 break;
@@ -1025,103 +1038,145 @@ static int nfs_parse_mount_options(char *raw,
1025 mnt->flags |= NFS_MOUNT_UNSHARED; 1038 mnt->flags |= NFS_MOUNT_UNSHARED;
1026 break; 1039 break;
1027 1040
1041 /*
1042 * options that take numeric values
1043 */
1028 case Opt_port: 1044 case Opt_port:
1029 if (match_int(args, &option)) 1045 if (match_int(args, &option) ||
1030 return 0; 1046 option < 0 || option > USHORT_MAX) {
1031 if (option < 0 || option > 65535) 1047 errors++;
1032 return 0; 1048 nfs_parse_invalid_value("port");
1033 mnt->nfs_server.port = option; 1049 } else
1050 mnt->nfs_server.port = option;
1034 break; 1051 break;
1035 case Opt_rsize: 1052 case Opt_rsize:
1036 if (match_int(args, &mnt->rsize)) 1053 if (match_int(args, &option) || option < 0) {
1037 return 0; 1054 errors++;
1055 nfs_parse_invalid_value("rsize");
1056 } else
1057 mnt->rsize = option;
1038 break; 1058 break;
1039 case Opt_wsize: 1059 case Opt_wsize:
1040 if (match_int(args, &mnt->wsize)) 1060 if (match_int(args, &option) || option < 0) {
1041 return 0; 1061 errors++;
1062 nfs_parse_invalid_value("wsize");
1063 } else
1064 mnt->wsize = option;
1042 break; 1065 break;
1043 case Opt_bsize: 1066 case Opt_bsize:
1044 if (match_int(args, &option)) 1067 if (match_int(args, &option) || option < 0) {
1045 return 0; 1068 errors++;
1046 if (option < 0) 1069 nfs_parse_invalid_value("bsize");
1047 return 0; 1070 } else
1048 mnt->bsize = option; 1071 mnt->bsize = option;
1049 break; 1072 break;
1050 case Opt_timeo: 1073 case Opt_timeo:
1051 if (match_int(args, &mnt->timeo)) 1074 if (match_int(args, &option) || option <= 0) {
1052 return 0; 1075 errors++;
1076 nfs_parse_invalid_value("timeo");
1077 } else
1078 mnt->timeo = option;
1053 break; 1079 break;
1054 case Opt_retrans: 1080 case Opt_retrans:
1055 if (match_int(args, &mnt->retrans)) 1081 if (match_int(args, &option) || option <= 0) {
1056 return 0; 1082 errors++;
1083 nfs_parse_invalid_value("retrans");
1084 } else
1085 mnt->retrans = option;
1057 break; 1086 break;
1058 case Opt_acregmin: 1087 case Opt_acregmin:
1059 if (match_int(args, &mnt->acregmin)) 1088 if (match_int(args, &option) || option < 0) {
1060 return 0; 1089 errors++;
1090 nfs_parse_invalid_value("acregmin");
1091 } else
1092 mnt->acregmin = option;
1061 break; 1093 break;
1062 case Opt_acregmax: 1094 case Opt_acregmax:
1063 if (match_int(args, &mnt->acregmax)) 1095 if (match_int(args, &option) || option < 0) {
1064 return 0; 1096 errors++;
1097 nfs_parse_invalid_value("acregmax");
1098 } else
1099 mnt->acregmax = option;
1065 break; 1100 break;
1066 case Opt_acdirmin: 1101 case Opt_acdirmin:
1067 if (match_int(args, &mnt->acdirmin)) 1102 if (match_int(args, &option) || option < 0) {
1068 return 0; 1103 errors++;
1104 nfs_parse_invalid_value("acdirmin");
1105 } else
1106 mnt->acdirmin = option;
1069 break; 1107 break;
1070 case Opt_acdirmax: 1108 case Opt_acdirmax:
1071 if (match_int(args, &mnt->acdirmax)) 1109 if (match_int(args, &option) || option < 0) {
1072 return 0; 1110 errors++;
1111 nfs_parse_invalid_value("acdirmax");
1112 } else
1113 mnt->acdirmax = option;
1073 break; 1114 break;
1074 case Opt_actimeo: 1115 case Opt_actimeo:
1075 if (match_int(args, &option)) 1116 if (match_int(args, &option) || option < 0) {
1076 return 0; 1117 errors++;
1077 if (option < 0) 1118 nfs_parse_invalid_value("actimeo");
1078 return 0; 1119 } else
1079 mnt->acregmin = 1120 mnt->acregmin = mnt->acregmax =
1080 mnt->acregmax = 1121 mnt->acdirmin = mnt->acdirmax = option;
1081 mnt->acdirmin =
1082 mnt->acdirmax = option;
1083 break; 1122 break;
1084 case Opt_namelen: 1123 case Opt_namelen:
1085 if (match_int(args, &mnt->namlen)) 1124 if (match_int(args, &option) || option < 0) {
1086 return 0; 1125 errors++;
1126 nfs_parse_invalid_value("namlen");
1127 } else
1128 mnt->namlen = option;
1087 break; 1129 break;
1088 case Opt_mountport: 1130 case Opt_mountport:
1089 if (match_int(args, &option)) 1131 if (match_int(args, &option) ||
1090 return 0; 1132 option < 0 || option > USHORT_MAX) {
1091 if (option < 0 || option > 65535) 1133 errors++;
1092 return 0; 1134 nfs_parse_invalid_value("mountport");
1093 mnt->mount_server.port = option; 1135 } else
1136 mnt->mount_server.port = option;
1094 break; 1137 break;
1095 case Opt_mountvers: 1138 case Opt_mountvers:
1096 if (match_int(args, &option)) 1139 if (match_int(args, &option) ||
1097 return 0; 1140 option < NFS_MNT_VERSION ||
1098 if (option < 0) 1141 option > NFS_MNT3_VERSION) {
1099 return 0; 1142 errors++;
1100 mnt->mount_server.version = option; 1143 nfs_parse_invalid_value("mountvers");
1144 } else
1145 mnt->mount_server.version = option;
1101 break; 1146 break;
1102 case Opt_nfsvers: 1147 case Opt_nfsvers:
1103 if (match_int(args, &option)) 1148 if (match_int(args, &option)) {
1104 return 0; 1149 errors++;
1150 nfs_parse_invalid_value("nfsvers");
1151 break;
1152 }
1105 switch (option) { 1153 switch (option) {
1106 case 2: 1154 case NFS2_VERSION:
1107 mnt->flags &= ~NFS_MOUNT_VER3; 1155 mnt->flags &= ~NFS_MOUNT_VER3;
1108 break; 1156 break;
1109 case 3: 1157 case NFS3_VERSION:
1110 mnt->flags |= NFS_MOUNT_VER3; 1158 mnt->flags |= NFS_MOUNT_VER3;
1111 break; 1159 break;
1112 default: 1160 default:
1113 goto out_unrec_vers; 1161 errors++;
1162 nfs_parse_invalid_value("nfsvers");
1114 } 1163 }
1115 break; 1164 break;
1116 1165
1166 /*
1167 * options that take text values
1168 */
1117 case Opt_sec: 1169 case Opt_sec:
1118 string = match_strdup(args); 1170 string = match_strdup(args);
1119 if (string == NULL) 1171 if (string == NULL)
1120 goto out_nomem; 1172 goto out_nomem;
1121 rc = nfs_parse_security_flavors(string, mnt); 1173 rc = nfs_parse_security_flavors(string, mnt);
1122 kfree(string); 1174 kfree(string);
1123 if (!rc) 1175 if (!rc) {
1124 goto out_unrec_sec; 1176 errors++;
1177 dfprintk(MOUNT, "NFS: unrecognized "
1178 "security flavor\n");
1179 }
1125 break; 1180 break;
1126 case Opt_proto: 1181 case Opt_proto:
1127 string = match_strdup(args); 1182 string = match_strdup(args);
@@ -1146,7 +1201,9 @@ static int nfs_parse_mount_options(char *raw,
1146 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1201 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
1147 break; 1202 break;
1148 default: 1203 default:
1149 goto out_unrec_xprt; 1204 errors++;
1205 dfprintk(MOUNT, "NFS: unrecognized "
1206 "transport protocol\n");
1150 } 1207 }
1151 break; 1208 break;
1152 case Opt_mountproto: 1209 case Opt_mountproto:
@@ -1166,7 +1223,9 @@ static int nfs_parse_mount_options(char *raw,
1166 break; 1223 break;
1167 case Opt_xprt_rdma: /* not used for side protocols */ 1224 case Opt_xprt_rdma: /* not used for side protocols */
1168 default: 1225 default:
1169 goto out_unrec_xprt; 1226 errors++;
1227 dfprintk(MOUNT, "NFS: unrecognized "
1228 "transport protocol\n");
1170 } 1229 }
1171 break; 1230 break;
1172 case Opt_addr: 1231 case Opt_addr:
@@ -1204,6 +1263,13 @@ static int nfs_parse_mount_options(char *raw,
1204 kfree(string); 1263 kfree(string);
1205 break; 1264 break;
1206 1265
1266 /*
1267 * Special options
1268 */
1269 case Opt_sloppy:
1270 sloppy = 1;
1271 dfprintk(MOUNT, "NFS: relaxing parsing rules\n");
1272 break;
1207 case Opt_userspace: 1273 case Opt_userspace:
1208 case Opt_deprecated: 1274 case Opt_deprecated:
1209 dfprintk(MOUNT, "NFS: ignoring mount option " 1275 dfprintk(MOUNT, "NFS: ignoring mount option "
@@ -1211,7 +1277,9 @@ static int nfs_parse_mount_options(char *raw,
1211 break; 1277 break;
1212 1278
1213 default: 1279 default:
1214 goto out_unknown; 1280 errors++;
1281 dfprintk(MOUNT, "NFS: unrecognized mount option "
1282 "'%s'\n", p);
1215 } 1283 }
1216 } 1284 }
1217 1285
@@ -1224,21 +1292,6 @@ out_security_failure:
1224 free_secdata(secdata); 1292 free_secdata(secdata);
1225 printk(KERN_INFO "NFS: security options invalid: %d\n", rc); 1293 printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
1226 return 0; 1294 return 0;
1227out_unrec_vers:
1228 printk(KERN_INFO "NFS: unrecognized NFS version number\n");
1229 return 0;
1230
1231out_unrec_xprt:
1232 printk(KERN_INFO "NFS: unrecognized transport protocol\n");
1233 return 0;
1234
1235out_unrec_sec:
1236 printk(KERN_INFO "NFS: unrecognized security flavor\n");
1237 return 0;
1238
1239out_unknown:
1240 printk(KERN_INFO "NFS: unknown mount option: %s\n", p);
1241 return 0;
1242} 1295}
1243 1296
1244/* 1297/*