aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-09-08 19:49:47 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-09-08 19:49:47 -0400
commit4cfd74fc99a41fdc161f243e1c16199656d33ab1 (patch)
treeb92cb5a87dfeb13cc042768351ffda6a64d58713 /fs
parentdbab8360ed8abca38121109feab47c4bea895994 (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.h9
-rw-r--r--fs/nfs/super.c55
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 */
54struct nfs_parsed_mount_data { 59struct 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 */
753static 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