[pnfs] [PATCH 04/10] pnfs: update client layout xdr for draft 19.

Benny Halevy bhalevy at panasas.com
Sun Feb 10 04:45:33 EST 2008


On Feb. 09, 2008, 10:26 +0200, Marc Eshel <eshel at almaden.ibm.com> wrote:
> From: Dean Hildebrand <dhildeb at us.ibm.com>
> 
> 
> ---
> 
>  fs/nfs/nfs4filelayout.c   |    1 +
>  fs/nfs/nfs4filelayout.h   |    1 +
>  fs/nfs/nfs4xdr.c          |   55 ++++++++++++++++++++++++++-------------------
>  fs/nfs/pnfs.c             |    3 ++
>  include/linux/nfs4_pnfs.h |    1 +
>  include/linux/pnfs_xdr.h  |    8 +++++--
>  6 files changed, 43 insertions(+), 26 deletions(-)
> 
> diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
> index a1ada9e..3453f2b 100644
> --- a/fs/nfs/nfs4filelayout.c
> +++ b/fs/nfs/nfs4filelayout.c
> @@ -618,6 +618,7 @@ filelayout_set_layout(struct pnfs_layout_type *layoutid,
>  	fl->stripe_unit = nfl_util & ~NFL4_UFLG_MASK;
>  
>  	READ32(fl->first_stripe_index);
> +	READ64(fl->pattern_offset);
>  	READ32(fl->num_fh);
>  
>  	dprintk("%s: nfl_util 0x%X num_fh %u dev_id %s\n",
> diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
> index 4feee5f..8278068 100644
> --- a/fs/nfs/nfs4filelayout.h
> +++ b/fs/nfs/nfs4filelayout.h
> @@ -89,6 +89,7 @@ struct nfs4_filelayout_segment {
>  	u32 commit_through_mds;
>  	u64 stripe_unit;
>  	u32 first_stripe_index;
> +	u64 pattern_offset;
>  	pnfs_deviceid dev_id;
>  	unsigned int num_fh;
>  	struct nfs_fh fh_array[NFS4_PNFS_MAX_STRIPE_CNT];
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 867bc22..ea6d3e8 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -280,14 +280,19 @@ static int nr_sequence_quads;
>  				    NFS4_PNFS_DEVICEID4_SIZE)
>  #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + 2 + \
>  				   NFS4_PNFS_DEV_MAXSIZE)
> -#define encode_pnfs_layoutget_sz (op_encode_hdr_maxsz + 13)
> +#define encode_pnfs_layoutget_sz (op_encode_hdr_maxsz + 10 + encode_stateid_maxsz)
>  #define decode_pnfs_layoutget_maxsz	(op_decode_hdr_maxsz + 8 + \
> -					 PNFS_LAYOUT_MAXSIZE)
> -#define encode_pnfs_layoutcommit_sz	(18 + PNFS_LAYOUT_MAXSIZE + \
> -					op_encode_hdr_maxsz)
> +					 decode_stateid_maxsz + \
> +					 XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE))
> +#define encode_pnfs_layoutcommit_sz	(18 +				\
> +					 XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE) + \
> +					 op_encode_hdr_maxsz +		\
> +					 encode_stateid_maxsz)
>  #define decode_pnfs_layoutcommit_maxsz	(3 + op_decode_hdr_maxsz)
> -#define encode_pnfs_layoutreturn_sz	(8 + op_encode_hdr_maxsz)
> -#define decode_pnfs_layoutreturn_maxsz	(op_decode_hdr_maxsz)
> +#define encode_pnfs_layoutreturn_sz	(8 + op_encode_hdr_maxsz + \
> +					 encode_stateid_maxsz)
> +#define decode_pnfs_layoutreturn_maxsz	(op_decode_hdr_maxsz + \
> +					 decode_stateid_maxsz)
>  #endif /* CONFIG_PNFS */
>  
>  #define NFS40_enc_compound_sz	(1024)  /* XXX: large enough? */
> @@ -1110,29 +1115,21 @@ static int encode_pnfs_layoutcommit(struct xdr_stream *xdr,
>  		args->lseg.length, args->lseg.offset, args->lastbytewritten,
>  		args->layout_type);
>  
> -	RESERVE_SPACE(40);
> +	RESERVE_SPACE(40 + NFS4_STATEID_SIZE);
>  	WRITE32(OP_LAYOUTCOMMIT);
>  	WRITE64(args->lseg.offset);
>  	WRITE64(args->lseg.length);
>  	WRITE32(0);     /* reclaim */
> +	WRITEMEM(args->stateid.data, NFS4_STATEID_SIZE);
>  	WRITE32(1);     /* newoffset = TRUE */
>  	WRITE64(args->lastbytewritten);
> -	WRITE32(args->time_modify_changed);
> +	WRITE32(args->time_modify_changed != 0);
>  	if (args->time_modify_changed) {
>  		RESERVE_SPACE(12);
>  		WRITE32(0);
>  		WRITE32(args->time_modify.tv_sec);
>  		WRITE32(args->time_modify.tv_nsec);
>  	}
> -	RESERVE_SPACE(4);
> -	WRITE32(args->time_access_changed);
> -	if (args->time_access_changed) {
> -		RESERVE_SPACE(12);
> -		WRITE32(0);
> -		WRITE32(args->time_access.tv_sec);
> -		WRITE32(args->time_access.tv_nsec);
> -	}
> -
>  	RESERVE_SPACE(8 + args->new_layout_size);
>  	WRITE32(args->layout_type);
>  	WRITE32(args->new_layout_size);
> @@ -1847,7 +1844,7 @@ static int encode_pnfs_layoutget(struct xdr_stream *xdr,
>  {
>  	uint32_t *p;
>  
> -	RESERVE_SPACE(44);
> +	RESERVE_SPACE(44 + NFS4_STATEID_SIZE);
>  	WRITE32(OP_LAYOUTGET);
>  	WRITE32(0);     /* Signal layout available */
>  	WRITE32(args->type);
> @@ -1855,6 +1852,7 @@ static int encode_pnfs_layoutget(struct xdr_stream *xdr,
>  	WRITE64(args->lseg.offset);
>  	WRITE64(args->lseg.length);
>  	WRITE64(args->minlength);
> +	WRITEMEM(&args->stateid.data, NFS4_STATEID_SIZE);
>  	WRITE32(args->maxcount);
>  
>  	dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d\n",
> @@ -1881,9 +1879,10 @@ static int encode_pnfs_layoutreturn(struct xdr_stream *xdr,
>  	WRITE32(args->lseg.iomode);
>  	WRITE32(args->return_type);
>  	if (args->return_type == RETURN_FILE) {
> -		RESERVE_SPACE(16);
> +		RESERVE_SPACE(16 + NFS4_STATEID_SIZE);
>  		WRITE64(args->lseg.offset);
>  		WRITE64(args->lseg.length);
> +		WRITEMEM(&args->stateid.data, NFS4_STATEID_SIZE);
>  	}
>  	return 0;
>  }
> @@ -5553,8 +5552,9 @@ static int decode_pnfs_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
>  	status = decode_op_hdr(xdr, OP_LAYOUTGET);
>  	if (status)
>  		return status;
> -	READ_BUF(32);
> +	READ_BUF(32 + NFS4_STATEID_SIZE);
>  	READ32(res->return_on_close);
> +	COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
>  	READ64(res->lseg.offset);
>  	READ64(res->lseg.length);
>  	READ32(res->lseg.iomode);
> @@ -5579,9 +5579,18 @@ static int decode_pnfs_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
>  /*
>   * Decode LAYOUTRETURN reply
>   */
> -static int decode_pnfs_layoutreturn(struct xdr_stream *xdr)
> +static int decode_pnfs_layoutreturn(struct xdr_stream *xdr, uint32_t *p, struct nfs4_pnfs_layoutreturn_res *res)
>  {
> -	return decode_op_hdr(xdr, OP_LAYOUTRETURN);
> +	int status;
> +
> +	status = decode_op_hdr(xdr, OP_LAYOUTRETURN);
> +	if (status)
> +		return status;
> +	READ_BUF(4 + NFS4_STATEID_SIZE);
> +	READ32(res->lrs_present);
> +	if (res->lrs_present)
> +		COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
> +	return 0;
>  }
>  
>   #endif /* CONFIG_PNFS */
> @@ -7534,7 +7543,7 @@ static int nfs41_xdr_dec_pnfs_layoutreturn(struct rpc_rqst *rqstp, uint32_t *p,
>  	status = decode_putfh(&xdr);
>  	if (status)
>  		goto out;
> -	status = decode_pnfs_layoutreturn(&xdr);
> +	status = decode_pnfs_layoutreturn(&xdr, p, res);
>  out:
>  	return status;
>  }
> diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
> index f56ff89..64203f9 100644
> --- a/fs/nfs/pnfs.c
> +++ b/fs/nfs/pnfs.c
> @@ -866,7 +866,9 @@ pnfs_update_layout(struct inode *ino,
>  
>  	res.layout.buf = NULL;
>  	spin_unlock(&nfsi->lo_lock);
> +	memcpy(&layout_new->stateid.data, &arg.stateid.data, NFS4_STATEID_SIZE);
>  	result = get_layout(ino, ctx, &arg, &res);
> +	memcpy(&res.stateid.data, &layout_new->stateid.data, NFS4_STATEID_SIZE);
>  	spin_lock(&nfsi->lo_lock);

let's do the mem copies under the spin lock so at least they'll be atomic
(I can make the change when applying the patch here)
In the future we also need to check for reordering using the returned sequence id
so that we serialize the layout updates properly.

>  
>  	/* we got a reference on nfsi->current_layout hence it must never
> @@ -1688,7 +1690,6 @@ pnfs_layoutcommit_setup(struct pnfs_layoutcommit_data *data, int sync)
>  
>  	/* TODO: Need to determine the correct values */
>  	data->args.time_modify_changed = 0;
> -	data->args.time_access_changed = 0;
>  
>  	/* Set values from inode so it can be reset
>  	 */
> diff --git a/include/linux/nfs4_pnfs.h b/include/linux/nfs4_pnfs.h
> index c05477c..ff1eff7 100644
> --- a/include/linux/nfs4_pnfs.h
> +++ b/include/linux/nfs4_pnfs.h
> @@ -43,6 +43,7 @@ struct pnfs_layout_type {
>  	struct list_head segs;		/* layout segments list */
>  	int roc_iomode;			/* iomode to return on close, 0=none */
>  	struct inode *inode;
> +	nfs4_stateid stateid;
>  	u8 ld_data[];			/* layout driver private data */
>  };
>  
> diff --git a/include/linux/pnfs_xdr.h b/include/linux/pnfs_xdr.h
> index a75f143..c6a4e3a 100644
> --- a/include/linux/pnfs_xdr.h
> +++ b/include/linux/pnfs_xdr.h
> @@ -39,6 +39,7 @@ struct nfs4_pnfs_layoutget_arg {
>  	__u64 minlength;
>  	__u32 maxcount;
>  	struct nfs_open_context *ctx;
> +	nfs4_stateid stateid;
>  	struct inode *inode;
>  	struct nfs41_sequence_args	seq_args;
>  };
> @@ -47,6 +48,7 @@ struct nfs4_pnfs_layoutget_res {
>  	__u32 return_on_close;
>  	struct nfs4_pnfs_layout_segment lseg;
>  	__u32 type;
> +	nfs4_stateid stateid;
>  	struct nfs4_pnfs_layout layout;
>  	struct nfs41_sequence_res	seq_res;
>  };
> @@ -57,11 +59,10 @@ struct nfs4_pnfs_layoutget {
>  };
>  
>  struct pnfs_layoutcommit_arg {
> +	nfs4_stateid stateid;
>  	__u64 lastbytewritten;
>  	__u32 time_modify_changed;
>  	struct timespec time_modify;
> -	__u32 time_access_changed;
> -	struct timespec time_access;
>  	const u32 *bitmask;
>  	struct nfs_fh *fh;
>  
> @@ -96,12 +97,15 @@ struct nfs4_pnfs_layoutreturn_arg {
>  	__u32	layout_type;
>  	__u32	return_type;
>  	struct nfs4_pnfs_layout_segment lseg;
> +	nfs4_stateid stateid;
>  	struct inode *inode;
>  	struct nfs41_sequence_args	seq_args;
>  };
>  
>  struct nfs4_pnfs_layoutreturn_res {
>  	struct nfs41_sequence_res	seq_res;
> +	u32 lrs_present;
> +	nfs4_stateid stateid;
>  };
>  
>  struct nfs4_pnfs_layoutreturn {
> _______________________________________________
> pNFS mailing list
> pNFS at linux-nfs.org
> http://linux-nfs.org/cgi-bin/mailman/listinfo/pnfs



More information about the pNFS mailing list