[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