aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-06-17 21:02:14 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 21:02:14 -0400
commita5a16bae707cd5d2bc97d7bd1a30079f18113a77 (patch)
treedbd8012bbba334e92edae060806eebc73d4338ad /fs
parentd23c45fd84f79a3b84899dac053dcafe9d43ebc9 (diff)
NFS: More "sloppy" parsing problems
Specifying "port=-5" with the kernel's current mount option parser generates "unrecognized mount option". If "sloppy" is set, this causes the mount to succeed and use the default values; the desired behavior is that, since this is a valid option with an invalid value, the mount should fail, even with "sloppy." To properly handle "sloppy" parsing, we need to distinguish between correct options with invalid values, and incorrect options. We will need to parse integer values by hand, therefore, and not rely on match_token(). For instance, these must all fail with "invalid value": port=12345678 port=-5 port=samuel and not with "unrecognized option," as they do currently. Thus, for the sake of match_token() we need to treat the values for these options as strings, and do the conversion to integers using strict_strtol(). This is basically the same solution we used for the earlier "retry=" fix (commit ecbb3845), except in this case the kernel actually has to parse the value, rather than ignore it. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/super.c142
1 files changed, 108 insertions, 34 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a2b2805caf9d..b798ed1bd36d 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -139,22 +139,22 @@ static const match_table_t nfs_mount_option_tokens = {
139 { Opt_fscache_uniq, "fsc=%s" }, 139 { Opt_fscache_uniq, "fsc=%s" },
140 { Opt_nofscache, "nofsc" }, 140 { Opt_nofscache, "nofsc" },
141 141
142 { Opt_port, "port=%u" }, 142 { Opt_port, "port=%s" },
143 { Opt_rsize, "rsize=%u" }, 143 { Opt_rsize, "rsize=%s" },
144 { Opt_wsize, "wsize=%u" }, 144 { Opt_wsize, "wsize=%s" },
145 { Opt_bsize, "bsize=%u" }, 145 { Opt_bsize, "bsize=%s" },
146 { Opt_timeo, "timeo=%u" }, 146 { Opt_timeo, "timeo=%s" },
147 { Opt_retrans, "retrans=%u" }, 147 { Opt_retrans, "retrans=%s" },
148 { Opt_acregmin, "acregmin=%u" }, 148 { Opt_acregmin, "acregmin=%s" },
149 { Opt_acregmax, "acregmax=%u" }, 149 { Opt_acregmax, "acregmax=%s" },
150 { Opt_acdirmin, "acdirmin=%u" }, 150 { Opt_acdirmin, "acdirmin=%s" },
151 { Opt_acdirmax, "acdirmax=%u" }, 151 { Opt_acdirmax, "acdirmax=%s" },
152 { Opt_actimeo, "actimeo=%u" }, 152 { Opt_actimeo, "actimeo=%s" },
153 { Opt_namelen, "namlen=%u" }, 153 { Opt_namelen, "namlen=%s" },
154 { Opt_mountport, "mountport=%u" }, 154 { Opt_mountport, "mountport=%s" },
155 { Opt_mountvers, "mountvers=%u" }, 155 { Opt_mountvers, "mountvers=%s" },
156 { Opt_nfsvers, "nfsvers=%u" }, 156 { Opt_nfsvers, "nfsvers=%s" },
157 { Opt_nfsvers, "vers=%u" }, 157 { Opt_nfsvers, "vers=%s" },
158 158
159 { Opt_sec, "sec=%s" }, 159 { Opt_sec, "sec=%s" },
160 { Opt_proto, "proto=%s" }, 160 { Opt_proto, "proto=%s" },
@@ -976,7 +976,8 @@ static int nfs_parse_mount_options(char *raw,
976 976
977 while ((p = strsep(&raw, ",")) != NULL) { 977 while ((p = strsep(&raw, ",")) != NULL) {
978 substring_t args[MAX_OPT_ARGS]; 978 substring_t args[MAX_OPT_ARGS];
979 int option, token; 979 unsigned long option;
980 int token;
980 981
981 if (!*p) 982 if (!*p)
982 continue; 983 continue;
@@ -1085,82 +1086,155 @@ static int nfs_parse_mount_options(char *raw,
1085 * options that take numeric values 1086 * options that take numeric values
1086 */ 1087 */
1087 case Opt_port: 1088 case Opt_port:
1088 if (match_int(args, &option) || 1089 string = match_strdup(args);
1089 option < 0 || option > USHORT_MAX) 1090 if (string == NULL)
1091 goto out_nomem;
1092 rc = strict_strtoul(string, 10, &option);
1093 kfree(string);
1094 if (rc != 0 || option > USHORT_MAX)
1090 goto out_invalid_value; 1095 goto out_invalid_value;
1091 mnt->nfs_server.port = option; 1096 mnt->nfs_server.port = option;
1092 break; 1097 break;
1093 case Opt_rsize: 1098 case Opt_rsize:
1094 if (match_int(args, &option) || option < 0) 1099 string = match_strdup(args);
1100 if (string == NULL)
1101 goto out_nomem;
1102 rc = strict_strtoul(string, 10, &option);
1103 kfree(string);
1104 if (rc != 0)
1095 goto out_invalid_value; 1105 goto out_invalid_value;
1096 mnt->rsize = option; 1106 mnt->rsize = option;
1097 break; 1107 break;
1098 case Opt_wsize: 1108 case Opt_wsize:
1099 if (match_int(args, &option) || option < 0) 1109 string = match_strdup(args);
1110 if (string == NULL)
1111 goto out_nomem;
1112 rc = strict_strtoul(string, 10, &option);
1113 kfree(string);
1114 if (rc != 0)
1100 goto out_invalid_value; 1115 goto out_invalid_value;
1101 mnt->wsize = option; 1116 mnt->wsize = option;
1102 break; 1117 break;
1103 case Opt_bsize: 1118 case Opt_bsize:
1104 if (match_int(args, &option) || option < 0) 1119 string = match_strdup(args);
1120 if (string == NULL)
1121 goto out_nomem;
1122 rc = strict_strtoul(string, 10, &option);
1123 kfree(string);
1124 if (rc != 0)
1105 goto out_invalid_value; 1125 goto out_invalid_value;
1106 mnt->bsize = option; 1126 mnt->bsize = option;
1107 break; 1127 break;
1108 case Opt_timeo: 1128 case Opt_timeo:
1109 if (match_int(args, &option) || option <= 0) 1129 string = match_strdup(args);
1130 if (string == NULL)
1131 goto out_nomem;
1132 rc = strict_strtoul(string, 10, &option);
1133 kfree(string);
1134 if (rc != 0 || option == 0)
1110 goto out_invalid_value; 1135 goto out_invalid_value;
1111 mnt->timeo = option; 1136 mnt->timeo = option;
1112 break; 1137 break;
1113 case Opt_retrans: 1138 case Opt_retrans:
1114 if (match_int(args, &option) || option <= 0) 1139 string = match_strdup(args);
1140 if (string == NULL)
1141 goto out_nomem;
1142 rc = strict_strtoul(string, 10, &option);
1143 kfree(string);
1144 if (rc != 0 || option == 0)
1115 goto out_invalid_value; 1145 goto out_invalid_value;
1116 mnt->retrans = option; 1146 mnt->retrans = option;
1117 break; 1147 break;
1118 case Opt_acregmin: 1148 case Opt_acregmin:
1119 if (match_int(args, &option) || option < 0) 1149 string = match_strdup(args);
1150 if (string == NULL)
1151 goto out_nomem;
1152 rc = strict_strtoul(string, 10, &option);
1153 kfree(string);
1154 if (rc != 0)
1120 goto out_invalid_value; 1155 goto out_invalid_value;
1121 mnt->acregmin = option; 1156 mnt->acregmin = option;
1122 break; 1157 break;
1123 case Opt_acregmax: 1158 case Opt_acregmax:
1124 if (match_int(args, &option) || option < 0) 1159 string = match_strdup(args);
1160 if (string == NULL)
1161 goto out_nomem;
1162 rc = strict_strtoul(string, 10, &option);
1163 kfree(string);
1164 if (rc != 0)
1125 goto out_invalid_value; 1165 goto out_invalid_value;
1126 mnt->acregmax = option; 1166 mnt->acregmax = option;
1127 break; 1167 break;
1128 case Opt_acdirmin: 1168 case Opt_acdirmin:
1129 if (match_int(args, &option) || option < 0) 1169 string = match_strdup(args);
1170 if (string == NULL)
1171 goto out_nomem;
1172 rc = strict_strtoul(string, 10, &option);
1173 kfree(string);
1174 if (rc != 0)
1130 goto out_invalid_value; 1175 goto out_invalid_value;
1131 mnt->acdirmin = option; 1176 mnt->acdirmin = option;
1132 break; 1177 break;
1133 case Opt_acdirmax: 1178 case Opt_acdirmax:
1134 if (match_int(args, &option) || option < 0) 1179 string = match_strdup(args);
1180 if (string == NULL)
1181 goto out_nomem;
1182 rc = strict_strtoul(string, 10, &option);
1183 kfree(string);
1184 if (rc != 0)
1135 goto out_invalid_value; 1185 goto out_invalid_value;
1136 mnt->acdirmax = option; 1186 mnt->acdirmax = option;
1137 break; 1187 break;
1138 case Opt_actimeo: 1188 case Opt_actimeo:
1139 if (match_int(args, &option) || option < 0) 1189 string = match_strdup(args);
1190 if (string == NULL)
1191 goto out_nomem;
1192 rc = strict_strtoul(string, 10, &option);
1193 kfree(string);
1194 if (rc != 0)
1140 goto out_invalid_value; 1195 goto out_invalid_value;
1141 mnt->acregmin = mnt->acregmax = 1196 mnt->acregmin = mnt->acregmax =
1142 mnt->acdirmin = mnt->acdirmax = option; 1197 mnt->acdirmin = mnt->acdirmax = option;
1143 break; 1198 break;
1144 case Opt_namelen: 1199 case Opt_namelen:
1145 if (match_int(args, &option) || option < 0) 1200 string = match_strdup(args);
1201 if (string == NULL)
1202 goto out_nomem;
1203 rc = strict_strtoul(string, 10, &option);
1204 kfree(string);
1205 if (rc != 0)
1146 goto out_invalid_value; 1206 goto out_invalid_value;
1147 mnt->namlen = option; 1207 mnt->namlen = option;
1148 break; 1208 break;
1149 case Opt_mountport: 1209 case Opt_mountport:
1150 if (match_int(args, &option) || 1210 string = match_strdup(args);
1151 option < 0 || option > USHORT_MAX) 1211 if (string == NULL)
1212 goto out_nomem;
1213 rc = strict_strtoul(string, 10, &option);
1214 kfree(string);
1215 if (rc != 0 || option > USHORT_MAX)
1152 goto out_invalid_value; 1216 goto out_invalid_value;
1153 mnt->mount_server.port = option; 1217 mnt->mount_server.port = option;
1154 break; 1218 break;
1155 case Opt_mountvers: 1219 case Opt_mountvers:
1156 if (match_int(args, &option) || 1220 string = match_strdup(args);
1221 if (string == NULL)
1222 goto out_nomem;
1223 rc = strict_strtoul(string, 10, &option);
1224 kfree(string);
1225 if (rc != 0 ||
1157 option < NFS_MNT_VERSION || 1226 option < NFS_MNT_VERSION ||
1158 option > NFS_MNT3_VERSION) 1227 option > NFS_MNT3_VERSION)
1159 goto out_invalid_value; 1228 goto out_invalid_value;
1160 mnt->mount_server.version = option; 1229 mnt->mount_server.version = option;
1161 break; 1230 break;
1162 case Opt_nfsvers: 1231 case Opt_nfsvers:
1163 if (match_int(args, &option)) 1232 string = match_strdup(args);
1233 if (string == NULL)
1234 goto out_nomem;
1235 rc = strict_strtoul(string, 10, &option);
1236 kfree(string);
1237 if (rc != 0)
1164 goto out_invalid_value; 1238 goto out_invalid_value;
1165 switch (option) { 1239 switch (option) {
1166 case NFS2_VERSION: 1240 case NFS2_VERSION: