diff options
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 147 |
1 files changed, 100 insertions, 47 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f9219024f31a..20a1cb1810fe 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -441,10 +441,52 @@ static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour) | |||
441 | return sec_flavours[i].str; | 441 | return sec_flavours[i].str; |
442 | } | 442 | } |
443 | 443 | ||
444 | static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | ||
445 | int showdefaults) | ||
446 | { | ||
447 | struct sockaddr *sap = (struct sockaddr *)&nfss->mountd_address; | ||
448 | |||
449 | switch (sap->sa_family) { | ||
450 | case AF_INET: { | ||
451 | struct sockaddr_in *sin = (struct sockaddr_in *)sap; | ||
452 | seq_printf(m, ",mountaddr=" NIPQUAD_FMT, | ||
453 | NIPQUAD(sin->sin_addr.s_addr)); | ||
454 | break; | ||
455 | } | ||
456 | case AF_INET6: { | ||
457 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | ||
458 | seq_printf(m, ",mountaddr=" NIP6_FMT, | ||
459 | NIP6(sin6->sin6_addr)); | ||
460 | break; | ||
461 | } | ||
462 | default: | ||
463 | if (showdefaults) | ||
464 | seq_printf(m, ",mountaddr=unspecified"); | ||
465 | } | ||
466 | |||
467 | if (nfss->mountd_version || showdefaults) | ||
468 | seq_printf(m, ",mountvers=%u", nfss->mountd_version); | ||
469 | if (nfss->mountd_port || showdefaults) | ||
470 | seq_printf(m, ",mountport=%u", nfss->mountd_port); | ||
471 | |||
472 | switch (nfss->mountd_protocol) { | ||
473 | case IPPROTO_UDP: | ||
474 | seq_printf(m, ",mountproto=udp"); | ||
475 | break; | ||
476 | case IPPROTO_TCP: | ||
477 | seq_printf(m, ",mountproto=tcp"); | ||
478 | break; | ||
479 | default: | ||
480 | if (showdefaults) | ||
481 | seq_printf(m, ",mountproto=auto"); | ||
482 | } | ||
483 | } | ||
484 | |||
444 | /* | 485 | /* |
445 | * Describe the mount options in force on this server representation | 486 | * Describe the mount options in force on this server representation |
446 | */ | 487 | */ |
447 | static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults) | 488 | static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, |
489 | int showdefaults) | ||
448 | { | 490 | { |
449 | static const struct proc_nfs_info { | 491 | static const struct proc_nfs_info { |
450 | int flag; | 492 | int flag; |
@@ -452,6 +494,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
452 | const char *nostr; | 494 | const char *nostr; |
453 | } nfs_info[] = { | 495 | } nfs_info[] = { |
454 | { NFS_MOUNT_SOFT, ",soft", ",hard" }, | 496 | { NFS_MOUNT_SOFT, ",soft", ",hard" }, |
497 | { NFS_MOUNT_INTR, ",intr", ",nointr" }, | ||
498 | { NFS_MOUNT_POSIX, ",posix", "" }, | ||
455 | { NFS_MOUNT_NOCTO, ",nocto", "" }, | 499 | { NFS_MOUNT_NOCTO, ",nocto", "" }, |
456 | { NFS_MOUNT_NOAC, ",noac", "" }, | 500 | { NFS_MOUNT_NOAC, ",noac", "" }, |
457 | { NFS_MOUNT_NONLM, ",nolock", "" }, | 501 | { NFS_MOUNT_NONLM, ",nolock", "" }, |
@@ -462,18 +506,22 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
462 | }; | 506 | }; |
463 | const struct proc_nfs_info *nfs_infop; | 507 | const struct proc_nfs_info *nfs_infop; |
464 | struct nfs_client *clp = nfss->nfs_client; | 508 | struct nfs_client *clp = nfss->nfs_client; |
465 | 509 | u32 version = clp->rpc_ops->version; | |
466 | seq_printf(m, ",vers=%d", clp->rpc_ops->version); | 510 | |
467 | seq_printf(m, ",rsize=%d", nfss->rsize); | 511 | seq_printf(m, ",vers=%u", version); |
468 | seq_printf(m, ",wsize=%d", nfss->wsize); | 512 | seq_printf(m, ",rsize=%u", nfss->rsize); |
513 | seq_printf(m, ",wsize=%u", nfss->wsize); | ||
514 | if (nfss->bsize != 0) | ||
515 | seq_printf(m, ",bsize=%u", nfss->bsize); | ||
516 | seq_printf(m, ",namlen=%u", nfss->namelen); | ||
469 | if (nfss->acregmin != 3*HZ || showdefaults) | 517 | if (nfss->acregmin != 3*HZ || showdefaults) |
470 | seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ); | 518 | seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ); |
471 | if (nfss->acregmax != 60*HZ || showdefaults) | 519 | if (nfss->acregmax != 60*HZ || showdefaults) |
472 | seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ); | 520 | seq_printf(m, ",acregmax=%u", nfss->acregmax/HZ); |
473 | if (nfss->acdirmin != 30*HZ || showdefaults) | 521 | if (nfss->acdirmin != 30*HZ || showdefaults) |
474 | seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ); | 522 | seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ); |
475 | if (nfss->acdirmax != 60*HZ || showdefaults) | 523 | if (nfss->acdirmax != 60*HZ || showdefaults) |
476 | seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ); | 524 | seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ); |
477 | for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { | 525 | for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { |
478 | if (nfss->flags & nfs_infop->flag) | 526 | if (nfss->flags & nfs_infop->flag) |
479 | seq_puts(m, nfs_infop->str); | 527 | seq_puts(m, nfs_infop->str); |
@@ -482,9 +530,24 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
482 | } | 530 | } |
483 | seq_printf(m, ",proto=%s", | 531 | seq_printf(m, ",proto=%s", |
484 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); | 532 | rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO)); |
533 | if (version == 4) { | ||
534 | if (nfss->port != NFS_PORT) | ||
535 | seq_printf(m, ",port=%u", nfss->port); | ||
536 | } else | ||
537 | if (nfss->port) | ||
538 | seq_printf(m, ",port=%u", nfss->port); | ||
539 | |||
485 | seq_printf(m, ",timeo=%lu", 10U * nfss->client->cl_timeout->to_initval / HZ); | 540 | seq_printf(m, ",timeo=%lu", 10U * nfss->client->cl_timeout->to_initval / HZ); |
486 | seq_printf(m, ",retrans=%u", nfss->client->cl_timeout->to_retries); | 541 | seq_printf(m, ",retrans=%u", nfss->client->cl_timeout->to_retries); |
487 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); | 542 | seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor)); |
543 | |||
544 | if (version != 4) | ||
545 | nfs_show_mountd_options(m, nfss, showdefaults); | ||
546 | |||
547 | #ifdef CONFIG_NFS_V4 | ||
548 | if (clp->rpc_ops->version == 4) | ||
549 | seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr); | ||
550 | #endif | ||
488 | } | 551 | } |
489 | 552 | ||
490 | /* | 553 | /* |
@@ -529,10 +592,10 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) | |||
529 | 592 | ||
530 | seq_printf(m, "\n\tcaps:\t"); | 593 | seq_printf(m, "\n\tcaps:\t"); |
531 | seq_printf(m, "caps=0x%x", nfss->caps); | 594 | seq_printf(m, "caps=0x%x", nfss->caps); |
532 | seq_printf(m, ",wtmult=%d", nfss->wtmult); | 595 | seq_printf(m, ",wtmult=%u", nfss->wtmult); |
533 | seq_printf(m, ",dtsize=%d", nfss->dtsize); | 596 | seq_printf(m, ",dtsize=%u", nfss->dtsize); |
534 | seq_printf(m, ",bsize=%d", nfss->bsize); | 597 | seq_printf(m, ",bsize=%u", nfss->bsize); |
535 | seq_printf(m, ",namelen=%d", nfss->namelen); | 598 | seq_printf(m, ",namlen=%u", nfss->namelen); |
536 | 599 | ||
537 | #ifdef CONFIG_NFS_V4 | 600 | #ifdef CONFIG_NFS_V4 |
538 | if (nfss->nfs_client->rpc_ops->version == 4) { | 601 | if (nfss->nfs_client->rpc_ops->version == 4) { |
@@ -546,9 +609,9 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) | |||
546 | /* | 609 | /* |
547 | * Display security flavor in effect for this mount | 610 | * Display security flavor in effect for this mount |
548 | */ | 611 | */ |
549 | seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor); | 612 | seq_printf(m, "\n\tsec:\tflavor=%u", auth->au_ops->au_flavor); |
550 | if (auth->au_flavor) | 613 | if (auth->au_flavor) |
551 | seq_printf(m, ",pseudoflavor=%d", auth->au_flavor); | 614 | seq_printf(m, ",pseudoflavor=%u", auth->au_flavor); |
552 | 615 | ||
553 | /* | 616 | /* |
554 | * Display superblock I/O counters | 617 | * Display superblock I/O counters |
@@ -683,7 +746,6 @@ static int nfs_parse_mount_options(char *raw, | |||
683 | struct nfs_parsed_mount_data *mnt) | 746 | struct nfs_parsed_mount_data *mnt) |
684 | { | 747 | { |
685 | char *p, *string, *secdata; | 748 | char *p, *string, *secdata; |
686 | unsigned short port = 0; | ||
687 | int rc; | 749 | int rc; |
688 | 750 | ||
689 | if (!raw) { | 751 | if (!raw) { |
@@ -798,7 +860,7 @@ static int nfs_parse_mount_options(char *raw, | |||
798 | return 0; | 860 | return 0; |
799 | if (option < 0 || option > 65535) | 861 | if (option < 0 || option > 65535) |
800 | return 0; | 862 | return 0; |
801 | port = option; | 863 | mnt->nfs_server.port = option; |
802 | break; | 864 | break; |
803 | case Opt_rsize: | 865 | case Opt_rsize: |
804 | if (match_int(args, &mnt->rsize)) | 866 | if (match_int(args, &mnt->rsize)) |
@@ -1048,7 +1110,8 @@ static int nfs_parse_mount_options(char *raw, | |||
1048 | } | 1110 | } |
1049 | } | 1111 | } |
1050 | 1112 | ||
1051 | nfs_set_port((struct sockaddr *)&mnt->nfs_server.address, port); | 1113 | nfs_set_port((struct sockaddr *)&mnt->nfs_server.address, |
1114 | mnt->nfs_server.port); | ||
1052 | 1115 | ||
1053 | return 1; | 1116 | return 1; |
1054 | 1117 | ||
@@ -1169,7 +1232,9 @@ static int nfs_validate_mount_data(void *options, | |||
1169 | args->acregmax = 60; | 1232 | args->acregmax = 60; |
1170 | args->acdirmin = 30; | 1233 | args->acdirmin = 30; |
1171 | args->acdirmax = 60; | 1234 | args->acdirmax = 60; |
1235 | args->mount_server.port = 0; /* autobind unless user sets port */ | ||
1172 | args->mount_server.protocol = XPRT_TRANSPORT_UDP; | 1236 | args->mount_server.protocol = XPRT_TRANSPORT_UDP; |
1237 | args->nfs_server.port = 0; /* autobind unless user sets port */ | ||
1173 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1238 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
1174 | 1239 | ||
1175 | switch (data->version) { | 1240 | switch (data->version) { |
@@ -1208,7 +1273,6 @@ static int nfs_validate_mount_data(void *options, | |||
1208 | args->flags = data->flags; | 1273 | args->flags = data->flags; |
1209 | args->rsize = data->rsize; | 1274 | args->rsize = data->rsize; |
1210 | args->wsize = data->wsize; | 1275 | args->wsize = data->wsize; |
1211 | args->flags = data->flags; | ||
1212 | args->timeo = data->timeo; | 1276 | args->timeo = data->timeo; |
1213 | args->retrans = data->retrans; | 1277 | args->retrans = data->retrans; |
1214 | args->acregmin = data->acregmin; | 1278 | args->acregmin = data->acregmin; |
@@ -1230,6 +1294,8 @@ static int nfs_validate_mount_data(void *options, | |||
1230 | args->namlen = data->namlen; | 1294 | args->namlen = data->namlen; |
1231 | args->bsize = data->bsize; | 1295 | args->bsize = data->bsize; |
1232 | args->auth_flavors[0] = data->pseudoflavor; | 1296 | args->auth_flavors[0] = data->pseudoflavor; |
1297 | if (!args->nfs_server.hostname) | ||
1298 | goto out_nomem; | ||
1233 | 1299 | ||
1234 | /* | 1300 | /* |
1235 | * The legacy version 6 binary mount data from userspace has a | 1301 | * The legacy version 6 binary mount data from userspace has a |
@@ -1276,6 +1342,8 @@ static int nfs_validate_mount_data(void *options, | |||
1276 | len = c - dev_name; | 1342 | len = c - dev_name; |
1277 | /* N.B. caller will free nfs_server.hostname in all cases */ | 1343 | /* N.B. caller will free nfs_server.hostname in all cases */ |
1278 | args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); | 1344 | args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); |
1345 | if (!args->nfs_server.hostname) | ||
1346 | goto out_nomem; | ||
1279 | 1347 | ||
1280 | c++; | 1348 | c++; |
1281 | if (strlen(c) > NFS_MAXPATHLEN) | 1349 | if (strlen(c) > NFS_MAXPATHLEN) |
@@ -1319,6 +1387,10 @@ out_v3_not_compiled: | |||
1319 | return -EPROTONOSUPPORT; | 1387 | return -EPROTONOSUPPORT; |
1320 | #endif /* !CONFIG_NFS_V3 */ | 1388 | #endif /* !CONFIG_NFS_V3 */ |
1321 | 1389 | ||
1390 | out_nomem: | ||
1391 | dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n"); | ||
1392 | return -ENOMEM; | ||
1393 | |||
1322 | out_no_address: | 1394 | out_no_address: |
1323 | dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); | 1395 | dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n"); |
1324 | return -EINVAL; | 1396 | return -EINVAL; |
@@ -1706,28 +1778,6 @@ static void nfs4_fill_super(struct super_block *sb) | |||
1706 | } | 1778 | } |
1707 | 1779 | ||
1708 | /* | 1780 | /* |
1709 | * If the user didn't specify a port, set the port number to | ||
1710 | * the NFS version 4 default port. | ||
1711 | */ | ||
1712 | static void nfs4_default_port(struct sockaddr *sap) | ||
1713 | { | ||
1714 | switch (sap->sa_family) { | ||
1715 | case AF_INET: { | ||
1716 | struct sockaddr_in *ap = (struct sockaddr_in *)sap; | ||
1717 | if (ap->sin_port == 0) | ||
1718 | ap->sin_port = htons(NFS_PORT); | ||
1719 | break; | ||
1720 | } | ||
1721 | case AF_INET6: { | ||
1722 | struct sockaddr_in6 *ap = (struct sockaddr_in6 *)sap; | ||
1723 | if (ap->sin6_port == 0) | ||
1724 | ap->sin6_port = htons(NFS_PORT); | ||
1725 | break; | ||
1726 | } | ||
1727 | } | ||
1728 | } | ||
1729 | |||
1730 | /* | ||
1731 | * Validate NFSv4 mount options | 1781 | * Validate NFSv4 mount options |
1732 | */ | 1782 | */ |
1733 | static int nfs4_validate_mount_data(void *options, | 1783 | static int nfs4_validate_mount_data(void *options, |
@@ -1751,6 +1801,7 @@ static int nfs4_validate_mount_data(void *options, | |||
1751 | args->acregmax = 60; | 1801 | args->acregmax = 60; |
1752 | args->acdirmin = 30; | 1802 | args->acdirmin = 30; |
1753 | args->acdirmax = 60; | 1803 | args->acdirmax = 60; |
1804 | args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ | ||
1754 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1805 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
1755 | 1806 | ||
1756 | switch (data->version) { | 1807 | switch (data->version) { |
@@ -1767,9 +1818,6 @@ static int nfs4_validate_mount_data(void *options, | |||
1767 | &args->nfs_server.address)) | 1818 | &args->nfs_server.address)) |
1768 | goto out_no_address; | 1819 | goto out_no_address; |
1769 | 1820 | ||
1770 | nfs4_default_port((struct sockaddr *) | ||
1771 | &args->nfs_server.address); | ||
1772 | |||
1773 | switch (data->auth_flavourlen) { | 1821 | switch (data->auth_flavourlen) { |
1774 | case 0: | 1822 | case 0: |
1775 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 1823 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
@@ -1827,9 +1875,6 @@ static int nfs4_validate_mount_data(void *options, | |||
1827 | &args->nfs_server.address)) | 1875 | &args->nfs_server.address)) |
1828 | return -EINVAL; | 1876 | return -EINVAL; |
1829 | 1877 | ||
1830 | nfs4_default_port((struct sockaddr *) | ||
1831 | &args->nfs_server.address); | ||
1832 | |||
1833 | switch (args->auth_flavor_len) { | 1878 | switch (args->auth_flavor_len) { |
1834 | case 0: | 1879 | case 0: |
1835 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 1880 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
@@ -1852,12 +1897,16 @@ static int nfs4_validate_mount_data(void *options, | |||
1852 | return -ENAMETOOLONG; | 1897 | return -ENAMETOOLONG; |
1853 | /* N.B. caller will free nfs_server.hostname in all cases */ | 1898 | /* N.B. caller will free nfs_server.hostname in all cases */ |
1854 | args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); | 1899 | args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL); |
1900 | if (!args->nfs_server.hostname) | ||
1901 | goto out_nomem; | ||
1855 | 1902 | ||
1856 | c++; /* step over the ':' */ | 1903 | c++; /* step over the ':' */ |
1857 | len = strlen(c); | 1904 | len = strlen(c); |
1858 | if (len > NFS4_MAXPATHLEN) | 1905 | if (len > NFS4_MAXPATHLEN) |
1859 | return -ENAMETOOLONG; | 1906 | return -ENAMETOOLONG; |
1860 | args->nfs_server.export_path = kstrndup(c, len, GFP_KERNEL); | 1907 | args->nfs_server.export_path = kstrndup(c, len, GFP_KERNEL); |
1908 | if (!args->nfs_server.export_path) | ||
1909 | goto out_nomem; | ||
1861 | 1910 | ||
1862 | dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path); | 1911 | dprintk("NFS: MNTPATH: '%s'\n", args->nfs_server.export_path); |
1863 | 1912 | ||
@@ -1879,6 +1928,10 @@ out_inval_auth: | |||
1879 | data->auth_flavourlen); | 1928 | data->auth_flavourlen); |
1880 | return -EINVAL; | 1929 | return -EINVAL; |
1881 | 1930 | ||
1931 | out_nomem: | ||
1932 | dfprintk(MOUNT, "NFS4: not enough memory to handle mount options\n"); | ||
1933 | return -ENOMEM; | ||
1934 | |||
1882 | out_no_address: | 1935 | out_no_address: |
1883 | dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); | 1936 | dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n"); |
1884 | return -EINVAL; | 1937 | return -EINVAL; |