aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c62
1 files changed, 44 insertions, 18 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 74c00bc92b9a..4949667c84ea 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1674,12 +1674,12 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1674 1674
1675static void write32(__be32 **p, u32 n) 1675static void write32(__be32 **p, u32 n)
1676{ 1676{
1677 *(*p)++ = n; 1677 *(*p)++ = htonl(n);
1678} 1678}
1679 1679
1680static void write64(__be32 **p, u64 n) 1680static void write64(__be32 **p, u64 n)
1681{ 1681{
1682 write32(p, (u32)(n >> 32)); 1682 write32(p, (n >> 32));
1683 write32(p, (u32)n); 1683 write32(p, (u32)n);
1684} 1684}
1685 1685
@@ -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);
@@ -3251,7 +3277,7 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
3251} 3277}
3252 3278
3253static __be32 3279static __be32
3254nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr, 3280nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
3255 struct nfsd4_exchange_id *exid) 3281 struct nfsd4_exchange_id *exid)
3256{ 3282{
3257 __be32 *p; 3283 __be32 *p;
@@ -3306,7 +3332,7 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
3306} 3332}
3307 3333
3308static __be32 3334static __be32
3309nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr, 3335nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3310 struct nfsd4_create_session *sess) 3336 struct nfsd4_create_session *sess)
3311{ 3337{
3312 __be32 *p; 3338 __be32 *p;
@@ -3355,14 +3381,14 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
3355} 3381}
3356 3382
3357static __be32 3383static __be32
3358nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr, 3384nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, __be32 nfserr,
3359 struct nfsd4_destroy_session *destroy_session) 3385 struct nfsd4_destroy_session *destroy_session)
3360{ 3386{
3361 return nfserr; 3387 return nfserr;
3362} 3388}
3363 3389
3364static __be32 3390static __be32
3365nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr, 3391nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3366 struct nfsd4_free_stateid *free_stateid) 3392 struct nfsd4_free_stateid *free_stateid)
3367{ 3393{
3368 __be32 *p; 3394 __be32 *p;
@@ -3371,13 +3397,13 @@ nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr,
3371 return nfserr; 3397 return nfserr;
3372 3398
3373 RESERVE_SPACE(4); 3399 RESERVE_SPACE(4);
3374 WRITE32(nfserr); 3400 *p++ = nfserr;
3375 ADJUST_ARGS(); 3401 ADJUST_ARGS();
3376 return nfserr; 3402 return nfserr;
3377} 3403}
3378 3404
3379static __be32 3405static __be32
3380nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr, 3406nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
3381 struct nfsd4_sequence *seq) 3407 struct nfsd4_sequence *seq)
3382{ 3408{
3383 __be32 *p; 3409 __be32 *p;
@@ -3399,8 +3425,8 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3399 return 0; 3425 return 0;
3400} 3426}
3401 3427
3402__be32 3428static __be32
3403nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, 3429nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
3404 struct nfsd4_test_stateid *test_stateid) 3430 struct nfsd4_test_stateid *test_stateid)
3405{ 3431{
3406 struct nfsd4_test_stateid_id *stateid, *next; 3432 struct nfsd4_test_stateid_id *stateid, *next;
@@ -3503,7 +3529,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
3503 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so 3529 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3504 * will be at least a page and will therefore hold the xdr_buf head. 3530 * will be at least a page and will therefore hold the xdr_buf head.
3505 */ 3531 */
3506int nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad) 3532__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
3507{ 3533{
3508 struct xdr_buf *xb = &resp->rqstp->rq_res; 3534 struct xdr_buf *xb = &resp->rqstp->rq_res;
3509 struct nfsd4_session *session = NULL; 3535 struct nfsd4_session *session = NULL;