diff options
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 42f9fb661006..70296fedee41 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -236,6 +236,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) | |||
236 | 236 | ||
237 | bmval[0] = 0; | 237 | bmval[0] = 0; |
238 | bmval[1] = 0; | 238 | bmval[1] = 0; |
239 | bmval[2] = 0; | ||
239 | 240 | ||
240 | READ_BUF(4); | 241 | READ_BUF(4); |
241 | READ32(bmlen); | 242 | READ32(bmlen); |
@@ -247,13 +248,16 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) | |||
247 | READ32(bmval[0]); | 248 | READ32(bmval[0]); |
248 | if (bmlen > 1) | 249 | if (bmlen > 1) |
249 | READ32(bmval[1]); | 250 | READ32(bmval[1]); |
251 | if (bmlen > 2) | ||
252 | READ32(bmval[2]); | ||
250 | 253 | ||
251 | DECODE_TAIL; | 254 | DECODE_TAIL; |
252 | } | 255 | } |
253 | 256 | ||
254 | static u32 nfsd_attrmask[] = { | 257 | static u32 nfsd_attrmask[] = { |
255 | NFSD_WRITEABLE_ATTRS_WORD0, | 258 | NFSD_WRITEABLE_ATTRS_WORD0, |
256 | NFSD_WRITEABLE_ATTRS_WORD1 | 259 | NFSD_WRITEABLE_ATTRS_WORD1, |
260 | NFSD_WRITEABLE_ATTRS_WORD2 | ||
257 | }; | 261 | }; |
258 | 262 | ||
259 | static __be32 | 263 | static __be32 |
@@ -274,9 +278,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable, | |||
274 | * According to spec, unsupported attributes return ERR_ATTRNOTSUPP; | 278 | * According to spec, unsupported attributes return ERR_ATTRNOTSUPP; |
275 | * read-only attributes return ERR_INVAL. | 279 | * read-only attributes return ERR_INVAL. |
276 | */ | 280 | */ |
277 | if ((bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0) || (bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1)) | 281 | if ((bmval[0] & ~nfsd_suppattrs0(argp->minorversion)) || |
282 | (bmval[1] & ~nfsd_suppattrs1(argp->minorversion)) || | ||
283 | (bmval[2] & ~nfsd_suppattrs2(argp->minorversion))) | ||
278 | return nfserr_attrnotsupp; | 284 | return nfserr_attrnotsupp; |
279 | if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1])) | 285 | if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) || |
286 | (bmval[2] & ~writable[2])) | ||
280 | return nfserr_inval; | 287 | return nfserr_inval; |
281 | 288 | ||
282 | READ_BUF(4); | 289 | READ_BUF(4); |
@@ -411,6 +418,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable, | |||
411 | goto xdr_error; | 418 | goto xdr_error; |
412 | } | 419 | } |
413 | } | 420 | } |
421 | BUG_ON(bmval[2]); /* no such writeable attr supported yet */ | ||
414 | if (len != expected_len) | 422 | if (len != expected_len) |
415 | goto xdr_error; | 423 | goto xdr_error; |
416 | 424 | ||
@@ -1726,6 +1734,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1726 | { | 1734 | { |
1727 | u32 bmval0 = bmval[0]; | 1735 | u32 bmval0 = bmval[0]; |
1728 | u32 bmval1 = bmval[1]; | 1736 | u32 bmval1 = bmval[1]; |
1737 | u32 bmval2 = bmval[2]; | ||
1729 | struct kstat stat; | 1738 | struct kstat stat; |
1730 | struct svc_fh tempfh; | 1739 | struct svc_fh tempfh; |
1731 | struct kstatfs statfs; | 1740 | struct kstatfs statfs; |
@@ -1739,12 +1748,16 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1739 | int err; | 1748 | int err; |
1740 | int aclsupport = 0; | 1749 | int aclsupport = 0; |
1741 | struct nfs4_acl *acl = NULL; | 1750 | struct nfs4_acl *acl = NULL; |
1751 | struct nfsd4_compoundres *resp = rqstp->rq_resp; | ||
1752 | u32 minorversion = resp->cstate.minorversion; | ||
1742 | 1753 | ||
1743 | BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); | 1754 | BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1); |
1744 | BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0); | 1755 | BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion)); |
1745 | BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1); | 1756 | BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion)); |
1757 | BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion)); | ||
1746 | 1758 | ||
1747 | if (exp->ex_fslocs.migrated) { | 1759 | if (exp->ex_fslocs.migrated) { |
1760 | BUG_ON(bmval[2]); | ||
1748 | status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err); | 1761 | status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err); |
1749 | if (status) | 1762 | if (status) |
1750 | goto out; | 1763 | goto out; |
@@ -1790,22 +1803,42 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | |||
1790 | if ((buflen -= 16) < 0) | 1803 | if ((buflen -= 16) < 0) |
1791 | goto out_resource; | 1804 | goto out_resource; |
1792 | 1805 | ||
1793 | WRITE32(2); | 1806 | if (unlikely(bmval2)) { |
1794 | WRITE32(bmval0); | 1807 | WRITE32(3); |
1795 | WRITE32(bmval1); | 1808 | WRITE32(bmval0); |
1809 | WRITE32(bmval1); | ||
1810 | WRITE32(bmval2); | ||
1811 | } else if (likely(bmval1)) { | ||
1812 | WRITE32(2); | ||
1813 | WRITE32(bmval0); | ||
1814 | WRITE32(bmval1); | ||
1815 | } else { | ||
1816 | WRITE32(1); | ||
1817 | WRITE32(bmval0); | ||
1818 | } | ||
1796 | attrlenp = p++; /* to be backfilled later */ | 1819 | attrlenp = p++; /* to be backfilled later */ |
1797 | 1820 | ||
1798 | if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { | 1821 | if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) { |
1799 | u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0; | 1822 | u32 word0 = nfsd_suppattrs0(minorversion); |
1823 | u32 word1 = nfsd_suppattrs1(minorversion); | ||
1824 | u32 word2 = nfsd_suppattrs2(minorversion); | ||
1825 | |||
1800 | if ((buflen -= 12) < 0) | 1826 | if ((buflen -= 12) < 0) |
1801 | goto out_resource; | 1827 | goto out_resource; |
1802 | if (!aclsupport) | 1828 | if (!aclsupport) |
1803 | word0 &= ~FATTR4_WORD0_ACL; | 1829 | word0 &= ~FATTR4_WORD0_ACL; |
1804 | if (!exp->ex_fslocs.locations) | 1830 | if (!exp->ex_fslocs.locations) |
1805 | word0 &= ~FATTR4_WORD0_FS_LOCATIONS; | 1831 | word0 &= ~FATTR4_WORD0_FS_LOCATIONS; |
1806 | WRITE32(2); | 1832 | if (!word2) { |
1807 | WRITE32(word0); | 1833 | WRITE32(2); |
1808 | WRITE32(NFSD_SUPPORTED_ATTRS_WORD1); | 1834 | WRITE32(word0); |
1835 | WRITE32(word1); | ||
1836 | } else { | ||
1837 | WRITE32(3); | ||
1838 | WRITE32(word0); | ||
1839 | WRITE32(word1); | ||
1840 | WRITE32(word2); | ||
1841 | } | ||
1809 | } | 1842 | } |
1810 | if (bmval0 & FATTR4_WORD0_TYPE) { | 1843 | if (bmval0 & FATTR4_WORD0_TYPE) { |
1811 | if ((buflen -= 4) < 0) | 1844 | if ((buflen -= 4) < 0) |
@@ -2115,6 +2148,8 @@ out_acl: | |||
2115 | } | 2148 | } |
2116 | WRITE64(stat.ino); | 2149 | WRITE64(stat.ino); |
2117 | } | 2150 | } |
2151 | BUG_ON(bmval2); /* FIXME: not implemented yet */ | ||
2152 | |||
2118 | *attrlenp = htonl((char *)p - (char *)attrlenp - 4); | 2153 | *attrlenp = htonl((char *)p - (char *)attrlenp - 4); |
2119 | *countp = p - buffer; | 2154 | *countp = p - buffer; |
2120 | status = nfs_ok; | 2155 | status = nfs_ok; |