summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2012-04-25 00:50:37 +0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-04-26 20:11:29 +0400
commit1aba1567637b93eee32253b42deaaad381c3175b (patch)
treea1bc797ef749f93d39a2112022fefcb29bfa68f0
parent2300fd67b4f29eec19addb15a8571837228f63fc (diff)
downloadlinux-1aba1567637b93eee32253b42deaaad381c3175b.tar.xz
nfs4: fix referrals on mounts that use IPv6 addrs
All referrals (IPv4 addr, IPv6 addr, and DNS) are broken on mounts of IPv6 addresses, because validation code uses a path that is parsed from the dev_name ("<server>:<path>") by splitting on the first colon and colons are used in IPv6 addrs. This patch ignores colons within IPv6 addresses that are escaped by '[' and ']'. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/nfs4namespace.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 9c8eca315f43..7483a177dc97 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -52,6 +52,30 @@ Elong:
}
/*
+ * return the path component of "<server>:<path>"
+ * nfspath - the "<server>:<path>" string
+ * end - one past the last char that could contain "<server>:"
+ * returns NULL on failure
+ */
+static char *nfs_path_component(const char *nfspath, const char *end)
+{
+ char *p;
+
+ if (*nfspath == '[') {
+ /* parse [] escaped IPv6 addrs */
+ p = strchr(nfspath, ']');
+ if (p != NULL && ++p < end && *p == ':')
+ return p + 1;
+ } else {
+ /* otherwise split on first colon */
+ p = strchr(nfspath, ':');
+ if (p != NULL && p < end)
+ return p + 1;
+ }
+ return NULL;
+}
+
+/*
* Determine the mount path as a string
*/
static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
@@ -59,9 +83,9 @@ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
char *limit;
char *path = nfs_path(&limit, dentry, buffer, buflen);
if (!IS_ERR(path)) {
- char *colon = strchr(path, ':');
- if (colon && colon < limit)
- path = colon + 1;
+ char *path_component = nfs_path_component(path, limit);
+ if (path_component)
+ return path_component;
}
return path;
}