diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-03 01:29:11 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-03 20:41:23 -0400 |
commit | 7e70570647827345352cf6c17461c9fa166f570a (patch) | |
tree | a200662bb68cd9a1396c365a47b50e46f0ea9f73 /fs | |
parent | 95ec28cda323104bbff64fc7ec8ee4c9042e51fa (diff) |
nfsd41: support for 3-word long attribute bitmask
Also, use client minorversion to generate supported attrs
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 15 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 59 |
2 files changed, 56 insertions, 18 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 937853f62834..e206053433e3 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -463,8 +463,9 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
463 | if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) | 463 | if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) |
464 | return nfserr_inval; | 464 | return nfserr_inval; |
465 | 465 | ||
466 | getattr->ga_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; | 466 | getattr->ga_bmval[0] &= nfsd_suppattrs0(cstate->minorversion); |
467 | getattr->ga_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; | 467 | getattr->ga_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); |
468 | getattr->ga_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); | ||
468 | 469 | ||
469 | getattr->ga_fhp = &cstate->current_fh; | 470 | getattr->ga_fhp = &cstate->current_fh; |
470 | return nfs_ok; | 471 | return nfs_ok; |
@@ -555,8 +556,9 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
555 | if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) | 556 | if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) |
556 | return nfserr_inval; | 557 | return nfserr_inval; |
557 | 558 | ||
558 | readdir->rd_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; | 559 | readdir->rd_bmval[0] &= nfsd_suppattrs0(cstate->minorversion); |
559 | readdir->rd_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; | 560 | readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion); |
561 | readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion); | ||
560 | 562 | ||
561 | if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) || | 563 | if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) || |
562 | (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) | 564 | (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) |
@@ -746,8 +748,9 @@ _nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
746 | if (status) | 748 | if (status) |
747 | return status; | 749 | return status; |
748 | 750 | ||
749 | if ((verify->ve_bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0) | 751 | if ((verify->ve_bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) |
750 | || (verify->ve_bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1)) | 752 | || (verify->ve_bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) |
753 | || (verify->ve_bmval[2] & ~nfsd_suppattrs2(cstate->minorversion))) | ||
751 | return nfserr_attrnotsupp; | 754 | return nfserr_attrnotsupp; |
752 | if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR) | 755 | if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR) |
753 | || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)) | 756 | || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)) |
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; |