diff options
-rw-r--r-- | fs/nfs/super.c | 94 |
1 files changed, 81 insertions, 13 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f0188eaf3726..bfad74648754 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -175,14 +175,16 @@ static const match_table_t nfs_mount_option_tokens = { | |||
175 | }; | 175 | }; |
176 | 176 | ||
177 | enum { | 177 | enum { |
178 | Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_rdma, | 178 | Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma, |
179 | 179 | ||
180 | Opt_xprt_err | 180 | Opt_xprt_err |
181 | }; | 181 | }; |
182 | 182 | ||
183 | static const match_table_t nfs_xprt_protocol_tokens = { | 183 | static const match_table_t nfs_xprt_protocol_tokens = { |
184 | { Opt_xprt_udp, "udp" }, | 184 | { Opt_xprt_udp, "udp" }, |
185 | { Opt_xprt_udp6, "udp6" }, | ||
185 | { Opt_xprt_tcp, "tcp" }, | 186 | { Opt_xprt_tcp, "tcp" }, |
187 | { Opt_xprt_tcp6, "tcp6" }, | ||
186 | { Opt_xprt_rdma, "rdma" }, | 188 | { Opt_xprt_rdma, "rdma" }, |
187 | 189 | ||
188 | { Opt_xprt_err, NULL } | 190 | { Opt_xprt_err, NULL } |
@@ -492,6 +494,45 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) | |||
492 | return sec_flavours[i].str; | 494 | return sec_flavours[i].str; |
493 | } | 495 | } |
494 | 496 | ||
497 | static void nfs_show_mountd_netid(struct seq_file *m, struct nfs_server *nfss, | ||
498 | int showdefaults) | ||
499 | { | ||
500 | struct sockaddr *sap = (struct sockaddr *) &nfss->mountd_address; | ||
501 | |||
502 | seq_printf(m, ",mountproto="); | ||
503 | switch (sap->sa_family) { | ||
504 | case AF_INET: | ||
505 | switch (nfss->mountd_protocol) { | ||
506 | case IPPROTO_UDP: | ||
507 | seq_printf(m, RPCBIND_NETID_UDP); | ||
508 | break; | ||
509 | case IPPROTO_TCP: | ||
510 | seq_printf(m, RPCBIND_NETID_TCP); | ||
511 | break; | ||
512 | default: | ||
513 | if (showdefaults) | ||
514 | seq_printf(m, "auto"); | ||
515 | } | ||
516 | break; | ||
517 | case AF_INET6: | ||
518 | switch (nfss->mountd_protocol) { | ||
519 | case IPPROTO_UDP: | ||
520 | seq_printf(m, RPCBIND_NETID_UDP6); | ||
521 | break; | ||
522 | case IPPROTO_TCP: | ||
523 | seq_printf(m, RPCBIND_NETID_TCP6); | ||
524 | break; | ||
525 | default: | ||
526 | if (showdefaults) | ||
527 | seq_printf(m, "auto"); | ||
528 | } | ||
529 | break; | ||
530 | default: | ||
531 | if (showdefaults) | ||
532 | seq_printf(m, "auto"); | ||
533 | } | ||
534 | } | ||
535 | |||
495 | static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | 536 | static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, |
496 | int showdefaults) | 537 | int showdefaults) |
497 | { | 538 | { |
@@ -518,17 +559,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | |||
518 | if (nfss->mountd_port || showdefaults) | 559 | if (nfss->mountd_port || showdefaults) |
519 | seq_printf(m, ",mountport=%u", nfss->mountd_port); | 560 | seq_printf(m, ",mountport=%u", nfss->mountd_port); |
520 | 561 | ||
521 | switch (nfss->mountd_protocol) { | 562 | nfs_show_mountd_netid(m, nfss, showdefaults); |
522 | case IPPROTO_UDP: | ||
523 | seq_printf(m, ",mountproto=udp"); | ||
524 | break; | ||
525 | case IPPROTO_TCP: | ||
526 | seq_printf(m, ",mountproto=tcp"); | ||
527 | break; | ||
528 | default: | ||
529 | if (showdefaults) | ||
530 | seq_printf(m, ",mountproto=auto"); | ||
531 | } | ||
532 | } | 563 | } |
533 | 564 | ||
534 | /* | 565 | /* |
@@ -578,7 +609,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
578 | seq_puts(m, nfs_infop->nostr); | 609 | seq_puts(m, nfs_infop->nostr); |
579 | } | 610 | } |
580 | seq_printf(m, ",proto=%s", | 611 | seq_printf(m, ",proto=%s", |
581 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); | 612 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_NETID)); |
582 | if (version == 4) { | 613 | if (version == 4) { |
583 | if (nfss->port != NFS_PORT) | 614 | if (nfss->port != NFS_PORT) |
584 | seq_printf(m, ",port=%u", nfss->port); | 615 | seq_printf(m, ",port=%u", nfss->port); |
@@ -883,6 +914,8 @@ static int nfs_parse_mount_options(char *raw, | |||
883 | { | 914 | { |
884 | char *p, *string, *secdata; | 915 | char *p, *string, *secdata; |
885 | int rc, sloppy = 0, invalid_option = 0; | 916 | int rc, sloppy = 0, invalid_option = 0; |
917 | unsigned short protofamily = AF_UNSPEC; | ||
918 | unsigned short mountfamily = AF_UNSPEC; | ||
886 | 919 | ||
887 | if (!raw) { | 920 | if (!raw) { |
888 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); | 921 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); |
@@ -1228,12 +1261,17 @@ static int nfs_parse_mount_options(char *raw, | |||
1228 | token = match_token(string, | 1261 | token = match_token(string, |
1229 | nfs_xprt_protocol_tokens, args); | 1262 | nfs_xprt_protocol_tokens, args); |
1230 | 1263 | ||
1264 | protofamily = AF_INET; | ||
1231 | switch (token) { | 1265 | switch (token) { |
1266 | case Opt_xprt_udp6: | ||
1267 | protofamily = AF_INET6; | ||
1232 | case Opt_xprt_udp: | 1268 | case Opt_xprt_udp: |
1233 | mnt->flags &= ~NFS_MOUNT_TCP; | 1269 | mnt->flags &= ~NFS_MOUNT_TCP; |
1234 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 1270 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
1235 | kfree(string); | 1271 | kfree(string); |
1236 | break; | 1272 | break; |
1273 | case Opt_xprt_tcp6: | ||
1274 | protofamily = AF_INET6; | ||
1237 | case Opt_xprt_tcp: | 1275 | case Opt_xprt_tcp: |
1238 | mnt->flags |= NFS_MOUNT_TCP; | 1276 | mnt->flags |= NFS_MOUNT_TCP; |
1239 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1277 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
@@ -1261,10 +1299,15 @@ static int nfs_parse_mount_options(char *raw, | |||
1261 | nfs_xprt_protocol_tokens, args); | 1299 | nfs_xprt_protocol_tokens, args); |
1262 | kfree(string); | 1300 | kfree(string); |
1263 | 1301 | ||
1302 | mountfamily = AF_INET; | ||
1264 | switch (token) { | 1303 | switch (token) { |
1304 | case Opt_xprt_udp6: | ||
1305 | mountfamily = AF_INET6; | ||
1265 | case Opt_xprt_udp: | 1306 | case Opt_xprt_udp: |
1266 | mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; | 1307 | mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; |
1267 | break; | 1308 | break; |
1309 | case Opt_xprt_tcp6: | ||
1310 | mountfamily = AF_INET6; | ||
1268 | case Opt_xprt_tcp: | 1311 | case Opt_xprt_tcp: |
1269 | mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; | 1312 | mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; |
1270 | break; | 1313 | break; |
@@ -1363,8 +1406,33 @@ static int nfs_parse_mount_options(char *raw, | |||
1363 | if (!sloppy && invalid_option) | 1406 | if (!sloppy && invalid_option) |
1364 | return 0; | 1407 | return 0; |
1365 | 1408 | ||
1409 | /* | ||
1410 | * verify that any proto=/mountproto= options match the address | ||
1411 | * familiies in the addr=/mountaddr= options. | ||
1412 | */ | ||
1413 | if (protofamily != AF_UNSPEC && | ||
1414 | protofamily != mnt->nfs_server.address.ss_family) | ||
1415 | goto out_proto_mismatch; | ||
1416 | |||
1417 | if (mountfamily != AF_UNSPEC) { | ||
1418 | if (mnt->mount_server.addrlen) { | ||
1419 | if (mountfamily != mnt->mount_server.address.ss_family) | ||
1420 | goto out_mountproto_mismatch; | ||
1421 | } else { | ||
1422 | if (mountfamily != mnt->nfs_server.address.ss_family) | ||
1423 | goto out_mountproto_mismatch; | ||
1424 | } | ||
1425 | } | ||
1426 | |||
1366 | return 1; | 1427 | return 1; |
1367 | 1428 | ||
1429 | out_mountproto_mismatch: | ||
1430 | printk(KERN_INFO "NFS: mount server address does not match mountproto= " | ||
1431 | "option\n"); | ||
1432 | return 0; | ||
1433 | out_proto_mismatch: | ||
1434 | printk(KERN_INFO "NFS: server address does not match proto= option\n"); | ||
1435 | return 0; | ||
1368 | out_invalid_address: | 1436 | out_invalid_address: |
1369 | printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); | 1437 | printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); |
1370 | return 0; | 1438 | return 0; |