[pnfs] new version of xdr for pNFS Linux client/server

Benny Halevy bhalevy at panasas.com
Tue Aug 29 05:05:00 EDT 2006


It looks like the nfs error codes are stale...
Attached is a patch to fix that and if there's no objection I'd like to
submit it to the cvs tree (well, it compiles ;-)

The only change in it that's not mechanical is in nfsd4_layoutget()
in which the handling of the status returned by the file system's
layout_get() method didn't make much sense to me, especially
since nfserr_nomatching_layouttype does not exist in nfsv4.1.
The gist of it is to return nfserr_layouttrylater for transient
errors like ENOENT, nfserr_badlayout if layout are supported
but no layout matches the client provided layout identification
(I guessed the layout driver would return -ENOENT in this case)
and in the default case return nfserr_layoutunavailable indicating
that layouts are not supported for the file.

I'm not sure if the default error is the best one... Should we allow the 
file
system to return nfs errors rather than only system errors
if it wishes to return a specific nfs error code (e.g. NFS4ERR_INVAL
if a layoutget is called on a non-regular file). The nfsd can still
verify that the file-system provided error code is within the
spec before converting it to network order and returning upstream.

                switch (status) {
                        case 0:
                                break;
-                       case -ENOENT:
                        case -ENOMEM:
-                               status = nfserr_layoutunavailable;
+                               status = nfserr_layouttrylater;
+                               break;
+                       case -ENOENT:
+                               status = nfserr_badlayout;
                                break;
                        default:
-                               status = nfserr_nomatching_layouttype;
+                               status = nfserr_layoutunavailable;
                }

Benny

