diff options
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 104 |
1 files changed, 82 insertions, 22 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 90be551b80c1..ce907efc5508 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 | { |
@@ -505,7 +546,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | |||
505 | } | 546 | } |
506 | case AF_INET6: { | 547 | case AF_INET6: { |
507 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | 548 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; |
508 | seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr); | 549 | seq_printf(m, ",mountaddr=%pI6c", &sin6->sin6_addr); |
509 | break; | 550 | break; |
510 | } | 551 | } |
511 | default: | 552 | default: |
@@ -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); |
@@ -714,8 +745,6 @@ static void nfs_umount_begin(struct super_block *sb) | |||
714 | struct nfs_server *server; | 745 | struct nfs_server *server; |
715 | struct rpc_clnt *rpc; | 746 | struct rpc_clnt *rpc; |
716 | 747 | ||
717 | lock_kernel(); | ||
718 | |||
719 | server = NFS_SB(sb); | 748 | server = NFS_SB(sb); |
720 | /* -EIO all pending I/O */ | 749 | /* -EIO all pending I/O */ |
721 | rpc = server->client_acl; | 750 | rpc = server->client_acl; |
@@ -724,8 +753,6 @@ static void nfs_umount_begin(struct super_block *sb) | |||
724 | rpc = server->client; | 753 | rpc = server->client; |
725 | if (!IS_ERR(rpc)) | 754 | if (!IS_ERR(rpc)) |
726 | rpc_killall_tasks(rpc); | 755 | rpc_killall_tasks(rpc); |
727 | |||
728 | unlock_kernel(); | ||
729 | } | 756 | } |
730 | 757 | ||
731 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version) | 758 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version) |
@@ -734,8 +761,6 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve | |||
734 | 761 | ||
735 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 762 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
736 | if (data) { | 763 | if (data) { |
737 | data->rsize = NFS_MAX_FILE_IO_SIZE; | ||
738 | data->wsize = NFS_MAX_FILE_IO_SIZE; | ||
739 | data->acregmin = NFS_DEF_ACREGMIN; | 764 | data->acregmin = NFS_DEF_ACREGMIN; |
740 | data->acregmax = NFS_DEF_ACREGMAX; | 765 | data->acregmax = NFS_DEF_ACREGMAX; |
741 | data->acdirmin = NFS_DEF_ACDIRMIN; | 766 | data->acdirmin = NFS_DEF_ACDIRMIN; |
@@ -887,6 +912,8 @@ static int nfs_parse_mount_options(char *raw, | |||
887 | { | 912 | { |
888 | char *p, *string, *secdata; | 913 | char *p, *string, *secdata; |
889 | int rc, sloppy = 0, invalid_option = 0; | 914 | int rc, sloppy = 0, invalid_option = 0; |
915 | unsigned short protofamily = AF_UNSPEC; | ||
916 | unsigned short mountfamily = AF_UNSPEC; | ||
890 | 917 | ||
891 | if (!raw) { | 918 | if (!raw) { |
892 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); | 919 | dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); |
@@ -1232,12 +1259,17 @@ static int nfs_parse_mount_options(char *raw, | |||
1232 | token = match_token(string, | 1259 | token = match_token(string, |
1233 | nfs_xprt_protocol_tokens, args); | 1260 | nfs_xprt_protocol_tokens, args); |
1234 | 1261 | ||
1262 | protofamily = AF_INET; | ||
1235 | switch (token) { | 1263 | switch (token) { |
1264 | case Opt_xprt_udp6: | ||
1265 | protofamily = AF_INET6; | ||
1236 | case Opt_xprt_udp: | 1266 | case Opt_xprt_udp: |
1237 | mnt->flags &= ~NFS_MOUNT_TCP; | 1267 | mnt->flags &= ~NFS_MOUNT_TCP; |
1238 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 1268 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
1239 | kfree(string); | 1269 | kfree(string); |
1240 | break; | 1270 | break; |
1271 | case Opt_xprt_tcp6: | ||
1272 | protofamily = AF_INET6; | ||
1241 | case Opt_xprt_tcp: | 1273 | case Opt_xprt_tcp: |
1242 | mnt->flags |= NFS_MOUNT_TCP; | 1274 | mnt->flags |= NFS_MOUNT_TCP; |
1243 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1275 | mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
@@ -1265,10 +1297,15 @@ static int nfs_parse_mount_options(char *raw, | |||
1265 | nfs_xprt_protocol_tokens, args); | 1297 | nfs_xprt_protocol_tokens, args); |
1266 | kfree(string); | 1298 | kfree(string); |
1267 | 1299 | ||
1300 | mountfamily = AF_INET; | ||
1268 | switch (token) { | 1301 | switch (token) { |
1302 | case Opt_xprt_udp6: | ||
1303 | mountfamily = AF_INET6; | ||
1269 | case Opt_xprt_udp: | 1304 | case Opt_xprt_udp: |
1270 | mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; | 1305 | mnt->mount_server.protocol = XPRT_TRANSPORT_UDP; |
1271 | break; | 1306 | break; |
1307 | case Opt_xprt_tcp6: | ||
1308 | mountfamily = AF_INET6; | ||
1272 | case Opt_xprt_tcp: | 1309 | case Opt_xprt_tcp: |
1273 | mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; | 1310 | mnt->mount_server.protocol = XPRT_TRANSPORT_TCP; |
1274 | break; | 1311 | break; |
@@ -1367,8 +1404,33 @@ static int nfs_parse_mount_options(char *raw, | |||
1367 | if (!sloppy && invalid_option) | 1404 | if (!sloppy && invalid_option) |
1368 | return 0; | 1405 | return 0; |
1369 | 1406 | ||
1407 | /* | ||
1408 | * verify that any proto=/mountproto= options match the address | ||
1409 | * familiies in the addr=/mountaddr= options. | ||
1410 | */ | ||
1411 | if (protofamily != AF_UNSPEC && | ||
1412 | protofamily != mnt->nfs_server.address.ss_family) | ||
1413 | goto out_proto_mismatch; | ||
1414 | |||
1415 | if (mountfamily != AF_UNSPEC) { | ||
1416 | if (mnt->mount_server.addrlen) { | ||
1417 | if (mountfamily != mnt->mount_server.address.ss_family) | ||
1418 | goto out_mountproto_mismatch; | ||
1419 | } else { | ||
1420 | if (mountfamily != mnt->nfs_server.address.ss_family) | ||
1421 | goto out_mountproto_mismatch; | ||
1422 | } | ||
1423 | } | ||
1424 | |||
1370 | return 1; | 1425 | return 1; |
1371 | 1426 | ||
1427 | out_mountproto_mismatch: | ||
1428 | printk(KERN_INFO "NFS: mount server address does not match mountproto= " | ||
1429 | "option\n"); | ||
1430 | return 0; | ||
1431 | out_proto_mismatch: | ||
1432 | printk(KERN_INFO "NFS: server address does not match proto= option\n"); | ||
1433 | return 0; | ||
1372 | out_invalid_address: | 1434 | out_invalid_address: |
1373 | printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); | 1435 | printk(KERN_INFO "NFS: bad IP address specified: %s\n", p); |
1374 | return 0; | 1436 | return 0; |
@@ -1881,7 +1943,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) | |||
1881 | if (data == NULL) | 1943 | if (data == NULL) |
1882 | return -ENOMEM; | 1944 | return -ENOMEM; |
1883 | 1945 | ||
1884 | lock_kernel(); | ||
1885 | /* fill out struct with values from existing mount */ | 1946 | /* fill out struct with values from existing mount */ |
1886 | data->flags = nfss->flags; | 1947 | data->flags = nfss->flags; |
1887 | data->rsize = nfss->rsize; | 1948 | data->rsize = nfss->rsize; |
@@ -1907,7 +1968,6 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data) | |||
1907 | error = nfs_compare_remount_data(nfss, data); | 1968 | error = nfs_compare_remount_data(nfss, data); |
1908 | out: | 1969 | out: |
1909 | kfree(data); | 1970 | kfree(data); |
1910 | unlock_kernel(); | ||
1911 | return error; | 1971 | return error; |
1912 | } | 1972 | } |
1913 | 1973 | ||