diff options
-rw-r--r-- | fs/nfs/super.c | 155 |
1 files changed, 44 insertions, 111 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a74e9740190f..7e13e1a6b391 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -979,6 +979,27 @@ static int nfs_parse_security_flavors(char *value, | |||
979 | return 1; | 979 | return 1; |
980 | } | 980 | } |
981 | 981 | ||
982 | static int nfs_get_option_str(substring_t args[], char **option) | ||
983 | { | ||
984 | kfree(*option); | ||
985 | *option = match_strdup(args); | ||
986 | return !option; | ||
987 | } | ||
988 | |||
989 | static int nfs_get_option_ul(substring_t args[], unsigned long *option) | ||
990 | { | ||
991 | int rc; | ||
992 | char *string; | ||
993 | |||
994 | string = match_strdup(args); | ||
995 | if (string == NULL) | ||
996 | return -ENOMEM; | ||
997 | rc = strict_strtoul(string, 10, option); | ||
998 | kfree(string); | ||
999 | |||
1000 | return rc; | ||
1001 | } | ||
1002 | |||
982 | /* | 1003 | /* |
983 | * Error-check and convert a string of mount options from user space into | 1004 | * Error-check and convert a string of mount options from user space into |
984 | * a data structure. The whole mount string is processed; bad options are | 1005 | * a data structure. The whole mount string is processed; bad options are |
@@ -1127,155 +1148,82 @@ static int nfs_parse_mount_options(char *raw, | |||
1127 | * options that take numeric values | 1148 | * options that take numeric values |
1128 | */ | 1149 | */ |
1129 | case Opt_port: | 1150 | case Opt_port: |
1130 | string = match_strdup(args); | 1151 | if (nfs_get_option_ul(args, &option) || |
1131 | if (string == NULL) | 1152 | option > USHRT_MAX) |
1132 | goto out_nomem; | ||
1133 | rc = strict_strtoul(string, 10, &option); | ||
1134 | kfree(string); | ||
1135 | if (rc != 0 || option > USHRT_MAX) | ||
1136 | goto out_invalid_value; | 1153 | goto out_invalid_value; |
1137 | mnt->nfs_server.port = option; | 1154 | mnt->nfs_server.port = option; |
1138 | break; | 1155 | break; |
1139 | case Opt_rsize: | 1156 | case Opt_rsize: |
1140 | string = match_strdup(args); | 1157 | if (nfs_get_option_ul(args, &option)) |
1141 | if (string == NULL) | ||
1142 | goto out_nomem; | ||
1143 | rc = strict_strtoul(string, 10, &option); | ||
1144 | kfree(string); | ||
1145 | if (rc != 0) | ||
1146 | goto out_invalid_value; | 1158 | goto out_invalid_value; |
1147 | mnt->rsize = option; | 1159 | mnt->rsize = option; |
1148 | break; | 1160 | break; |
1149 | case Opt_wsize: | 1161 | case Opt_wsize: |
1150 | string = match_strdup(args); | 1162 | if (nfs_get_option_ul(args, &option)) |
1151 | if (string == NULL) | ||
1152 | goto out_nomem; | ||
1153 | rc = strict_strtoul(string, 10, &option); | ||
1154 | kfree(string); | ||
1155 | if (rc != 0) | ||
1156 | goto out_invalid_value; | 1163 | goto out_invalid_value; |
1157 | mnt->wsize = option; | 1164 | mnt->wsize = option; |
1158 | break; | 1165 | break; |
1159 | case Opt_bsize: | 1166 | case Opt_bsize: |
1160 | string = match_strdup(args); | 1167 | if (nfs_get_option_ul(args, &option)) |
1161 | if (string == NULL) | ||
1162 | goto out_nomem; | ||
1163 | rc = strict_strtoul(string, 10, &option); | ||
1164 | kfree(string); | ||
1165 | if (rc != 0) | ||
1166 | goto out_invalid_value; | 1168 | goto out_invalid_value; |
1167 | mnt->bsize = option; | 1169 | mnt->bsize = option; |
1168 | break; | 1170 | break; |
1169 | case Opt_timeo: | 1171 | case Opt_timeo: |
1170 | string = match_strdup(args); | 1172 | if (nfs_get_option_ul(args, &option) || option == 0) |
1171 | if (string == NULL) | ||
1172 | goto out_nomem; | ||
1173 | rc = strict_strtoul(string, 10, &option); | ||
1174 | kfree(string); | ||
1175 | if (rc != 0 || option == 0) | ||
1176 | goto out_invalid_value; | 1173 | goto out_invalid_value; |
1177 | mnt->timeo = option; | 1174 | mnt->timeo = option; |
1178 | break; | 1175 | break; |
1179 | case Opt_retrans: | 1176 | case Opt_retrans: |
1180 | string = match_strdup(args); | 1177 | if (nfs_get_option_ul(args, &option) || option == 0) |
1181 | if (string == NULL) | ||
1182 | goto out_nomem; | ||
1183 | rc = strict_strtoul(string, 10, &option); | ||
1184 | kfree(string); | ||
1185 | if (rc != 0 || option == 0) | ||
1186 | goto out_invalid_value; | 1178 | goto out_invalid_value; |
1187 | mnt->retrans = option; | 1179 | mnt->retrans = option; |
1188 | break; | 1180 | break; |
1189 | case Opt_acregmin: | 1181 | case Opt_acregmin: |
1190 | string = match_strdup(args); | 1182 | if (nfs_get_option_ul(args, &option)) |
1191 | if (string == NULL) | ||
1192 | goto out_nomem; | ||
1193 | rc = strict_strtoul(string, 10, &option); | ||
1194 | kfree(string); | ||
1195 | if (rc != 0) | ||
1196 | goto out_invalid_value; | 1183 | goto out_invalid_value; |
1197 | mnt->acregmin = option; | 1184 | mnt->acregmin = option; |
1198 | break; | 1185 | break; |
1199 | case Opt_acregmax: | 1186 | case Opt_acregmax: |
1200 | string = match_strdup(args); | 1187 | if (nfs_get_option_ul(args, &option)) |
1201 | if (string == NULL) | ||
1202 | goto out_nomem; | ||
1203 | rc = strict_strtoul(string, 10, &option); | ||
1204 | kfree(string); | ||
1205 | if (rc != 0) | ||
1206 | goto out_invalid_value; | 1188 | goto out_invalid_value; |
1207 | mnt->acregmax = option; | 1189 | mnt->acregmax = option; |
1208 | break; | 1190 | break; |
1209 | case Opt_acdirmin: | 1191 | case Opt_acdirmin: |
1210 | string = match_strdup(args); | 1192 | if (nfs_get_option_ul(args, &option)) |
1211 | if (string == NULL) | ||
1212 | goto out_nomem; | ||
1213 | rc = strict_strtoul(string, 10, &option); | ||
1214 | kfree(string); | ||
1215 | if (rc != 0) | ||
1216 | goto out_invalid_value; | 1193 | goto out_invalid_value; |
1217 | mnt->acdirmin = option; | 1194 | mnt->acdirmin = option; |
1218 | break; | 1195 | break; |
1219 | case Opt_acdirmax: | 1196 | case Opt_acdirmax: |
1220 | string = match_strdup(args); | 1197 | if (nfs_get_option_ul(args, &option)) |
1221 | if (string == NULL) | ||
1222 | goto out_nomem; | ||
1223 | rc = strict_strtoul(string, 10, &option); | ||
1224 | kfree(string); | ||
1225 | if (rc != 0) | ||
1226 | goto out_invalid_value; | 1198 | goto out_invalid_value; |
1227 | mnt->acdirmax = option; | 1199 | mnt->acdirmax = option; |
1228 | break; | 1200 | break; |
1229 | case Opt_actimeo: | 1201 | case Opt_actimeo: |
1230 | string = match_strdup(args); | 1202 | if (nfs_get_option_ul(args, &option)) |
1231 | if (string == NULL) | ||
1232 | goto out_nomem; | ||
1233 | rc = strict_strtoul(string, 10, &option); | ||
1234 | kfree(string); | ||
1235 | if (rc != 0) | ||
1236 | goto out_invalid_value; | 1203 | goto out_invalid_value; |
1237 | mnt->acregmin = mnt->acregmax = | 1204 | mnt->acregmin = mnt->acregmax = |
1238 | mnt->acdirmin = mnt->acdirmax = option; | 1205 | mnt->acdirmin = mnt->acdirmax = option; |
1239 | break; | 1206 | break; |
1240 | case Opt_namelen: | 1207 | case Opt_namelen: |
1241 | string = match_strdup(args); | 1208 | if (nfs_get_option_ul(args, &option)) |
1242 | if (string == NULL) | ||
1243 | goto out_nomem; | ||
1244 | rc = strict_strtoul(string, 10, &option); | ||
1245 | kfree(string); | ||
1246 | if (rc != 0) | ||
1247 | goto out_invalid_value; | 1209 | goto out_invalid_value; |
1248 | mnt->namlen = option; | 1210 | mnt->namlen = option; |
1249 | break; | 1211 | break; |
1250 | case Opt_mountport: | 1212 | case Opt_mountport: |
1251 | string = match_strdup(args); | 1213 | if (nfs_get_option_ul(args, &option) || |
1252 | if (string == NULL) | 1214 | option > USHRT_MAX) |
1253 | goto out_nomem; | ||
1254 | rc = strict_strtoul(string, 10, &option); | ||
1255 | kfree(string); | ||
1256 | if (rc != 0 || option > USHRT_MAX) | ||
1257 | goto out_invalid_value; | 1215 | goto out_invalid_value; |
1258 | mnt->mount_server.port = option; | 1216 | mnt->mount_server.port = option; |
1259 | break; | 1217 | break; |
1260 | case Opt_mountvers: | 1218 | case Opt_mountvers: |
1261 | string = match_strdup(args); | 1219 | if (nfs_get_option_ul(args, &option) || |
1262 | if (string == NULL) | ||
1263 | goto out_nomem; | ||
1264 | rc = strict_strtoul(string, 10, &option); | ||
1265 | kfree(string); | ||
1266 | if (rc != 0 || | ||
1267 | option < NFS_MNT_VERSION || | 1220 | option < NFS_MNT_VERSION || |
1268 | option > NFS_MNT3_VERSION) | 1221 | option > NFS_MNT3_VERSION) |
1269 | goto out_invalid_value; | 1222 | goto out_invalid_value; |
1270 | mnt->mount_server.version = option; | 1223 | mnt->mount_server.version = option; |
1271 | break; | 1224 | break; |
1272 | case Opt_nfsvers: | 1225 | case Opt_nfsvers: |
1273 | string = match_strdup(args); | 1226 | if (nfs_get_option_ul(args, &option)) |
1274 | if (string == NULL) | ||
1275 | goto out_nomem; | ||
1276 | rc = strict_strtoul(string, 10, &option); | ||
1277 | kfree(string); | ||
1278 | if (rc != 0) | ||
1279 | goto out_invalid_value; | 1227 | goto out_invalid_value; |
1280 | switch (option) { | 1228 | switch (option) { |
1281 | case NFS2_VERSION: | 1229 | case NFS2_VERSION: |
@@ -1295,12 +1243,7 @@ static int nfs_parse_mount_options(char *raw, | |||
1295 | } | 1243 | } |
1296 | break; | 1244 | break; |
1297 | case Opt_minorversion: | 1245 | case Opt_minorversion: |
1298 | string = match_strdup(args); | 1246 | if (nfs_get_option_ul(args, &option)) |
1299 | if (string == NULL) | ||
1300 | goto out_nomem; | ||
1301 | rc = strict_strtoul(string, 10, &option); | ||
1302 | kfree(string); | ||
1303 | if (rc != 0) | ||
1304 | goto out_invalid_value; | 1247 | goto out_invalid_value; |
1305 | if (option > NFS4_MAX_MINOR_VERSION) | 1248 | if (option > NFS4_MAX_MINOR_VERSION) |
1306 | goto out_invalid_value; | 1249 | goto out_invalid_value; |
@@ -1336,21 +1279,18 @@ static int nfs_parse_mount_options(char *raw, | |||
1336 | case Opt_xprt_udp: | 1279 | case Opt_xprt_udp: |
1337 | mnt->flags &= ~NFS_MOUNT_TCP; | 1280 | mnt->flags &= ~NFS_MOUNT_TCP; |
1338 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 1281 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
1339 | kfree(string); | ||
1340 | break; | 1282 | break; |
1341 | case Opt_xprt_tcp6: | 1283 | case Opt_xprt_tcp6: |
1342 | protofamily = AF_INET6; | 1284 | protofamily = AF_INET6; |
1343 | case Opt_xprt_tcp: | 1285 | case Opt_xprt_tcp: |
1344 | mnt->flags |= NFS_MOUNT_TCP; | 1286 | mnt->flags |= NFS_MOUNT_TCP; |
1345 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1287 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
1346 | kfree(string); | ||
1347 | break; | 1288 | break; |
1348 | case Opt_xprt_rdma: | 1289 | case Opt_xprt_rdma: |
1349 | /* vector side protocols to TCP */ | 1290 | /* vector side protocols to TCP */ |
1350 | mnt->flags |= NFS_MOUNT_TCP; | 1291 | mnt->flags |= NFS_MOUNT_TCP; |
1351 | mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; | 1292 | mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA; |
1352 | xprt_load_transport(string); | 1293 | xprt_load_transport(string); |
1353 | kfree(string); | ||
1354 | break; | 1294 | break; |
1355 | default: | 1295 | default: |
1356 | dfprintk(MOUNT, "NFS: unrecognized " | 1296 | dfprintk(MOUNT, "NFS: unrecognized " |
@@ -1358,6 +1298,7 @@ static int nfs_parse_mount_options(char *raw, | |||
1358 | kfree(string); | 1298 | kfree(string); |
1359 | return 0; | 1299 | return 0; |
1360 | } | 1300 | } |
1301 | kfree(string); | ||
1361 | break; | 1302 | break; |
1362 | case Opt_mountproto: | 1303 | case Opt_mountproto: |
1363 | string = match_strdup(args); | 1304 | string = match_strdup(args); |
@@ -1400,18 +1341,13 @@ static int nfs_parse_mount_options(char *raw, | |||
1400 | goto out_invalid_address; | 1341 | goto out_invalid_address; |
1401 | break; | 1342 | break; |
1402 | case Opt_clientaddr: | 1343 | case Opt_clientaddr: |
1403 | string = match_strdup(args); | 1344 | if (nfs_get_option_str(args, &mnt->client_address)) |
1404 | if (string == NULL) | ||
1405 | goto out_nomem; | 1345 | goto out_nomem; |
1406 | kfree(mnt->client_address); | ||
1407 | mnt->client_address = string; | ||
1408 | break; | 1346 | break; |
1409 | case Opt_mounthost: | 1347 | case Opt_mounthost: |
1410 | string = match_strdup(args); | 1348 | if (nfs_get_option_str(args, |
1411 | if (string == NULL) | 1349 | &mnt->mount_server.hostname)) |
1412 | goto out_nomem; | 1350 | goto out_nomem; |
1413 | kfree(mnt->mount_server.hostname); | ||
1414 | mnt->mount_server.hostname = string; | ||
1415 | break; | 1351 | break; |
1416 | case Opt_mountaddr: | 1352 | case Opt_mountaddr: |
1417 | string = match_strdup(args); | 1353 | string = match_strdup(args); |
@@ -1451,11 +1387,8 @@ static int nfs_parse_mount_options(char *raw, | |||
1451 | }; | 1387 | }; |
1452 | break; | 1388 | break; |
1453 | case Opt_fscache_uniq: | 1389 | case Opt_fscache_uniq: |
1454 | string = match_strdup(args); | 1390 | if (nfs_get_option_str(args, &mnt->fscache_uniq)) |
1455 | if (string == NULL) | ||
1456 | goto out_nomem; | 1391 | goto out_nomem; |
1457 | kfree(mnt->fscache_uniq); | ||
1458 | mnt->fscache_uniq = string; | ||
1459 | mnt->options |= NFS_OPTION_FSCACHE; | 1392 | mnt->options |= NFS_OPTION_FSCACHE; |
1460 | break; | 1393 | break; |
1461 | case Opt_local_lock: | 1394 | case Opt_local_lock: |