From 96728f8567ed91f8bfe9cb37222ac94edee97eb4 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 20 Aug 2008 16:10:23 -0400 Subject: [PATCH] --- yaml --- r: 115396 b: refs/heads/master c: ea31a4437c59219bf3ea946d58984b01a45a289c h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/nfs/internal.h | 2 ++ trunk/fs/nfs/nfs4namespace.c | 44 +++++++++++++++--------------------- trunk/fs/nfs/super.c | 4 +--- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/[refs] b/[refs] index e59c6ea1b6a8..d179d75015a0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f0c929251e01a7a86b6254c775cb6b65c6457f10 +refs/heads/master: ea31a4437c59219bf3ea946d58984b01a45a289c diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index 8d91bd88e310..5d2a5d3c4241 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -153,6 +153,7 @@ extern void nfs4_clear_inode(struct inode *); void nfs_zap_acl_cache(struct inode *inode); /* super.c */ +void nfs_parse_ip_address(char *, size_t, struct sockaddr *, size_t *); extern struct file_system_type nfs_xdev_fs_type; #ifdef CONFIG_NFS_V4 extern struct file_system_type nfs4_xdev_fs_type; @@ -276,6 +277,7 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len) PAGE_SIZE - 1) >> PAGE_SHIFT; } +#define IPV6_SCOPE_DELIMITER '%' /* * Set the port number in an address. Be agnostic about the address diff --git a/trunk/fs/nfs/nfs4namespace.c b/trunk/fs/nfs/nfs4namespace.c index 6bcc5696f911..30befc39b3c6 100644 --- a/trunk/fs/nfs/nfs4namespace.c +++ b/trunk/fs/nfs/nfs4namespace.c @@ -93,50 +93,42 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent, return 0; } -/* - * Check if the string represents a "valid" IPv4 address - */ -static inline int valid_ipaddr4(const char *buf) -{ - int rc, count, in[4]; - - rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]); - if (rc != 4) - return -EINVAL; - for (count = 0; count < 4; count++) { - if (in[count] > 255) - return -EINVAL; - } - return 0; -} - static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, char *page, char *page2, const struct nfs4_fs_location *location) { struct vfsmount *mnt = ERR_PTR(-ENOENT); char *mnt_path; + int page2len; unsigned int s; mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); if (IS_ERR(mnt_path)) return mnt; mountdata->mnt_path = mnt_path; + page2 += strlen(mnt_path) + 1; + page2len = PAGE_SIZE - strlen(mnt_path) - 1; for (s = 0; s < location->nservers; s++) { - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = htons(NFS_PORT), - }; + const struct nfs4_string *buf = &location->servers[s]; + struct sockaddr_storage addr; - if (location->servers[s].len <= 0 || - valid_ipaddr4(location->servers[s].data) < 0) + if (buf->len <= 0 || buf->len >= PAGE_SIZE) continue; - mountdata->hostname = location->servers[s].data; - addr.sin_addr.s_addr = in_aton(mountdata->hostname), mountdata->addr = (struct sockaddr *)&addr; - mountdata->addrlen = sizeof(addr); + + if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len)) + continue; + nfs_parse_ip_address(buf->data, buf->len, + mountdata->addr, &mountdata->addrlen); + if (mountdata->addr->sa_family == AF_UNSPEC) + continue; + nfs_set_port(mountdata->addr, NFS_PORT); + + strncpy(page2, buf->data, page2len); + page2[page2len] = '\0'; + mountdata->hostname = page2; snprintf(page, PAGE_SIZE, "%s:%s", mountdata->hostname, diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index b99096b8e827..20dc4ccdff56 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -716,8 +716,6 @@ static void nfs_parse_ipv4_address(char *string, size_t str_len, *addr_len = 0; } -#define IPV6_SCOPE_DELIMITER '%' - #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len, const char *delim, @@ -790,7 +788,7 @@ static void nfs_parse_ipv6_address(char *string, size_t str_len, * If there is a problem constructing the new sockaddr, set the address * family to AF_UNSPEC. */ -static void nfs_parse_ip_address(char *string, size_t str_len, +void nfs_parse_ip_address(char *string, size_t str_len, struct sockaddr *sap, size_t *addr_len) { unsigned int i, colons;