|
@@ -236,6 +236,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
|
|
|
|
|
|
bmval[0] = 0;
|
|
|
bmval[1] = 0;
|
|
|
+ bmval[2] = 0;
|
|
|
|
|
|
READ_BUF(4);
|
|
|
READ32(bmlen);
|
|
@@ -247,13 +248,16 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
|
|
|
READ32(bmval[0]);
|
|
|
if (bmlen > 1)
|
|
|
READ32(bmval[1]);
|
|
|
+ if (bmlen > 2)
|
|
|
+ READ32(bmval[2]);
|
|
|
|
|
|
DECODE_TAIL;
|
|
|
}
|
|
|
|
|
|
static u32 nfsd_attrmask[] = {
|
|
|
NFSD_WRITEABLE_ATTRS_WORD0,
|
|
|
- NFSD_WRITEABLE_ATTRS_WORD1
|
|
|
+ NFSD_WRITEABLE_ATTRS_WORD1,
|
|
|
+ NFSD_WRITEABLE_ATTRS_WORD2
|
|
|
};
|
|
|
|
|
|
static __be32
|
|
@@ -274,9 +278,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
|
|
|
* According to spec, unsupported attributes return ERR_ATTRNOTSUPP;
|
|
|
* read-only attributes return ERR_INVAL.
|
|
|
*/
|
|
|
- if ((bmval[0] & ~NFSD_SUPPORTED_ATTRS_WORD0) || (bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1))
|
|
|
+ if ((bmval[0] & ~nfsd_suppattrs0(argp->minorversion)) ||
|
|
|
+ (bmval[1] & ~nfsd_suppattrs1(argp->minorversion)) ||
|
|
|
+ (bmval[2] & ~nfsd_suppattrs2(argp->minorversion)))
|
|
|
return nfserr_attrnotsupp;
|
|
|
- if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]))
|
|
|
+ if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
|
|
|
+ (bmval[2] & ~writable[2]))
|
|
|
return nfserr_inval;
|
|
|
|
|
|
READ_BUF(4);
|
|
@@ -411,6 +418,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, u32 *writable,
|
|
|
goto xdr_error;
|
|
|
}
|
|
|
}
|
|
|
+ BUG_ON(bmval[2]); /* no such writeable attr supported yet */
|
|
|
if (len != expected_len)
|
|
|
goto xdr_error;
|
|
|
|
|
@@ -1726,6 +1734,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
|
|
|
{
|
|
|
u32 bmval0 = bmval[0];
|
|
|
u32 bmval1 = bmval[1];
|
|
|
+ u32 bmval2 = bmval[2];
|
|
|
struct kstat stat;
|
|
|
struct svc_fh tempfh;
|
|
|
struct kstatfs statfs;
|
|
@@ -1739,12 +1748,16 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
|
|
|
int err;
|
|
|
int aclsupport = 0;
|
|
|
struct nfs4_acl *acl = NULL;
|
|
|
+ struct nfsd4_compoundres *resp = rqstp->rq_resp;
|
|
|
+ u32 minorversion = resp->cstate.minorversion;
|
|
|
|
|
|
BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
|
|
|
- BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
|
|
|
- BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
|
|
|
+ BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
|
|
|
+ BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
|
|
|
+ BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
|
|
|
|
|
|
if (exp->ex_fslocs.migrated) {
|
|
|
+ BUG_ON(bmval[2]);
|
|
|
status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
|
|
|
if (status)
|
|
|
goto out;
|
|
@@ -1790,22 +1803,42 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
|
|
|
if ((buflen -= 16) < 0)
|
|
|
goto out_resource;
|
|
|
|
|
|
- WRITE32(2);
|
|
|
- WRITE32(bmval0);
|
|
|
- WRITE32(bmval1);
|
|
|
+ if (unlikely(bmval2)) {
|
|
|
+ WRITE32(3);
|
|
|
+ WRITE32(bmval0);
|
|
|
+ WRITE32(bmval1);
|
|
|
+ WRITE32(bmval2);
|
|
|
+ } else if (likely(bmval1)) {
|
|
|
+ WRITE32(2);
|
|
|
+ WRITE32(bmval0);
|
|
|
+ WRITE32(bmval1);
|
|
|
+ } else {
|
|
|
+ WRITE32(1);
|
|
|
+ WRITE32(bmval0);
|
|
|
+ }
|
|
|
attrlenp = p++; /* to be backfilled later */
|
|
|
|
|
|
if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
|
|
|
- u32 word0 = NFSD_SUPPORTED_ATTRS_WORD0;
|
|
|
+ u32 word0 = nfsd_suppattrs0(minorversion);
|
|
|
+ u32 word1 = nfsd_suppattrs1(minorversion);
|
|
|
+ u32 word2 = nfsd_suppattrs2(minorversion);
|
|
|
+
|
|
|
if ((buflen -= 12) < 0)
|
|
|
goto out_resource;
|
|
|
if (!aclsupport)
|
|
|
word0 &= ~FATTR4_WORD0_ACL;
|
|
|
if (!exp->ex_fslocs.locations)
|
|
|
word0 &= ~FATTR4_WORD0_FS_LOCATIONS;
|
|
|
- WRITE32(2);
|
|
|
- WRITE32(word0);
|
|
|
- WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
|
|
|
+ if (!word2) {
|
|
|
+ WRITE32(2);
|
|
|
+ WRITE32(word0);
|
|
|
+ WRITE32(word1);
|
|
|
+ } else {
|
|
|
+ WRITE32(3);
|
|
|
+ WRITE32(word0);
|
|
|
+ WRITE32(word1);
|
|
|
+ WRITE32(word2);
|
|
|
+ }
|
|
|
}
|
|
|
if (bmval0 & FATTR4_WORD0_TYPE) {
|
|
|
if ((buflen -= 4) < 0)
|
|
@@ -2115,6 +2148,8 @@ out_acl:
|
|
|
}
|
|
|
WRITE64(stat.ino);
|
|
|
}
|
|
|
+ BUG_ON(bmval2); /* FIXME: not implemented yet */
|
|
|
+
|
|
|
*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
|
|
|
*countp = p - buffer;
|
|
|
status = nfs_ok;
|