diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2009-09-08 19:49:47 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-09-08 19:49:47 -0400 |
commit | 4cfd74fc99a41fdc161f243e1c16199656d33ab1 (patch) | |
tree | b92cb5a87dfeb13cc042768351ffda6a64d58713 /fs | |
parent | dbab8360ed8abca38121109feab47c4bea895994 (diff) |
NFS: Mount option parser should detect missing "port="
The meaning of not specifying the "port=" mount option is different
for "-t nfs" and "-t nfs4" mounts. The default port value for
NFSv2/v3 mounts is 0, but the default for NFSv4 mounts is 2049.
To support "-t nfs -o vers=4", the mount option parser must detect
when "port=" is missing so that the correct default port value can be
set depending on which NFS version is requested.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/internal.h | 9 | ||||
-rw-r--r-- | fs/nfs/super.c | 55 |
2 files changed, 36 insertions, 28 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 2e485677019c..5e686a4d744e 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -49,6 +49,11 @@ struct nfs_clone_mount { | |||
49 | #define NFS_MAX_SECFLAVORS (12) | 49 | #define NFS_MAX_SECFLAVORS (12) |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Value used if the user did not specify a port value. | ||
53 | */ | ||
54 | #define NFS_UNSPEC_PORT (-1) | ||
55 | |||
56 | /* | ||
52 | * In-kernel mount arguments | 57 | * In-kernel mount arguments |
53 | */ | 58 | */ |
54 | struct nfs_parsed_mount_data { | 59 | struct nfs_parsed_mount_data { |
@@ -71,7 +76,7 @@ struct nfs_parsed_mount_data { | |||
71 | size_t addrlen; | 76 | size_t addrlen; |
72 | char *hostname; | 77 | char *hostname; |
73 | u32 version; | 78 | u32 version; |
74 | unsigned short port; | 79 | int port; |
75 | unsigned short protocol; | 80 | unsigned short protocol; |
76 | } mount_server; | 81 | } mount_server; |
77 | 82 | ||
@@ -80,7 +85,7 @@ struct nfs_parsed_mount_data { | |||
80 | size_t addrlen; | 85 | size_t addrlen; |
81 | char *hostname; | 86 | char *hostname; |
82 | char *export_path; | 87 | char *export_path; |
83 | unsigned short port; | 88 | int port; |
84 | unsigned short protocol; | 89 | unsigned short protocol; |
85 | } nfs_server; | 90 | } nfs_server; |
86 | 91 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f3a95df4b95f..05544336f7de 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -747,6 +747,21 @@ static int nfs_verify_server_address(struct sockaddr *addr) | |||
747 | } | 747 | } |
748 | 748 | ||
749 | /* | 749 | /* |
750 | * Select between a default port value and a user-specified port value. | ||
751 | * If a zero value is set, then autobind will be used. | ||
752 | */ | ||
753 | static void nfs_set_default_port(struct sockaddr *sap, const int parsed_port, | ||
754 | const unsigned short default_port) | ||
755 | { | ||
756 | unsigned short port = default_port; | ||
757 | |||
758 | if (parsed_port != NFS_UNSPEC_PORT) | ||
759 | port = parsed_port; | ||
760 | |||
761 | rpc_set_port(sap, port); | ||
762 | } | ||
763 | |||
764 | /* | ||
750 | * Sanity check the NFS transport protocol. | 765 | * Sanity check the NFS transport protocol. |
751 | * | 766 | * |
752 | */ | 767 | */ |
@@ -1415,11 +1430,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args, | |||
1415 | args->mount_server.addrlen = args->nfs_server.addrlen; | 1430 | args->mount_server.addrlen = args->nfs_server.addrlen; |
1416 | } | 1431 | } |
1417 | request.salen = args->mount_server.addrlen; | 1432 | request.salen = args->mount_server.addrlen; |
1418 | 1433 | nfs_set_default_port(request.sap, args->mount_server.port, 0); | |
1419 | /* | ||
1420 | * autobind will be used if mount_server.port == 0 | ||
1421 | */ | ||
1422 | rpc_set_port(request.sap, args->mount_server.port); | ||
1423 | 1434 | ||
1424 | /* | 1435 | /* |
1425 | * Now ask the mount server to map our export path | 1436 | * Now ask the mount server to map our export path |
@@ -1597,6 +1608,7 @@ static int nfs_validate_mount_data(void *options, | |||
1597 | const char *dev_name) | 1608 | const char *dev_name) |
1598 | { | 1609 | { |
1599 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; | 1610 | struct nfs_mount_data *data = (struct nfs_mount_data *)options; |
1611 | struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; | ||
1600 | 1612 | ||
1601 | if (data == NULL) | 1613 | if (data == NULL) |
1602 | goto out_no_data; | 1614 | goto out_no_data; |
@@ -1608,8 +1620,8 @@ static int nfs_validate_mount_data(void *options, | |||
1608 | args->acregmax = NFS_DEF_ACREGMAX; | 1620 | args->acregmax = NFS_DEF_ACREGMAX; |
1609 | args->acdirmin = NFS_DEF_ACDIRMIN; | 1621 | args->acdirmin = NFS_DEF_ACDIRMIN; |
1610 | args->acdirmax = NFS_DEF_ACDIRMAX; | 1622 | args->acdirmax = NFS_DEF_ACDIRMAX; |
1611 | args->mount_server.port = 0; /* autobind unless user sets port */ | 1623 | args->mount_server.port = NFS_UNSPEC_PORT; |
1612 | args->nfs_server.port = 0; /* autobind unless user sets port */ | 1624 | args->nfs_server.port = NFS_UNSPEC_PORT; |
1613 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; | 1625 | args->nfs_server.protocol = XPRT_TRANSPORT_TCP; |
1614 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 1626 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
1615 | args->auth_flavor_len = 1; | 1627 | args->auth_flavor_len = 1; |
@@ -1657,11 +1669,9 @@ static int nfs_validate_mount_data(void *options, | |||
1657 | args->acdirmin = data->acdirmin; | 1669 | args->acdirmin = data->acdirmin; |
1658 | args->acdirmax = data->acdirmax; | 1670 | args->acdirmax = data->acdirmax; |
1659 | 1671 | ||
1660 | memcpy(&args->nfs_server.address, &data->addr, | 1672 | memcpy(sap, &data->addr, sizeof(data->addr)); |
1661 | sizeof(data->addr)); | ||
1662 | args->nfs_server.addrlen = sizeof(data->addr); | 1673 | args->nfs_server.addrlen = sizeof(data->addr); |
1663 | if (!nfs_verify_server_address((struct sockaddr *) | 1674 | if (!nfs_verify_server_address(sap)) |
1664 | &args->nfs_server.address)) | ||
1665 | goto out_no_address; | 1675 | goto out_no_address; |
1666 | 1676 | ||
1667 | if (!(data->flags & NFS_MOUNT_TCP)) | 1677 | if (!(data->flags & NFS_MOUNT_TCP)) |
@@ -1709,12 +1719,10 @@ static int nfs_validate_mount_data(void *options, | |||
1709 | if (nfs_parse_mount_options((char *)options, args) == 0) | 1719 | if (nfs_parse_mount_options((char *)options, args) == 0) |
1710 | return -EINVAL; | 1720 | return -EINVAL; |
1711 | 1721 | ||
1712 | if (!nfs_verify_server_address((struct sockaddr *) | 1722 | if (!nfs_verify_server_address(sap)) |
1713 | &args->nfs_server.address)) | ||
1714 | goto out_no_address; | 1723 | goto out_no_address; |
1715 | 1724 | ||
1716 | rpc_set_port((struct sockaddr *)&args->nfs_server.address, | 1725 | nfs_set_default_port(sap, args->nfs_server.port, 0); |
1717 | args->nfs_server.port); | ||
1718 | 1726 | ||
1719 | nfs_set_mount_transport_protocol(args); | 1727 | nfs_set_mount_transport_protocol(args); |
1720 | 1728 | ||
@@ -2261,7 +2269,7 @@ static int nfs4_validate_mount_data(void *options, | |||
2261 | struct nfs_parsed_mount_data *args, | 2269 | struct nfs_parsed_mount_data *args, |
2262 | const char *dev_name) | 2270 | const char *dev_name) |
2263 | { | 2271 | { |
2264 | struct sockaddr_in *ap; | 2272 | struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; |
2265 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; | 2273 | struct nfs4_mount_data *data = (struct nfs4_mount_data *)options; |
2266 | char *c; | 2274 | char *c; |
2267 | 2275 | ||
@@ -2274,23 +2282,21 @@ static int nfs4_validate_mount_data(void *options, | |||
2274 | args->acregmax = NFS_DEF_ACREGMAX; | 2282 | args->acregmax = NFS_DEF_ACREGMAX; |
2275 | args->acdirmin = NFS_DEF_ACDIRMIN; | 2283 | args->acdirmin = NFS_DEF_ACDIRMIN; |
2276 | args->acdirmax = NFS_DEF_ACDIRMAX; | 2284 | args->acdirmax = NFS_DEF_ACDIRMAX; |
2277 | args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */ | 2285 | args->nfs_server.port = NFS_UNSPEC_PORT; |
2278 | args->auth_flavors[0] = RPC_AUTH_UNIX; | 2286 | args->auth_flavors[0] = RPC_AUTH_UNIX; |
2279 | args->auth_flavor_len = 1; | 2287 | args->auth_flavor_len = 1; |
2280 | args->minorversion = 0; | 2288 | args->minorversion = 0; |
2281 | 2289 | ||
2282 | switch (data->version) { | 2290 | switch (data->version) { |
2283 | case 1: | 2291 | case 1: |
2284 | ap = (struct sockaddr_in *)&args->nfs_server.address; | ||
2285 | if (data->host_addrlen > sizeof(args->nfs_server.address)) | 2292 | if (data->host_addrlen > sizeof(args->nfs_server.address)) |
2286 | goto out_no_address; | 2293 | goto out_no_address; |
2287 | if (data->host_addrlen == 0) | 2294 | if (data->host_addrlen == 0) |
2288 | goto out_no_address; | 2295 | goto out_no_address; |
2289 | args->nfs_server.addrlen = data->host_addrlen; | 2296 | args->nfs_server.addrlen = data->host_addrlen; |
2290 | if (copy_from_user(ap, data->host_addr, data->host_addrlen)) | 2297 | if (copy_from_user(sap, data->host_addr, data->host_addrlen)) |
2291 | return -EFAULT; | 2298 | return -EFAULT; |
2292 | if (!nfs_verify_server_address((struct sockaddr *) | 2299 | if (!nfs_verify_server_address(sap)) |
2293 | &args->nfs_server.address)) | ||
2294 | goto out_no_address; | 2300 | goto out_no_address; |
2295 | 2301 | ||
2296 | if (data->auth_flavourlen) { | 2302 | if (data->auth_flavourlen) { |
@@ -2342,12 +2348,9 @@ static int nfs4_validate_mount_data(void *options, | |||
2342 | if (nfs_parse_mount_options((char *)options, args) == 0) | 2348 | if (nfs_parse_mount_options((char *)options, args) == 0) |
2343 | return -EINVAL; | 2349 | return -EINVAL; |
2344 | 2350 | ||
2345 | if (!nfs_verify_server_address((struct sockaddr *) | 2351 | if (!nfs_verify_server_address(sap)) |
2346 | &args->nfs_server.address)) | ||
2347 | return -EINVAL; | 2352 | return -EINVAL; |
2348 | 2353 | nfs_set_default_port(sap, args->nfs_server.port, NFS_PORT); | |
2349 | rpc_set_port((struct sockaddr *)&args->nfs_server.address, | ||
2350 | args->nfs_server.port); | ||
2351 | 2354 | ||
2352 | nfs_validate_transport_protocol(args); | 2355 | nfs_validate_transport_protocol(args); |
2353 | 2356 | ||