[pnfs] [PATCH 2/4] nfsd41: support for 3-word long attribute bitmask
Benny Halevy
bhalevy at panasas.com
Mon May 12 14:26:07 EDT 2008
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
fs/nfsd/nfs4xdr.c | 52 +++++++++++++++++++++++++++++++++++++-------
include/linux/nfsd/nfsd.h | 3 ++
include/linux/nfsd/xdr4.h | 12 +++++-----
3 files changed, 52 insertions(+), 15 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index cc5f62d..eac9656 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -248,13 +248,18 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
READ32(bmval[0]);
if (bmlen > 1)
READ32(bmval[1]);
+#if defined(CONFIG_NFSD_V4_1)
+ if (bmlen > 2)
+ READ32(bmval[2]);
+#endif /* CONFIG_NFSD_V4_1 */
DECODE_TAIL;
}
static u32 nfsd_attrmask[] = {
NFSD_WRITEABLE_ATTRS_WORD0,
- NFSD_WRITEABLE_ATTRS_WORD1
+ NFSD_WRITEABLE_ATTRS_WORD1,
+ NFSD_WRITEABLE_ATTRS_WORD2
};
static __be32
@@ -275,9 +280,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_SUPPORTED_ATTRS_WORD0) ||
+ (bmval[1] & ~NFSD_SUPPORTED_ATTRS_WORD1) ||
+ (bmval[2] & ~NFSD_SUPPORTED_ATTRS_WORD2))
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);
@@ -426,6 +434,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;
@@ -1728,6 +1737,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;
@@ -1745,8 +1755,13 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
+ if (bmval2 & ~NFSD_SUPPORTED_ATTRS_WORD2) {
+ printk(KERN_ERR "%s: bmval2=0x%x\n", __func__, bmval2);
+ WARN_ON(1);
+ }
if (exp->ex_fslocs.migrated) {
+ BUG_ON(bmval[2]);
status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
if (status)
goto out;
@@ -1792,9 +1807,19 @@ 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) {
@@ -1805,9 +1830,16 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
word0 &= ~FATTR4_WORD0_ACL;
if (!exp->ex_fslocs.locations)
word0 &= ~FATTR4_WORD0_FS_LOCATIONS;
- WRITE32(2);
- WRITE32(word0);
- WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
+ if (!NFSD_SUPPORTED_ATTRS_WORD2) {
+ WRITE32(2);
+ WRITE32(word0);
+ WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
+ } else {
+ WRITE32(3);
+ WRITE32(word0);
+ WRITE32(NFSD_SUPPORTED_ATTRS_WORD1);
+ WRITE32(NFSD_SUPPORTED_ATTRS_WORD2);
+ }
}
if (bmval0 & FATTR4_WORD0_TYPE) {
if ((buflen -= 4) < 0)
@@ -2117,6 +2149,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;
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 30fe601..64b9e45 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -333,6 +333,8 @@ extern struct timeval nfssvc_boot;
| FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \
| FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID)
+#define NFSD_SUPPORTED_ATTRS_WORD2 0
+
/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
#define NFSD_WRITEONLY_ATTRS_WORD1 \
(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
@@ -343,6 +345,7 @@ extern struct timeval nfssvc_boot;
#define NFSD_WRITEABLE_ATTRS_WORD1 \
(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
| FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_METADATA | FATTR4_WORD1_TIME_MODIFY_SET)
+#define NFSD_WRITEABLE_ATTRS_WORD2 0
#endif /* CONFIG_NFSD_V4 */
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
index 9e87ebf..8b4b48d 100644
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -93,7 +93,7 @@ struct nfsd4_create {
u32 specdata2;
} dev; /* NF4BLK, NF4CHR */
} u;
- u32 cr_bmval[2]; /* request */
+ u32 cr_bmval[3]; /* request */
struct iattr cr_iattr; /* request */
struct nfsd4_change_info cr_cinfo; /* response */
struct nfs4_acl *cr_acl;
@@ -109,7 +109,7 @@ struct nfsd4_delegreturn {
};
struct nfsd4_getattr {
- u32 ga_bmval[2]; /* request */
+ u32 ga_bmval[3]; /* request */
struct svc_fh *ga_fhp; /* response */
};
@@ -210,7 +210,7 @@ struct nfsd4_open {
stateid_t op_delegate_stateid; /* request - response */
u32 op_create; /* request */
u32 op_createmode; /* request */
- u32 op_bmval[2]; /* request */
+ u32 op_bmval[3]; /* request */
union { /* request */
struct iattr iattr; /* UNCHECKED4,GUARDED4 */
nfs4_verifier verf; /* EXCLUSIVE4 */
@@ -265,7 +265,7 @@ struct nfsd4_readdir {
nfs4_verifier rd_verf; /* request */
u32 rd_dircount; /* request */
u32 rd_maxcount; /* request */
- u32 rd_bmval[2]; /* request */
+ u32 rd_bmval[3]; /* request */
struct svc_rqst *rd_rqstp; /* response */
struct svc_fh * rd_fhp; /* response */
@@ -308,7 +308,7 @@ struct nfsd4_secinfo {
struct nfsd4_setattr {
stateid_t sa_stateid; /* request */
u32 sa_minorversion; /* processing */
- u32 sa_bmval[2]; /* request */
+ u32 sa_bmval[3]; /* request */
struct iattr sa_iattr; /* request */
struct nfs4_acl *sa_acl;
};
@@ -334,7 +334,7 @@ struct nfsd4_setclientid_confirm {
/* also used for NVERIFY */
struct nfsd4_verify {
- u32 ve_bmval[2]; /* request */
+ u32 ve_bmval[3]; /* request */
u32 ve_attrlen; /* request */
char * ve_attrval; /* request */
};
--
1.5.3.3
More information about the pNFS
mailing list