aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 21:13:00 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-18 21:13:44 -0400
commit1f84603c0940d5bed17f7e4d2e0b2a4b8b8f1b81 (patch)
tree143956f878290e85de7c9130f465e862f587ee53 /fs/nfs/super.c
parent301933a0acfdec837fd8b4884093b3f0fff01d8a (diff)
parent4bf259e3ae5015e73282ba66716c4a917e1264ac (diff)
Merge branch 'devel-for-2.6.31' into for-2.6.31
Conflicts: fs/nfs/client.c fs/nfs/super.c
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r--fs/nfs/super.c288
1 files changed, 168 insertions, 120 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 6063054455f8..3d460527daab 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -140,22 +140,22 @@ static const match_table_t nfs_mount_option_tokens = {
140 { Opt_fscache_uniq, "fsc=%s" }, 140 { Opt_fscache_uniq, "fsc=%s" },
141 { Opt_nofscache, "nofsc" }, 141 { Opt_nofscache, "nofsc" },
142 142
143 { Opt_port, "port=%u" }, 143 { Opt_port, "port=%s" },
144 { Opt_rsize, "rsize=%u" }, 144 { Opt_rsize, "rsize=%s" },
145 { Opt_wsize, "wsize=%u" }, 145 { Opt_wsize, "wsize=%s" },
146 { Opt_bsize, "bsize=%u" }, 146 { Opt_bsize, "bsize=%s" },
147 { Opt_timeo, "timeo=%u" }, 147 { Opt_timeo, "timeo=%s" },
148 { Opt_retrans, "retrans=%u" }, 148 { Opt_retrans, "retrans=%s" },
149 { Opt_acregmin, "acregmin=%u" }, 149 { Opt_acregmin, "acregmin=%s" },
150 { Opt_acregmax, "acregmax=%u" }, 150 { Opt_acregmax, "acregmax=%s" },
151 { Opt_acdirmin, "acdirmin=%u" }, 151 { Opt_acdirmin, "acdirmin=%s" },
152 { Opt_acdirmax, "acdirmax=%u" }, 152 { Opt_acdirmax, "acdirmax=%s" },
153 { Opt_actimeo, "actimeo=%u" }, 153 { Opt_actimeo, "actimeo=%s" },
154 { Opt_namelen, "namlen=%u" }, 154 { Opt_namelen, "namlen=%s" },
155 { Opt_mountport, "mountport=%u" }, 155 { Opt_mountport, "mountport=%s" },
156 { Opt_mountvers, "mountvers=%u" }, 156 { Opt_mountvers, "mountvers=%s" },
157 { Opt_nfsvers, "nfsvers=%u" }, 157 { Opt_nfsvers, "nfsvers=%s" },
158 { Opt_nfsvers, "vers=%u" }, 158 { Opt_nfsvers, "vers=%s" },
159 { Opt_minorversion, "minorversion=%u" }, 159 { Opt_minorversion, "minorversion=%u" },
160 160
161 { Opt_sec, "sec=%s" }, 161 { Opt_sec, "sec=%s" },
@@ -516,7 +516,6 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
516 const char *nostr; 516 const char *nostr;
517 } nfs_info[] = { 517 } nfs_info[] = {
518 { NFS_MOUNT_SOFT, ",soft", ",hard" }, 518 { NFS_MOUNT_SOFT, ",soft", ",hard" },
519 { NFS_MOUNT_INTR, ",intr", ",nointr" },
520 { NFS_MOUNT_POSIX, ",posix", "" }, 519 { NFS_MOUNT_POSIX, ",posix", "" },
521 { NFS_MOUNT_NOCTO, ",nocto", "" }, 520 { NFS_MOUNT_NOCTO, ",nocto", "" },
522 { NFS_MOUNT_NOAC, ",noac", "" }, 521 { NFS_MOUNT_NOAC, ",noac", "" },
@@ -945,11 +944,6 @@ static int nfs_parse_security_flavors(char *value,
945 return 1; 944 return 1;
946} 945}
947 946
948static void nfs_parse_invalid_value(const char *option)
949{
950 dfprintk(MOUNT, "NFS: bad value specified for %s option\n", option);
951}
952
953/* 947/*
954 * Error-check and convert a string of mount options from user space into 948 * Error-check and convert a string of mount options from user space into
955 * a data structure. The whole mount string is processed; bad options are 949 * a data structure. The whole mount string is processed; bad options are
@@ -960,7 +954,7 @@ static int nfs_parse_mount_options(char *raw,
960 struct nfs_parsed_mount_data *mnt) 954 struct nfs_parsed_mount_data *mnt)
961{ 955{
962 char *p, *string, *secdata; 956 char *p, *string, *secdata;
963 int rc, sloppy = 0, errors = 0; 957 int rc, sloppy = 0, invalid_option = 0;
964 958
965 if (!raw) { 959 if (!raw) {
966 dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); 960 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
@@ -984,7 +978,9 @@ static int nfs_parse_mount_options(char *raw,
984 978
985 while ((p = strsep(&raw, ",")) != NULL) { 979 while ((p = strsep(&raw, ",")) != NULL) {
986 substring_t args[MAX_OPT_ARGS]; 980 substring_t args[MAX_OPT_ARGS];
987 int option, token; 981 unsigned long option;
982 int int_option;
983 int token;
988 984
989 if (!*p) 985 if (!*p)
990 continue; 986 continue;
@@ -1093,114 +1089,156 @@ static int nfs_parse_mount_options(char *raw,
1093 * options that take numeric values 1089 * options that take numeric values
1094 */ 1090 */
1095 case Opt_port: 1091 case Opt_port:
1096 if (match_int(args, &option) || 1092 string = match_strdup(args);
1097 option < 0 || option > USHORT_MAX) { 1093 if (string == NULL)
1098 errors++; 1094 goto out_nomem;
1099 nfs_parse_invalid_value("port"); 1095 rc = strict_strtoul(string, 10, &option);
1100 } else 1096 kfree(string);
1101 mnt->nfs_server.port = option; 1097 if (rc != 0 || option > USHORT_MAX)
1098 goto out_invalid_value;
1099 mnt->nfs_server.port = option;
1102 break; 1100 break;
1103 case Opt_rsize: 1101 case Opt_rsize:
1104 if (match_int(args, &option) || option < 0) { 1102 string = match_strdup(args);
1105 errors++; 1103 if (string == NULL)
1106 nfs_parse_invalid_value("rsize"); 1104 goto out_nomem;
1107 } else 1105 rc = strict_strtoul(string, 10, &option);
1108 mnt->rsize = option; 1106 kfree(string);
1107 if (rc != 0)
1108 goto out_invalid_value;
1109 mnt->rsize = option;
1109 break; 1110 break;
1110 case Opt_wsize: 1111 case Opt_wsize:
1111 if (match_int(args, &option) || option < 0) { 1112 string = match_strdup(args);
1112 errors++; 1113 if (string == NULL)
1113 nfs_parse_invalid_value("wsize"); 1114 goto out_nomem;
1114 } else 1115 rc = strict_strtoul(string, 10, &option);
1115 mnt->wsize = option; 1116 kfree(string);
1117 if (rc != 0)
1118 goto out_invalid_value;
1119 mnt->wsize = option;
1116 break; 1120 break;
1117 case Opt_bsize: 1121 case Opt_bsize:
1118 if (match_int(args, &option) || option < 0) { 1122 string = match_strdup(args);
1119 errors++; 1123 if (string == NULL)
1120 nfs_parse_invalid_value("bsize"); 1124 goto out_nomem;
1121 } else 1125 rc = strict_strtoul(string, 10, &option);
1122 mnt->bsize = option; 1126 kfree(string);
1127 if (rc != 0)
1128 goto out_invalid_value;
1129 mnt->bsize = option;
1123 break; 1130 break;
1124 case Opt_timeo: 1131 case Opt_timeo:
1125 if (match_int(args, &option) || option <= 0) { 1132 string = match_strdup(args);
1126 errors++; 1133 if (string == NULL)
1127 nfs_parse_invalid_value("timeo"); 1134 goto out_nomem;
1128 } else 1135 rc = strict_strtoul(string, 10, &option);
1129 mnt->timeo = option; 1136 kfree(string);
1137 if (rc != 0 || option == 0)
1138 goto out_invalid_value;
1139 mnt->timeo = option;
1130 break; 1140 break;
1131 case Opt_retrans: 1141 case Opt_retrans:
1132 if (match_int(args, &option) || option <= 0) { 1142 string = match_strdup(args);
1133 errors++; 1143 if (string == NULL)
1134 nfs_parse_invalid_value("retrans"); 1144 goto out_nomem;
1135 } else 1145 rc = strict_strtoul(string, 10, &option);
1136 mnt->retrans = option; 1146 kfree(string);
1147 if (rc != 0 || option == 0)
1148 goto out_invalid_value;
1149 mnt->retrans = option;
1137 break; 1150 break;
1138 case Opt_acregmin: 1151 case Opt_acregmin:
1139 if (match_int(args, &option) || option < 0) { 1152 string = match_strdup(args);
1140 errors++; 1153 if (string == NULL)
1141 nfs_parse_invalid_value("acregmin"); 1154 goto out_nomem;
1142 } else 1155 rc = strict_strtoul(string, 10, &option);
1143 mnt->acregmin = option; 1156 kfree(string);
1157 if (rc != 0)
1158 goto out_invalid_value;
1159 mnt->acregmin = option;
1144 break; 1160 break;
1145 case Opt_acregmax: 1161 case Opt_acregmax:
1146 if (match_int(args, &option) || option < 0) { 1162 string = match_strdup(args);
1147 errors++; 1163 if (string == NULL)
1148 nfs_parse_invalid_value("acregmax"); 1164 goto out_nomem;
1149 } else 1165 rc = strict_strtoul(string, 10, &option);
1150 mnt->acregmax = option; 1166 kfree(string);
1167 if (rc != 0)
1168 goto out_invalid_value;
1169 mnt->acregmax = option;
1151 break; 1170 break;
1152 case Opt_acdirmin: 1171 case Opt_acdirmin:
1153 if (match_int(args, &option) || option < 0) { 1172 string = match_strdup(args);
1154 errors++; 1173 if (string == NULL)
1155 nfs_parse_invalid_value("acdirmin"); 1174 goto out_nomem;
1156 } else 1175 rc = strict_strtoul(string, 10, &option);
1157 mnt->acdirmin = option; 1176 kfree(string);
1177 if (rc != 0)
1178 goto out_invalid_value;
1179 mnt->acdirmin = option;
1158 break; 1180 break;
1159 case Opt_acdirmax: 1181 case Opt_acdirmax:
1160 if (match_int(args, &option) || option < 0) { 1182 string = match_strdup(args);
1161 errors++; 1183 if (string == NULL)
1162 nfs_parse_invalid_value("acdirmax"); 1184 goto out_nomem;
1163 } else 1185 rc = strict_strtoul(string, 10, &option);
1164 mnt->acdirmax = option; 1186 kfree(string);
1187 if (rc != 0)
1188 goto out_invalid_value;
1189 mnt->acdirmax = option;
1165 break; 1190 break;
1166 case Opt_actimeo: 1191 case Opt_actimeo:
1167 if (match_int(args, &option) || option < 0) { 1192 string = match_strdup(args);
1168 errors++; 1193 if (string == NULL)
1169 nfs_parse_invalid_value("actimeo"); 1194 goto out_nomem;
1170 } else 1195 rc = strict_strtoul(string, 10, &option);
1171 mnt->acregmin = mnt->acregmax = 1196 kfree(string);
1172 mnt->acdirmin = mnt->acdirmax = option; 1197 if (rc != 0)
1198 goto out_invalid_value;
1199 mnt->acregmin = mnt->acregmax =
1200 mnt->acdirmin = mnt->acdirmax = option;
1173 break; 1201 break;
1174 case Opt_namelen: 1202 case Opt_namelen:
1175 if (match_int(args, &option) || option < 0) { 1203 string = match_strdup(args);
1176 errors++; 1204 if (string == NULL)
1177 nfs_parse_invalid_value("namlen"); 1205 goto out_nomem;
1178 } else 1206 rc = strict_strtoul(string, 10, &option);
1179 mnt->namlen = option; 1207 kfree(string);
1208 if (rc != 0)
1209 goto out_invalid_value;
1210 mnt->namlen = option;
1180 break; 1211 break;
1181 case Opt_mountport: 1212 case Opt_mountport:
1182 if (match_int(args, &option) || 1213 string = match_strdup(args);
1183 option < 0 || option > USHORT_MAX) { 1214 if (string == NULL)
1184 errors++; 1215 goto out_nomem;
1185 nfs_parse_invalid_value("mountport"); 1216 rc = strict_strtoul(string, 10, &option);
1186 } else 1217 kfree(string);
1187 mnt->mount_server.port = option; 1218 if (rc != 0 || option > USHORT_MAX)
1219 goto out_invalid_value;
1220 mnt->mount_server.port = option;
1188 break; 1221 break;
1189 case Opt_mountvers: 1222 case Opt_mountvers:
1190 if (match_int(args, &option) || 1223 string = match_strdup(args);
1224 if (string == NULL)
1225 goto out_nomem;
1226 rc = strict_strtoul(string, 10, &option);
1227 kfree(string);
1228 if (rc != 0 ||
1191 option < NFS_MNT_VERSION || 1229 option < NFS_MNT_VERSION ||
1192 option > NFS_MNT3_VERSION) { 1230 option > NFS_MNT3_VERSION)
1193 errors++; 1231 goto out_invalid_value;
1194 nfs_parse_invalid_value("mountvers"); 1232 mnt->mount_server.version = option;
1195 } else
1196 mnt->mount_server.version = option;
1197 break; 1233 break;
1198 case Opt_nfsvers: 1234 case Opt_nfsvers:
1199 if (match_int(args, &option)) { 1235 string = match_strdup(args);
1200 errors++; 1236 if (string == NULL)
1201 nfs_parse_invalid_value("nfsvers"); 1237 goto out_nomem;
1202 break; 1238 rc = strict_strtoul(string, 10, &option);
1203 } 1239 kfree(string);
1240 if (rc != 0)
1241 goto out_invalid_value;
1204 switch (option) { 1242 switch (option) {
1205 case NFS2_VERSION: 1243 case NFS2_VERSION:
1206 mnt->flags &= ~NFS_MOUNT_VER3; 1244 mnt->flags &= ~NFS_MOUNT_VER3;
@@ -1209,16 +1247,15 @@ static int nfs_parse_mount_options(char *raw,
1209 mnt->flags |= NFS_MOUNT_VER3; 1247 mnt->flags |= NFS_MOUNT_VER3;
1210 break; 1248 break;
1211 default: 1249 default:
1212 errors++; 1250 goto out_invalid_value;
1213 nfs_parse_invalid_value("nfsvers");
1214 } 1251 }
1215 break; 1252 break;
1216 case Opt_minorversion: 1253 case Opt_minorversion:
1217 if (match_int(args, &option)) 1254 if (match_int(args, &int_option))
1218 return 0; 1255 return 0;
1219 if (option < 0 || option > NFS4_MAX_MINOR_VERSION) 1256 if (int_option < 0 || int_option > NFS4_MAX_MINOR_VERSION)
1220 return 0; 1257 return 0;
1221 mnt->minorversion = option; 1258 mnt->minorversion = int_option;
1222 break; 1259 break;
1223 1260
1224 /* 1261 /*
@@ -1231,9 +1268,9 @@ static int nfs_parse_mount_options(char *raw,
1231 rc = nfs_parse_security_flavors(string, mnt); 1268 rc = nfs_parse_security_flavors(string, mnt);
1232 kfree(string); 1269 kfree(string);
1233 if (!rc) { 1270 if (!rc) {
1234 errors++;
1235 dfprintk(MOUNT, "NFS: unrecognized " 1271 dfprintk(MOUNT, "NFS: unrecognized "
1236 "security flavor\n"); 1272 "security flavor\n");
1273 return 0;
1237 } 1274 }
1238 break; 1275 break;
1239 case Opt_proto: 1276 case Opt_proto:
@@ -1247,23 +1284,25 @@ static int nfs_parse_mount_options(char *raw,
1247 case Opt_xprt_udp: 1284 case Opt_xprt_udp:
1248 mnt->flags &= ~NFS_MOUNT_TCP; 1285 mnt->flags &= ~NFS_MOUNT_TCP;
1249 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1286 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1287 kfree(string);
1250 break; 1288 break;
1251 case Opt_xprt_tcp: 1289 case Opt_xprt_tcp:
1252 mnt->flags |= NFS_MOUNT_TCP; 1290 mnt->flags |= NFS_MOUNT_TCP;
1253 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; 1291 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1292 kfree(string);
1254 break; 1293 break;
1255 case Opt_xprt_rdma: 1294 case Opt_xprt_rdma:
1256 /* vector side protocols to TCP */ 1295 /* vector side protocols to TCP */
1257 mnt->flags |= NFS_MOUNT_TCP; 1296 mnt->flags |= NFS_MOUNT_TCP;
1258 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; 1297 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
1259 xprt_load_transport(string); 1298 xprt_load_transport(string);
1299 kfree(string);
1260 break; 1300 break;
1261 default: 1301 default:
1262 errors++;
1263 dfprintk(MOUNT, "NFS: unrecognized " 1302 dfprintk(MOUNT, "NFS: unrecognized "
1264 "transport protocol\n"); 1303 "transport protocol\n");
1304 return 0;
1265 } 1305 }
1266 kfree(string);
1267 break; 1306 break;
1268 case Opt_mountproto: 1307 case Opt_mountproto:
1269 string = match_strdup(args); 1308 string = match_strdup(args);
@@ -1282,9 +1321,9 @@ static int nfs_parse_mount_options(char *raw,
1282 break; 1321 break;
1283 case Opt_xprt_rdma: /* not used for side protocols */ 1322 case Opt_xprt_rdma: /* not used for side protocols */
1284 default: 1323 default:
1285 errors++;
1286 dfprintk(MOUNT, "NFS: unrecognized " 1324 dfprintk(MOUNT, "NFS: unrecognized "
1287 "transport protocol\n"); 1325 "transport protocol\n");
1326 return 0;
1288 } 1327 }
1289 break; 1328 break;
1290 case Opt_addr: 1329 case Opt_addr:
@@ -1340,9 +1379,9 @@ static int nfs_parse_mount_options(char *raw,
1340 mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE; 1379 mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
1341 break; 1380 break;
1342 default: 1381 default:
1343 errors++;
1344 dfprintk(MOUNT, "NFS: invalid " 1382 dfprintk(MOUNT, "NFS: invalid "
1345 "lookupcache argument\n"); 1383 "lookupcache argument\n");
1384 return 0;
1346 }; 1385 };
1347 break; 1386 break;
1348 1387
@@ -1360,20 +1399,20 @@ static int nfs_parse_mount_options(char *raw,
1360 break; 1399 break;
1361 1400
1362 default: 1401 default:
1363 errors++; 1402 invalid_option = 1;
1364 dfprintk(MOUNT, "NFS: unrecognized mount option " 1403 dfprintk(MOUNT, "NFS: unrecognized mount option "
1365 "'%s'\n", p); 1404 "'%s'\n", p);
1366 } 1405 }
1367 } 1406 }
1368 1407
1369 if (errors > 0) { 1408 if (!sloppy && invalid_option)
1370 dfprintk(MOUNT, "NFS: parsing encountered %d error%s\n", 1409 return 0;
1371 errors, (errors == 1 ? "" : "s")); 1410
1372 if (!sloppy)
1373 return 0;
1374 }
1375 return 1; 1411 return 1;
1376 1412
1413out_invalid_value:
1414 printk(KERN_INFO "NFS: bad mount option value specified: %s \n", p);
1415 return 0;
1377out_nomem: 1416out_nomem:
1378 printk(KERN_INFO "NFS: not enough memory to parse option\n"); 1417 printk(KERN_INFO "NFS: not enough memory to parse option\n");
1379 return 0; 1418 return 0;
@@ -1390,6 +1429,7 @@ out_security_failure:
1390static int nfs_try_mount(struct nfs_parsed_mount_data *args, 1429static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1391 struct nfs_fh *root_fh) 1430 struct nfs_fh *root_fh)
1392{ 1431{
1432 unsigned int auth_flavor_len = 0;
1393 struct nfs_mount_request request = { 1433 struct nfs_mount_request request = {
1394 .sap = (struct sockaddr *) 1434 .sap = (struct sockaddr *)
1395 &args->mount_server.address, 1435 &args->mount_server.address,
@@ -1397,6 +1437,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1397 .protocol = args->mount_server.protocol, 1437 .protocol = args->mount_server.protocol,
1398 .fh = root_fh, 1438 .fh = root_fh,
1399 .noresvport = args->flags & NFS_MOUNT_NORESVPORT, 1439 .noresvport = args->flags & NFS_MOUNT_NORESVPORT,
1440 .auth_flav_len = &auth_flavor_len,
1400 }; 1441 };
1401 int status; 1442 int status;
1402 1443
@@ -2249,6 +2290,11 @@ static void nfs4_fill_super(struct super_block *sb)
2249 nfs_initialise_sb(sb); 2290 nfs_initialise_sb(sb);
2250} 2291}
2251 2292
2293static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
2294{
2295 args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3);
2296}
2297
2252/* 2298/*
2253 * Validate NFSv4 mount options 2299 * Validate NFSv4 mount options
2254 */ 2300 */
@@ -2346,6 +2392,8 @@ static int nfs4_validate_mount_data(void *options,
2346 2392
2347 nfs_validate_transport_protocol(args); 2393 nfs_validate_transport_protocol(args);
2348 2394
2395 nfs4_validate_mount_flags(args);
2396
2349 if (args->auth_flavor_len > 1) 2397 if (args->auth_flavor_len > 1)
2350 goto out_inval_auth; 2398 goto out_inval_auth;
2351 2399