aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-06-17 21:02:13 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 21:02:13 -0400
commitd23c45fd84f79a3b84899dac053dcafe9d43ebc9 (patch)
tree38586e19ef996fdf12a11baf01ac3e62a9f56475 /fs/nfs/super.c
parent065015e5efff60884ad600a3e9a5127dbb684429 (diff)
NFS: Invalid mount option values should always fail, even with "sloppy"
Ian Kent reports: "I've noticed a couple of other regressions with the options vers and proto option of mount.nfs(8). The commands: mount -t nfs -o vers=<invalid version> <server>:/<path> /<mountpoint> mount -t nfs -o proto=<invalid proto> <server>:/<path> /<mountpoint> both immediately fail. But if the "-s" option is also used they both succeed with the mount falling back to defaults (by the look of it). In the past these failed even when the sloppy option was given, as I think they should. I believe the sloppy option is meant to allow the mount command to still function for mount options (for example in shared autofs maps) that exist on other Unix implementations but aren't present in the Linux mount.nfs(8). So, an invalid value specified for a known mount option is different to an unknown mount option and should fail appropriately." See RH bugzilla 486266. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c157
1 files changed, 61 insertions, 96 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 0b72357cdc41..a2b2805caf9d 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -942,11 +942,6 @@ static int nfs_parse_security_flavors(char *value,
942 return 1; 942 return 1;
943} 943}
944 944
945static void nfs_parse_invalid_value(const char *option)
946{
947 dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option);
948}
949
950/* 945/*
951 * Error-check and convert a string of mount options from user space into 946 * Error-check and convert a string of mount options from user space into
952 * a data structure. The whole mount string is processed; bad options are 947 * a data structure. The whole mount string is processed; bad options are
@@ -957,7 +952,7 @@ static int nfs_parse_mount_options(char *raw,
957 struct nfs_parsed_mount_data *mnt) 952 struct nfs_parsed_mount_data *mnt)
958{ 953{
959 char *p, *string, *secdata; 954 char *p, *string, *secdata;
960 int rc, sloppy = 0, errors = 0; 955 int rc, sloppy = 0, invalid_option = 0;
961 956
962 if (!raw) { 957 if (!raw) {
963 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 958 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -1091,113 +1086,82 @@ static int nfs_parse_mount_options(char *raw,
1091 */ 1086 */
1092 case Opt_port: 1087 case Opt_port:
1093 if (match_int(args, &option) || 1088 if (match_int(args, &option) ||
1094 option < 0 || option > USHORT_MAX) { 1089 option < 0 || option > USHORT_MAX)
1095 errors++; 1090 goto out_invalid_value;
1096 nfs_parse_invalid_value("port"); 1091 mnt->nfs_server.port = option;
1097 } else
1098 mnt->nfs_server.port = option;
1099 break; 1092 break;
1100 case Opt_rsize: 1093 case Opt_rsize:
1101 if (match_int(args, &option) || option < 0) { 1094 if (match_int(args, &option) || option < 0)
1102 errors++; 1095 goto out_invalid_value;
1103 nfs_parse_invalid_value("rsize"); 1096 mnt->rsize = option;
1104 } else
1105 mnt->rsize = option;
1106 break; 1097 break;
1107 case Opt_wsize: 1098 case Opt_wsize:
1108 if (match_int(args, &option) || option < 0) { 1099 if (match_int(args, &option) || option < 0)
1109 errors++; 1100 goto out_invalid_value;
1110 nfs_parse_invalid_value("wsize"); 1101 mnt->wsize = option;
1111 } else
1112 mnt->wsize = option;
1113 break; 1102 break;
1114 case Opt_bsize: 1103 case Opt_bsize:
1115 if (match_int(args, &option) || option < 0) { 1104 if (match_int(args, &option) || option < 0)
1116 errors++; 1105 goto out_invalid_value;
1117 nfs_parse_invalid_value("bsize"); 1106 mnt->bsize = option;
1118 } else
1119 mnt->bsize = option;
1120 break; 1107 break;
1121 case Opt_timeo: 1108 case Opt_timeo:
1122 if (match_int(args, &option) || option <= 0) { 1109 if (match_int(args, &option) || option <= 0)
1123 errors++; 1110 goto out_invalid_value;
1124 nfs_parse_invalid_value("timeo"); 1111 mnt->timeo = option;
1125 } else
1126 mnt->timeo = option;
1127 break; 1112 break;
1128 case Opt_retrans: 1113 case Opt_retrans:
1129 if (match_int(args, &option) || option <= 0) { 1114 if (match_int(args, &option) || option <= 0)
1130 errors++; 1115 goto out_invalid_value;
1131 nfs_parse_invalid_value("retrans"); 1116 mnt->retrans = option;
1132 } else
1133 mnt->retrans = option;
1134 break; 1117 break;
1135 case Opt_acregmin: 1118 case Opt_acregmin:
1136 if (match_int(args, &option) || option < 0) { 1119 if (match_int(args, &option) || option < 0)
1137 errors++; 1120 goto out_invalid_value;
1138 nfs_parse_invalid_value("acregmin"); 1121 mnt->acregmin = option;
1139 } else
1140 mnt->acregmin = option;
1141 break; 1122 break;
1142 case Opt_acregmax: 1123 case Opt_acregmax:
1143 if (match_int(args, &option) || option < 0) { 1124 if (match_int(args, &option) || option < 0)
1144 errors++; 1125 goto out_invalid_value;
1145 nfs_parse_invalid_value("acregmax"); 1126 mnt->acregmax = option;
1146 } else
1147 mnt->acregmax = option;
1148 break; 1127 break;
1149 case Opt_acdirmin: 1128 case Opt_acdirmin:
1150 if (match_int(args, &option) || option < 0) { 1129 if (match_int(args, &option) || option < 0)
1151 errors++; 1130 goto out_invalid_value;
1152 nfs_parse_invalid_value("acdirmin"); 1131 mnt->acdirmin = option;
1153 } else
1154 mnt->acdirmin = option;
1155 break; 1132 break;
1156 case Opt_acdirmax: 1133 case Opt_acdirmax:
1157 if (match_int(args, &option) || option < 0) { 1134 if (match_int(args, &option) || option < 0)
1158 errors++; 1135 goto out_invalid_value;
1159 nfs_parse_invalid_value("acdirmax"); 1136 mnt->acdirmax = option;
1160 } else
1161 mnt->acdirmax = option;
1162 break; 1137 break;
1163 case Opt_actimeo: 1138 case Opt_actimeo:
1164 if (match_int(args, &option) || option < 0) { 1139 if (match_int(args, &option) || option < 0)
1165 errors++; 1140 goto out_invalid_value;
1166 nfs_parse_invalid_value("actimeo"); 1141 mnt->acregmin = mnt->acregmax =
1167 } else 1142 mnt->acdirmin = mnt->acdirmax = option;
1168 mnt->acregmin = mnt->acregmax =
1169 mnt->acdirmin = mnt->acdirmax = option;
1170 break; 1143 break;
1171 case Opt_namelen: 1144 case Opt_namelen:
1172 if (match_int(args, &option) || option < 0) { 1145 if (match_int(args, &option) || option < 0)
1173 errors++; 1146 goto out_invalid_value;
1174 nfs_parse_invalid_value("namlen"); 1147 mnt->namlen = option;
1175 } else
1176 mnt->namlen = option;
1177 break; 1148 break;
1178 case Opt_mountport: 1149 case Opt_mountport:
1179 if (match_int(args, &option) || 1150 if (match_int(args, &option) ||
1180 option < 0 || option > USHORT_MAX) { 1151 option < 0 || option > USHORT_MAX)
1181 errors++; 1152 goto out_invalid_value;
1182 nfs_parse_invalid_value("mountport"); 1153 mnt->mount_server.port = option;
1183 } else
1184 mnt->mount_server.port = option;
1185 break; 1154 break;
1186 case Opt_mountvers: 1155 case Opt_mountvers:
1187 if (match_int(args, &option) || 1156 if (match_int(args, &option) ||
1188 option < NFS_MNT_VERSION || 1157 option < NFS_MNT_VERSION ||
1189 option > NFS_MNT3_VERSION) { 1158 option > NFS_MNT3_VERSION)
1190 errors++; 1159 goto out_invalid_value;
1191 nfs_parse_invalid_value("mountvers"); 1160 mnt->mount_server.version = option;
1192 } else
1193 mnt->mount_server.version = option;
1194 break; 1161 break;
1195 case Opt_nfsvers: 1162 case Opt_nfsvers:
1196 if (match_int(args, &option)) { 1163 if (match_int(args, &option))
1197 errors++; 1164 goto out_invalid_value;
1198 nfs_parse_invalid_value("nfsvers");
1199 break;
1200 }
1201 switch (option) { 1165 switch (option) {
1202 case NFS2_VERSION: 1166 case NFS2_VERSION:
1203 mnt->flags &= ~NFS_MOUNT_VER3; 1167 mnt->flags &= ~NFS_MOUNT_VER3;
@@ -1206,8 +1170,7 @@ static int nfs_parse_mount_options(char *raw,
1206 mnt->flags |= NFS_MOUNT_VER3; 1170 mnt->flags |= NFS_MOUNT_VER3;
1207 break; 1171 break;
1208 default: 1172 default:
1209 errors++; 1173 goto out_invalid_value;
1210 nfs_parse_invalid_value("nfsvers");
1211 } 1174 }
1212 break; 1175 break;
1213 1176
@@ -1221,9 +1184,9 @@ static int nfs_parse_mount_options(char *raw,
1221 rc = nfs_parse_security_flavors(string, mnt); 1184 rc = nfs_parse_security_flavors(string, mnt);
1222 kfree(string); 1185 kfree(string);
1223 if (!rc) { 1186 if (!rc) {
1224 errors++;
1225 dfprintk(MOUNT, "NFS: unrecognized " 1187 dfprintk(MOUNT, "NFS: unrecognized "
1226 "security flavor\n"); 1188 "security flavor\n");
1189 return 0;
1227 } 1190 }
1228 break; 1191 break;
1229 case Opt_proto: 1192 case Opt_proto:
@@ -1237,23 +1200,25 @@ static int nfs_parse_mount_options(char *raw,
1237 case Opt_xprt_udp: 1200 case Opt_xprt_udp:
1238 mnt->flags &= ~NFS_MOUNT_TCP; 1201 mnt->flags &= ~NFS_MOUNT_TCP;
1239 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1202 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1203 kfree(string);
1240 break; 1204 break;
1241 case Opt_xprt_tcp: 1205 case Opt_xprt_tcp:
1242 mnt->flags |= NFS_MOUNT_TCP; 1206 mnt->flags |= NFS_MOUNT_TCP;
1243 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1207 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1208 kfree(string);
1244 break; 1209 break;
1245 case Opt_xprt_rdma: 1210 case Opt_xprt_rdma:
1246 /* vector side protocols to TCP */ 1211 /* vector side protocols to TCP */
1247 mnt->flags |= NFS_MOUNT_TCP; 1212 mnt->flags |= NFS_MOUNT_TCP;
1248 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1213 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
1249 xprt_load_transport(string); 1214 xprt_load_transport(string);
1215 kfree(string);
1250 break; 1216 break;
1251 default: 1217 default:
1252 errors++;
1253 dfprintk(MOUNT, "NFS: unrecognized " 1218 dfprintk(MOUNT, "NFS: unrecognized "
1254 "transport protocol\n"); 1219 "transport protocol\n");
1220 return 0;
1255 } 1221 }
1256 kfree(string);
1257 break; 1222 break;
1258 case Opt_mountproto: 1223 case Opt_mountproto:
1259 string = match_strdup(args); 1224 string = match_strdup(args);
@@ -1272,9 +1237,9 @@ static int nfs_parse_mount_options(char *raw,
1272 break; 1237 break;
1273 case Opt_xprt_rdma: /* not used for side protocols */ 1238 case Opt_xprt_rdma: /* not used for side protocols */
1274 default: 1239 default:
1275 errors++;
1276 dfprintk(MOUNT, "NFS: unrecognized " 1240 dfprintk(MOUNT, "NFS: unrecognized "
1277 "transport protocol\n"); 1241 "transport protocol\n");
1242 return 0;
1278 } 1243 }
1279 break; 1244 break;
1280 case Opt_addr: 1245 case Opt_addr:
@@ -1330,9 +1295,9 @@ static int nfs_parse_mount_options(char *raw,
1330 mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; 1295 mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
1331 break; 1296 break;
1332 default: 1297 default:
1333 errors++;
1334 dfprintk(MOUNT, "NFS: invalid " 1298 dfprintk(MOUNT, "NFS: invalid "
1335 "lookupcache argument\n"); 1299 "lookupcache argument\n");
1300 return 0;
1336 }; 1301 };
1337 break; 1302 break;
1338 1303
@@ -1350,20 +1315,20 @@ static int nfs_parse_mount_options(char *raw,
1350 break; 1315 break;
1351 1316
1352 default: 1317 default:
1353 errors++; 1318 invalid_option = 1;
1354 dfprintk(MOUNT, "NFS: unrecognized mount option " 1319 dfprintk(MOUNT, "NFS: unrecognized mount option "
1355 "'%s'\n", p); 1320 "'%s'\n", p);
1356 } 1321 }
1357 } 1322 }
1358 1323
1359 if (errors > 0) { 1324 if (!sloppy && invalid_option)
1360 dfprintk(MOUNT, "NFS: parsing encountered %d error%s\n", 1325 return 0;
1361 errors, (errors == 1 ? "" : "s")); 1326
1362 if (!sloppy)
1363 return 0;
1364 }
1365 return 1; 1327 return 1;
1366 1328
1329out_invalid_value:
1330 printk(KERN_INFO "NFS: bad mount option value specified: %s \n", p);
1331 return 0;
1367out_nomem: 1332out_nomem:
1368 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1333 printk(KERN_INFO "NFS: not enough memory to parse option\n");
1369 return 0; 1334 return 0;