Marc Eshel wrote:
> Attached is the patch to upgrade the pNFS Linux client and server code 
> to the latest spec. If there are no objection I will check it in to 
> the cvs tree in a couple of days.
> Marc.
>
> ------------------------------------------------------------------------
>
> Index: nfs4.h
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/include/linux/nfs4.h,v
> retrieving revision 1.8
> diff -u -r1.8 nfs4.h
> --- nfs4.h	13 Jul 2006 17:18:46 -0000	1.8
> +++ nfs4.h	22 Aug 2006 22:12:29 -0000
> @@ -152,11 +152,11 @@
>  	OP_VERIFY = 37,
>  	OP_WRITE = 38,
>  	OP_RELEASE_LOCKOWNER = 39,
> -	OP_LAYOUTGET = 40,
> -	OP_LAYOUTCOMMIT = 41,
> -	OP_LAYOUTRETURN = 42,
> -	OP_GETDEVICEINFO = 43,
> -	OP_GETDEVICELIST = 44,
> +	OP_GETDEVICEINFO = 47,
> +	OP_GETDEVICELIST = 48,
> +	OP_LAYOUTCOMMIT = 49,
> +	OP_LAYOUTGET = 50,
> +	OP_LAYOUTRETURN = 51,
>  	OP_ILLEGAL = 10044,
>  };
>  
> Index: nfs4_pnfs.h
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/include/linux/nfs4_pnfs.h,v
> retrieving revision 1.10
> diff -u -r1.10 nfs4_pnfs.h
> --- nfs4_pnfs.h	18 Aug 2006 14:09:33 -0000	1.10
> +++ nfs4_pnfs.h	22 Aug 2006 22:12:29 -0000
> @@ -116,14 +116,16 @@
>  
>  struct pnfs_device
>  {
> -	unsigned int  layoutclass;
>  	int           dev_id;
> +	int           dev_type;
> +	unsigned int  dev_count;
>  	unsigned int  dev_addr_len;
>  	char          dev_addr_buf[NFS4_PNFS_DEV_MAXSIZE];
>  };
>  
>  struct pnfs_devicelist {
>  	unsigned int        num_devs;
> +	unsigned int        eof;
>  	unsigned int        devs_len;
>  	struct pnfs_device  devs[NFS4_PNFS_DEV_MAXCOUNT];
>  };
> @@ -168,6 +170,11 @@
>  	LAYOUT_OSD2_OBJECTS = 2,
>  	LAYOUT_BLOCK_VOLUME = 3,
>  	LAYOUT_PVFS2        = 4
> +};
> +
> +enum file_layout_device_type {
> +	FILE_SIMPLE  = 1,
> +	FILE_COMPLEX = 2
>  };
>  
>  #endif /* LINUX_NFS4_PNFS_H */
> Index: nfsd/nfs4layoutxdr.h
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/include/linux/nfsd/nfs4layoutxdr.h,v
> retrieving revision 1.2
> diff -u -r1.2 nfs4layoutxdr.h
> --- nfsd/nfs4layoutxdr.h	12 Apr 2006 17:59:58 -0000	1.2
> +++ nfsd/nfs4layoutxdr.h	22 Aug 2006 22:12:30 -0000
> @@ -62,13 +62,9 @@
>  	struct xdr_netobj r_addr;
>  };
>  
> -struct nfsd4_pnfs_layoutdevlist {
> -	u32     len;
> -	u32     *list;
> -};
> -
>  struct nfsd4_pnfs_layoutlist {
> -	struct nfsd4_pnfs_layoutdevlist dev_ids;
> +	u32				dev_id;
> +	u32                             dev_index;
>  	struct knfsd_fh                 *fhp;
>  };
>  
> @@ -77,6 +73,8 @@
>  	u32                             lg_commit_through_mds; /* response */
>  	u64                             lg_stripe_unit; /* response */
>  	u64                             lg_file_size;   /* response */
> +	u32                             lg_indexlen;    /* response */
> +	u32				*lg_indexlist;  /* response */
>  	u32                             lg_llistlen;    /* response */
>  	struct nfsd4_pnfs_layoutlist    *lg_llist;      /* response */
>  };
> Index: nfsd/nfsd4_pnfs.h
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/include/linux/nfsd/nfsd4_pnfs.h,v
> retrieving revision 1.4
> diff -u -r1.4 nfsd4_pnfs.h
> --- nfsd/nfsd4_pnfs.h	25 Jul 2006 04:35:03 -0000	1.4
> +++ nfsd/nfsd4_pnfs.h	22 Aug 2006 22:12:30 -0000
> @@ -45,7 +45,7 @@
>   * the gd_ops->layout_encode() callback */
>  struct nfsd4_pnfs_devlist {
>  	u32		dev_id;
> -	u32		dev_lotype;
> +	u32		dev_type;
>  	void	 	*dev_addr;  /* encoded by callback */
>  };
>  
> @@ -56,8 +56,10 @@
>  	/* nfs4_verifier */
>  	u64			        gd_verf;        /* request - response */
>  	struct export_operations	*gd_ops;
> +	u32             		gd_dev_type;    /* response */
>  	u32				gd_devlist_len; /* response */
>  	struct nfsd4_pnfs_devlist 	*gd_devlist;    /*response */
> +	u32				gd_eof;
>  };
>  
>  struct nfsd4_pnfs_getdevinfo {
> @@ -65,7 +67,9 @@
>  	u32                             gd_dev_id;    /* request */
>  	u32                             gd_maxcnt;    /* request */
>  	struct export_operations	*gd_ops;
> -	void				*gd_devaddr;  /*response */
> +	u32             		gd_dev_type;    /* response */
> +	u32				gd_devlist_len; /* response */
> +	void				*gd_devaddr;    /*response */
>  };
>  
>  struct nfsd4_pnfs_layoutget {
> Index: nfsd/state.h
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/include/linux/nfsd/state.h,v
> retrieving revision 1.7
> diff -u -r1.7 state.h
> --- nfsd/state.h	25 Jul 2006 04:35:03 -0000	1.7
> +++ nfsd/state.h	22 Aug 2006 22:12:30 -0000
> @@ -139,7 +139,8 @@
>  
>  enum layout_recall_type {
>  	RECALL_FILE = 1,
> -	RECALL_FSID = 2
> +	RECALL_FSID = 2,
> +	RECALL_ALL  = 3
>  };
>  
>  struct nfs4_cb_layout {
>
> Index: callback.h
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfs/callback.h,v
> retrieving revision 1.4
> diff -u -r1.4 callback.h
> --- callback.h	25 Jul 2006 04:35:02 -0000	1.4
> +++ callback.h	22 Aug 2006 22:11:58 -0000
> @@ -62,7 +62,8 @@
>
>  enum layout_recall_type {
>  	RECALL_FILE = 1,
> -	RECALL_FSID = 2
> +	RECALL_FSID = 2,
> +	RECALL_ALL  = 3
>  };
>
>  struct cb_pnfs_layoutrecallargs {
> Index: callback_xdr.c
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfs/callback_xdr.c,v
> retrieving revision 1.5
> diff -u -r1.5 callback_xdr.c
> --- callback_xdr.c	25 Jul 2006 04:35:02 -0000	1.5
> +++ callback_xdr.c	22 Aug 2006 22:11:58 -0000
> @@ -228,7 +228,7 @@
>  		READ64(args->cbl_fsid.major);
>  		READ64(args->cbl_fsid.minor);
>          }
> -        else {
> +        else if (args->cbl_recall_type == RECALL_FILE) {
>  		status = decode_fh(xdr, &args->cbl_fh);
>  		if (unlikely(status != 0))
>  			goto out;
> Index: nfs4filelayout.c
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfs/nfs4filelayout.c,v
> retrieving revision 1.25
> diff -u -r1.25 nfs4filelayout.c
> --- nfs4filelayout.c	31 Jul 2006 23:32:59 -0000	1.25
> +++ nfs4filelayout.c	22 Aug 2006 22:11:58 -0000
> @@ -443,6 +443,10 @@
>  	READ32(fl->commit_through_mds);
>  	READ64(fl->stripe_unit);
>  	READ64(fl->file_size);
> +	READ32(fl->index_len);
> +	if (fl->index_len > 0) { //??? if>0 must build index list
> +		printk("filelayout_set_layout: XXX add loop for index list\n");
> +	}
>  	READ32(fl->num_devs);
>
>  	dprintk("DEBUG: %s: type %d stripe_unit %lld file_size %lld devs %d\n",
> @@ -450,18 +454,11 @@
>  				fl->file_size, fl->num_devs);
>
>  	for (i = 0; i < fl->num_devs; i++) {
> -		uint32_t devs_per_stripe, j;
> -
> -		READ32(devs_per_stripe);
>
>  		/* dev_id */
>  		READ32(fl->devs[i].dev_id);
> +		READ32(fl->devs[i].dev_index);
>
> -		for (j = 1; j < devs_per_stripe; j++) {
> -			uint32_t tmp_id;
> -			READ32(tmp_id);
> -		}
> -
>  		/* fh */
>  		memset(&fl->devs[i].fh, 0, sizeof(struct nfs_fh));
>  		READ32(fl->devs[i].fh.size);
> Index: nfs4filelayout.h
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfs/nfs4filelayout.h,v
> retrieving revision 1.5
> diff -u -r1.5 nfs4filelayout.h
> --- nfs4filelayout.h	13 Jul 2006 17:18:40 -0000	1.5
> +++ nfs4filelayout.h	22 Aug 2006 22:11:58 -0000
> @@ -56,6 +56,7 @@
>
>  struct nfs4_filelayout_devs {
>  	u32 dev_id;
> +	u32 dev_index;
>  	struct nfs_fh fh;
>  };
>
> @@ -70,6 +71,7 @@
>  	u32 stripe_type;
>  	u32 commit_through_mds;
>  	u64 stripe_unit;
> +	unsigned int index_len;
>  	unsigned int num_devs;
>  	struct nfs4_filelayout_devs devs[NFS4_PNFS_MAX_DEVS];
>  };
> Index: nfs4xdr.c
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfs/nfs4xdr.c,v
> retrieving revision 1.19
> diff -u -r1.19 nfs4xdr.c
> --- nfs4xdr.c	13 Jul 2006 17:18:41 -0000	1.19
> +++ nfs4xdr.c	22 Aug 2006 22:11:59 -0000
> @@ -3787,7 +3787,7 @@
>  		READ32(res->devs[cnt].dev_id);  /* device id */
>
>  		READ_BUF(4);
> -		READ32(res->devs[cnt].layoutclass);
> +		READ32(res->devs[cnt].dev_type);
>
>  		READ_BUF(4);
>  		READ32(len);
> @@ -3807,6 +3807,8 @@
>  		total_len += len;
>  		cnt++;
>  	}
> +	READ_BUF(4);
> +	READ32(res->eof);
>
>  	res->devs_len = total_len;
>  	return 0;
> @@ -3829,7 +3831,13 @@
>  	READ32(res->dev_id);  /* device id */
>
>  	READ_BUF(4);
> -	READ32(res->layoutclass);
> +	READ32(res->dev_type);
> +
> +	READ_BUF(4);
> +	READ32(res->dev_count);
> +	if (res->dev_count > 1) { //??? if>1 must loop on list
> +		printk("decode_getdeviceinfo: XXX add loop \n");
> +	}
>
>  	READ_BUF(4);
>  	READ32(len);
> @@ -4820,11 +4828,14 @@
>  	RESERVE_SPACE(40);
>  	WRITE32(OP_LAYOUTRETURN);
>  	WRITE64(args->clientid);
> -	WRITE64(args->offset);
> -	WRITE64(args->length);
>  	WRITE32(args->reclaim);
> -	WRITE32(args->iomode);
>  	WRITE32(args->type);
> +	WRITE32(args->iomode);
> +	if (args->type == LAYOUT_NFSV4_FILES)
> +	{
> +		WRITE64(args->offset);
> +		WRITE64(args->length);
> +	}
>  	return 0;
>  }
>
> Index: nfs4callback.c
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfsd/nfs4callback.c,v
> retrieving revision 1.2
> diff -u -r1.2 nfs4callback.c
> --- nfs4callback.c	25 Jul 2006 04:35:03 -0000	1.2
> +++ nfs4callback.c	22 Aug 2006 22:12:16 -0000
> @@ -264,7 +264,7 @@
>  			lr->cbl_layoutchanged, lr->cbl_recall_type,
>  			lr->cbl_fsid.major, lr->cbl_fsid.minor);
>  	}
> -	else {
> +	else if (lr->cbl_recall_type == RECALL_FILE) {
>  		WRITE32(len);
>  		WRITEMEM(lr->cbl_fhval, len);
>  		WRITE64(lr->cbl_offset);
> Index: nfs4filelayoutxdr.c
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfsd/nfs4filelayoutxdr.c,v
> retrieving revision 1.13
> diff -u -r1.13 nfs4filelayoutxdr.c
> --- nfs4filelayoutxdr.c	12 Apr 2006 18:03:42 -0000	1.13
> +++ nfs4filelayoutxdr.c	22 Aug 2006 22:12:16 -0000
> @@ -83,21 +83,14 @@
>  static int
>  filelayout_encode_layoutlist_item(struct nfsd4_compoundres *resp, struct nfsd4_pnfs_layoutlist *item)
>  {
> -	struct nfsd4_pnfs_layoutdevlist *dlist;
> -	int i, len;
> +	int len;
>  	unsigned int fhlen = item->fhp->fh_size;
> -	u32 *devid;
>  	ENCODE_HEAD;
>
> -	dlist = &item->dev_ids;
> -	len = 8 + (4 * dlist->len) + fhlen;
> +	len = 12 + fhlen;
>  	RESERVE_SPACE(len);
> -	WRITE32(dlist->len);
> -
> -	devid = dlist->list;
> -	for (i=0; i < dlist->len; i++) {
> -		WRITE32(devid[i]);
> -	}
> +	WRITE32(item->dev_id);
> +	WRITE32(item->dev_index);
>  	WRITE32(fhlen);
>  	WRITEMEM(&item->fhp->fh_base, fhlen);
>  	ADJUST_ARGS();
> @@ -115,7 +108,7 @@
>  	ENCODE_HEAD;
>
>  	flp = (struct nfsd4_pnfs_filelayout *)layout;
> -	len = 28;
> +	len = 32;
>  	RESERVE_SPACE(len + 4);
>  	totlen = p; 	/* fill-in  opaque layout length later*/
>  	p++;
> @@ -123,6 +116,10 @@
>  	WRITE32(flp->lg_commit_through_mds);
>  	WRITE64(flp->lg_stripe_unit);
>  	WRITE64(flp->lg_file_size);
> +	WRITE32(flp->lg_indexlen);
> +	if (flp->lg_indexlen > 0) {   //??? if>0 must build index list
> +		printk("filelayout_encode_layout: XXX add loop for index list\n");
> +	}
>  	WRITE32(flp->lg_llistlen);
>  	ADJUST_ARGS();
>  	for (i=0; i < flp->lg_llistlen; i++) {
> @@ -147,8 +144,6 @@
>  		return;
>  	item = flp->lg_llist;
>  	for (i=0; i < flp->lg_llistlen; i++) {
> -		if (item->dev_ids.list)
> -			kfree(item->dev_ids.list);
>  #if 0 /* the fh is part of nfsd4_pnfs_layoutget struct */
>  		if (item->fhp)
>  			kfree(item->fhp);
> Index: nfs4proc.c
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfsd/nfs4proc.c,v
> retrieving revision 1.18
> diff -u -r1.18 nfs4proc.c
> --- nfs4proc.c	13 Jul 2006 17:18:41 -0000	1.18
> +++ nfs4proc.c	22 Aug 2006 22:12:16 -0000
> @@ -970,7 +970,6 @@
>
>          /* set the ops for encoding the devaddr */
>          gdp->gd_ops = sb->s_export_op;
> -
>  	if (sb && sb->s_export_op->get_deviceinfo) {
>  		status = sb->s_export_op->get_deviceinfo(sb, (void *)gdp);
>
> Index: nfs4xdr.c
> ===================================================================
> RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfsd/nfs4xdr.c,v
> retrieving revision 1.23
> diff -u -r1.23 nfs4xdr.c
> --- nfs4xdr.c	13 Jul 2006 17:18:41 -0000	1.23
> +++ nfs4xdr.c	22 Aug 2006 22:12:16 -0000
> @@ -1108,13 +1108,16 @@
>  {
>  	DECODE_HEAD;
>
> -	READ_BUF(36);
> +	READ_BUF(40);
>  	READ64(lrp->lr_clientid);
> -	READ64(lrp->lr_offset);
> -	READ64(lrp->lr_length);
> -	READ32(lrp->lr_iomode);
>  	READ32(lrp->lr_reclaim);
>  	READ32(lrp->lr_type);
> +	READ32(lrp->lr_iomode);
> +	if (lrp->lr_type == LAYOUT_NFSV4_FILES)
> +	{
> +		READ64(lrp->lr_offset);
> +		READ64(lrp->lr_length);
> +	}	
>
>  	DECODE_TAIL;
>  }
> @@ -1606,6 +1609,7 @@
>  	BUG_ON(bmval0 & ~NFSD_SUPPORTED_ATTRS_WORD0);
>  	BUG_ON(bmval1 & ~NFSD_SUPPORTED_ATTRS_WORD1);
>
> +
>  	if (exp->ex_fslocs.migrated) {
>  		status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
>  		if (status)
> @@ -2668,16 +2672,15 @@
>  }
>
>  static void
> -nfsd4_encode_devlist_item(struct nfsd4_compoundres *resp, struct nfsd4_pnfs_devlist *dlist, struct export_operations *ex_ops)
> +nfsd4_encode_devlist_item(struct nfsd4_compoundres *resp, struct nfsd4_pnfs_devlist *dlist, struct export_operations *ex_ops, int lotype)
>  {
>  	ENCODE_HEAD;
>
>  	RESERVE_SPACE(8);
>  	WRITE32(dlist->dev_id);
> -	WRITE32(dlist->dev_lotype);
> +	WRITE32(dlist->dev_type);
>  	ADJUST_ARGS();
> -	if (ex_ops->devaddr_encode == NULL &&
> -				dlist->dev_lotype == LAYOUT_NFSV4_FILES)
> +	if (ex_ops->devaddr_encode == NULL && lotype == LAYOUT_NFSV4_FILES)
>  	{
>  		filelayout_encode_devaddr(resp, dlist->dev_addr);
>  		filelayout_free_devaddr(dlist->dev_addr);
> @@ -2716,9 +2719,13 @@
>  		item = gdevl->gd_devlist;
>  		for (i = 0; i < gdevl->gd_devlist_len; i++) {
>  			dprintk("%s: i %d item %p\n",__FUNCTION__, i, item);
> -			nfsd4_encode_devlist_item (resp, item, gdevl->gd_ops);
> +			nfsd4_encode_devlist_item (resp, item, gdevl->gd_ops,
> +								gdevl->gd_type);
>  			item++;
>  		}
> +		RESERVE_SPACE(4);
> +		WRITE32(gdevl->gd_eof);
> +		ADJUST_ARGS();
>  		kfree(gdevl->gd_devlist);
>  	}
>  }
> @@ -2736,9 +2743,13 @@
>
>  	printk("%s: err %d\n",__FUNCTION__, nfserr);
>  	if (!nfserr) {
> -		RESERVE_SPACE(8);
> +		RESERVE_SPACE(12);
>  		WRITE32(gdev->gd_dev_id);
> -		WRITE32(gdev->gd_type);
> +		WRITE32(gdev->gd_dev_type);
> +		WRITE32(gdev->gd_devlist_len);
> +		if (gdev->gd_devlist_len > 1) { //??? if>1 must build list
> +			printk("nfsd4_encode_getdevinfo: XXX add loop list");
> +		}
>  		ADJUST_ARGS();
>  		if (gdev->gd_ops->devaddr_encode == NULL &&
>  					gdev->gd_type == LAYOUT_NFSV4_FILES)
>
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> pNFS mailing list
> pNFS at linux-nfs.org
> http://linux-nfs.org/cgi-bin/mailman/listinfo/pnfs



More information about the pNFS mailing list