[pnfs] [PATCH 2/4] nfsd41: support for 3-word long attribute bitmask
Benny Halevy
bhalevy at panasas.com
Mon May 12 14:55:39 EDT 2008
On May. 12, 2008, 11:26 -0700, Benny Halevy <bhalevy at panasas.com> wrote:
> 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
bmval[2] must be initialized to zero.
@@ -237,6 +237,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
bmval[0] = 0;
bmval[1] = 0;
+ bmval[2] = 0;
READ_BUF(4);
READ32(bmlen);
> @@ -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 */
> };
More information about the pNFS
mailing list