aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2012-04-24 11:07:59 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-05-31 20:29:38 -0400
commite7a0444aef4a1649bc155fd5c6d6ab3f8bdc88ab (patch)
treee3afdeb61ecb045dd95c371f4d6cc89246d0663b /fs/nfsd/nfs4xdr.c
parent45eaa1c1a16122a98bf995c004c23806759d2e5f (diff)
nfsd: add IPv6 addr escaping to fs_location hosts
The fs_location->hosts list is split on colons, but this doesn't work when IPv6 addresses are used (they contain colons). This patch adds the function nfsd4_encode_components_esc() to allow the caller to specify escape characters when splitting on 'sep'. In order to fix referrals, this patch must be used with the mountd patch that similarly fixes IPv6 [] escaping. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 61555e756410..30817e9f1bb7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1744,15 +1744,16 @@ static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, _
1744} 1744}
1745 1745
1746/* Encode as an array of strings the string given with components 1746/* Encode as an array of strings the string given with components
1747 * separated @sep. 1747 * separated @sep, escaped with esc_enter and esc_exit.
1748 */ 1748 */
1749static __be32 nfsd4_encode_components(char sep, char *components, 1749static __be32 nfsd4_encode_components_esc(char sep, char *components,
1750 __be32 **pp, int *buflen) 1750 __be32 **pp, int *buflen,
1751 char esc_enter, char esc_exit)
1751{ 1752{
1752 __be32 *p = *pp; 1753 __be32 *p = *pp;
1753 __be32 *countp = p; 1754 __be32 *countp = p;
1754 int strlen, count=0; 1755 int strlen, count=0;
1755 char *str, *end; 1756 char *str, *end, *next;
1756 1757
1757 dprintk("nfsd4_encode_components(%s)\n", components); 1758 dprintk("nfsd4_encode_components(%s)\n", components);
1758 if ((*buflen -= 4) < 0) 1759 if ((*buflen -= 4) < 0)
@@ -1760,8 +1761,23 @@ static __be32 nfsd4_encode_components(char sep, char *components,
1760 WRITE32(0); /* We will fill this in with @count later */ 1761 WRITE32(0); /* We will fill this in with @count later */
1761 end = str = components; 1762 end = str = components;
1762 while (*end) { 1763 while (*end) {
1763 for (; *end && (*end != sep); end++) 1764 bool found_esc = false;
1764 ; /* Point to end of component */ 1765
1766 /* try to parse as esc_start, ..., esc_end, sep */
1767 if (*str == esc_enter) {
1768 for (; *end && (*end != esc_exit); end++)
1769 /* find esc_exit or end of string */;
1770 next = end + 1;
1771 if (*end && (!*next || *next == sep)) {
1772 str++;
1773 found_esc = true;
1774 }
1775 }
1776
1777 if (!found_esc)
1778 for (; *end && (*end != sep); end++)
1779 /* find sep or end of string */;
1780
1765 strlen = end - str; 1781 strlen = end - str;
1766 if (strlen) { 1782 if (strlen) {
1767 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0) 1783 if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
@@ -1780,6 +1796,15 @@ static __be32 nfsd4_encode_components(char sep, char *components,
1780 return 0; 1796 return 0;
1781} 1797}
1782 1798
1799/* Encode as an array of strings the string given with components
1800 * separated @sep.
1801 */
1802static __be32 nfsd4_encode_components(char sep, char *components,
1803 __be32 **pp, int *buflen)
1804{
1805 return nfsd4_encode_components_esc(sep, components, pp, buflen, 0, 0);
1806}
1807
1783/* 1808/*
1784 * encode a location element of a fs_locations structure 1809 * encode a location element of a fs_locations structure
1785 */ 1810 */
@@ -1789,7 +1814,8 @@ static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1789 __be32 status; 1814 __be32 status;
1790 __be32 *p = *pp; 1815 __be32 *p = *pp;
1791 1816
1792 status = nfsd4_encode_components(':', location->hosts, &p, buflen); 1817 status = nfsd4_encode_components_esc(':', location->hosts, &p, buflen,
1818 '[', ']');
1793 if (status) 1819 if (status)
1794 return status; 1820 return status;
1795 status = nfsd4_encode_components('/', location->path, &p, buflen); 1821 status = nfsd4_encode_components('/', location->path, &p, buflen);