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.c59
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
254static u32 nfsd_attrmask[] = { 257static 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
259static __be32 263static __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;