2008-06-18 22:36:09

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH 2/4] NFS: Support raw IPv6 address hostnames during NFS mount operation

Chuck Lever wrote:
> Traditionally the mount command has looked for a ":" to separate the
> server's hostname from the export path in the mounted on device name,
> like this:
>
> mount server:/export /mounted/on/dir
>
> The server's hostname is "server" and the export path is "/export".
>
> You can also substitute a specific IPv4 network address for the server
> hostname, like this:
>
> mount 192.168.0.55:/export /mounted/on/dir
>
> Raw IPv6 addresses present a problem, however, because they look
> something like this:
>
> fe80::200:5aff:fe00:30b
>
> Note the use of colons.
>
> To get around the presence of colons, copy the Solaris convention used for
> mounting IPv6 servers by address: wrap a raw IPv6 address with square
> brackets.
>
>

It seems unfortunate that the convention couldn't have been to
look for the first instance of ":/" and break the strings there.

ps

> Signed-off-by: Chuck Lever <[email protected]>
> ---
>
> fs/nfs/super.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 files changed, 82 insertions(+), 8 deletions(-)
>
>
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index 5e0eefa..98c8110 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -1215,14 +1215,9 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
> return status;
> }
>
> -/*
> - * Split "dev_name" into "hostname:export_path".
> - *
> - * Note: caller frees hostname and export path, even on error.
> - */
> -static int nfs_parse_devname(const char *dev_name,
> - char **hostname, size_t maxnamlen,
> - char **export_path, size_t maxpathlen)
> +static int nfs_parse_simple_hostname(const char *dev_name,
> + char **hostname, size_t maxnamlen,
> + char **export_path, size_t maxpathlen)
> {
> size_t len;
> char *colon, *comma;
> @@ -1277,6 +1272,85 @@ out_path:
> }
>
> /*
> + * Hostname has square brackets around it because it contains one or
> + * more colons. We look for the first closing square bracket, and a
> + * colon must follow it.
> + */
> +static int nfs_parse_protected_hostname(const char *dev_name,
> + char **hostname, size_t maxnamlen,
> + char **export_path, size_t maxpathlen)
> +{
> + size_t len;
> + char *start, *end;
> +
> + start = (char *)(dev_name + 1);
> +
> + end = strchr(start, ']');
> + if (end == NULL)
> + goto out_bad_devname;
> + if (*(end + 1) != ':')
> + goto out_bad_devname;
> +
> + len = end - start;
> + if (len > maxnamlen)
> + goto out_hostname;
> +
> + /* N.B. caller will free nfs_server.hostname in all cases */
> + *hostname = kstrndup(start, len, GFP_KERNEL);
> + if (*hostname == NULL)
> + goto out_nomem;
> +
> + end += 2;
> + len = strlen(end);
> + if (len > maxpathlen)
> + goto out_path;
> + *export_path = kstrndup(end, len, GFP_KERNEL);
> + if (!*export_path)
> + goto out_nomem;
> +
> + return 0;
> +
> +out_bad_devname:
> + dfprintk(MOUNT, "NFS: device name not in host:path format\n");
> + return -EINVAL;
> +
> +out_nomem:
> + dfprintk(MOUNT, "NFS: not enough memory to parse device name\n");
> + return -ENOMEM;
> +
> +out_hostname:
> + dfprintk(MOUNT, "NFS: server hostname too long\n");
> + return -ENAMETOOLONG;
> +
> +out_path:
> + dfprintk(MOUNT, "NFS: export pathname too long\n");
> + return -ENAMETOOLONG;
> +}
> +
> +/*
> + * Split "dev_name" into "hostname:export_path".
> + *
> + * The leftmost colon demarks the split between the server's hostname
> + * and the export path. If the hostname starts with a left square
> + * bracket, then it may contain colons.
> + *
> + * Note: caller frees hostname and export path, even on error.
> + */
> +static int nfs_parse_devname(const char *dev_name,
> + char **hostname, size_t maxnamlen,
> + char **export_path, size_t maxpathlen)
> +{
> + if (*dev_name == '[')
> + return nfs_parse_protected_hostname(dev_name,
> + hostname, maxnamlen,
> + export_path, maxpathlen);
> +
> + return nfs_parse_simple_hostname(dev_name,
> + hostname, maxnamlen,
> + export_path, maxpathlen);
> +}
> +
> +/*
> * Validate the NFS2/NFS3 mount data
> * - fills in the mount root filehandle
> *
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>



2008-06-18 22:43:15

by Chuck Lever

[permalink] [raw]
Subject: Re: [PATCH 2/4] NFS: Support raw IPv6 address hostnames during NFS mount operation

Peter Staubach wrote:
> Chuck Lever wrote:
>> Traditionally the mount command has looked for a ":" to separate the
>> server's hostname from the export path in the mounted on device name,
>> like this:
>>
>> mount server:/export /mounted/on/dir
>>
>> The server's hostname is "server" and the export path is "/export".
>>
>> You can also substitute a specific IPv4 network address for the server
>> hostname, like this:
>>
>> mount 192.168.0.55:/export /mounted/on/dir
>>
>> Raw IPv6 addresses present a problem, however, because they look
>> something like this:
>>
>> fe80::200:5aff:fe00:30b
>>
>> Note the use of colons.
>>
>> To get around the presence of colons, copy the Solaris convention used
>> for
>> mounting IPv6 servers by address: wrap a raw IPv6 address with square
>> brackets.
>>
>>
>
> It seems unfortunate that the convention couldn't have been to
> look for the first instance of ":/" and break the strings there.

I wonder if you can ever specify an export path that does not begin with
a '/' -- is that possible when mounting an NFS server that exports, say,
an old-fashioned HFS volume?

"macintosh::Macintosh HD:Users:cel"

Looking for only the first colon gives the correct results in this case,
but looking for ":/" would not.

Likewise on FAT32:

"windows:\Documents and Settings\Chuck Lever\My Documents"


Attachments:
chuck_lever.vcf (259.00 B)

2008-06-18 22:52:08

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH 2/4] NFS: Support raw IPv6 address hostnames during NFS mount operation

On Wed, 2008-06-18 at 18:42 -0400, Chuck Lever wrote:
> Peter Staubach wrote:
> > It seems unfortunate that the convention couldn't have been to
> > look for the first instance of ":/" and break the strings there.
>
> I wonder if you can ever specify an export path that does not begin with
> a '/' -- is that possible when mounting an NFS server that exports, say,
> an old-fashioned HFS volume?

It is quite legal to specify a path that doesn't start with '/':
NFSv2/v3 mount servers will, for instance, just implicitly assume it.
For that reason, there were user complaints the last time we started
requiring the '/' and returning an error when it wasn't supplied.

--
Trond Myklebust
Linux NFS client maintainer

NetApp
[email protected]
http://www.netapp.com

2008-06-18 23:00:18

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH 2/4] NFS: Support raw IPv6 address hostnames during NFS mount operation

Trond Myklebust wrote:
> On Wed, 2008-06-18 at 18:42 -0400, Chuck Lever wrote:
>
>> Peter Staubach wrote:
>>
>>> It seems unfortunate that the convention couldn't have been to
>>> look for the first instance of ":/" and break the strings there.
>>>
>> I wonder if you can ever specify an export path that does not begin with
>> a '/' -- is that possible when mounting an NFS server that exports, say,
>> an old-fashioned HFS volume?
>>
>
> It is quite legal to specify a path that doesn't start with '/':
> NFSv2/v3 mount servers will, for instance, just implicitly assume it.
> For that reason, there were user complaints the last time we started
> requiring the '/' and returning an error when it wasn't supplied.

And, hence, the [] syntax... :-)

ps