[pnfs] [PATCH 3/3] pnfs-gfs2: initial GETDEVICE* work for pNFS/GFS2 integration

Benny Halevy bhalevy at panasas.com
Sun Jun 1 04:53:44 EDT 2008


On May. 30, 2008, 0:04 +0300, "David M. Richter" <richterd at citi.umich.edu> wrote:
> Initial work on the get_device_iter() and get_device_info() export operations.
> Tested at Connectathon.
> 
> Signed-off-by: David M. Richter <richterd at citi.umich.edu>
> Signed-off-by: Frank Filz <ffilzlnx at us.ibm.com>
> ---
>  fs/gfs2/ops_export.c |  128 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 128 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
> index b62cc66..4a8f6d3 100644
> --- a/fs/gfs2/ops_export.c
> +++ b/fs/gfs2/ops_export.c
> @@ -395,6 +395,132 @@ static int gfs2_layout_return(struct inode *inode, void *p)
>  
>  	return 0;
>  }
> +
> +static int gfs2_get_device_iter(struct super_block *sb,
> +				struct pnfs_deviter_arg *arg)
> +{
> +	if (arg->type != LAYOUT_NFSV4_FILES) {
> +		printk(KERN_ERR "%s: ERROR: layout type isn't 'file' "
> +			"(type: %x)\n", __func__, arg->type);
> +		return -EOPNOTSUPP;
> +	}
> +
> +	if (arg->cookie == 0) {
> +		arg->cookie = 1;
> +		arg->verf = 1;
> +		arg->devid = 1;
> +	} else
> +		arg->eof = 1;
> +
> +	return 0;
> +}
> +
> +static int gfs2_get_device_info(struct super_block *sb,
> +				struct pnfs_devinfo_arg *arg)
> +{
> +	int err, len, i = 0;
> +	struct pnfs_filelayout_device fdev;
> +	struct pnfs_filelayout_devaddr *daddr;
> +	char *ds_buf, *bufp, *bufp2;
> +
> +	if (arg->type != LAYOUT_NFSV4_FILES) {
> +		printk(KERN_ERR "%s: ERROR: layout type isn't 'file' "
> +			"(type: %x)\n", __func__, arg->type);
> +		err = -EOPNOTSUPP;
> +		goto out;
> +	}
> +
> +	if (arg->devid.pnfs_devid != 1) {
> +		printk(KERN_DEBUG "%s: WARNING: didn't receive a deviceid of "
> +			"1 (got: 0x%llx)\n", __func__, arg->devid.pnfs_devid);
> +		err = -EINVAL;
> +		goto out;
> +	}
> +
> +	/* XXX: no notifications yet */
> +	arg->notify_types = 0;
> +
> +	printk(KERN_DEBUG "%s: DEBUG: current entire DS list is |%s|\n",
> +		__func__, pnfs_ds_list);
> +	if (!*pnfs_ds_list) {
> +		printk(KERN_ERR "%s: ERROR: pnfs_ds_list has no entries!\n",
> +			__func__);
> +		err = -EIO;
> +		goto out;
> +	}
> +
> +	err = -ENOMEM;
> +	len = strlen(pnfs_ds_list) + 1;
> +	ds_buf = kmalloc(len, GFP_KERNEL);
> +	if (!ds_buf)
> +		goto out;
> +	memcpy(ds_buf, pnfs_ds_list, len);
> +	bufp = bufp2 = ds_buf;
> +
> +	/* count the number of comma-delimited DS IPs */
> +	fdev.fl_device_length = 1;
> +	while ((bufp = strchr(bufp, ',')) != NULL) {
> +		fdev.fl_device_length++;
> +		bufp++;
> +	}
> +
> +	len = sizeof(*fdev.fl_device_list) * fdev.fl_device_length;
> +	fdev.fl_device_list = kzalloc(len, GFP_KERNEL);
> +	if (!fdev.fl_device_list) {
> +		printk(KERN_ERR "%s: ERROR: unable to kmalloc a device list "
> +			"buffer for %d DSes.\n", __func__, i);
> +		goto out;
> +	}
> +
> +	fdev.fl_stripeindices_length = fdev.fl_device_length;
> +	fdev.fl_stripeindices_list =
> +		kzalloc(sizeof(u32) * fdev.fl_stripeindices_length, GFP_KERNEL);
> +
> +	if (!fdev.fl_stripeindices_list) {
> +		printk(KERN_ERR "%s: ERROR: unable to kmalloc a stripeindices "
> +			"list buffer for %d DSes.\n", __func__, i);
> +		goto out;
> +	}
> +	for (i = 0; i < fdev.fl_stripeindices_length; i++)
> +		fdev.fl_stripeindices_list[i] = i;
> +
> +	for (i = 0; (bufp = strsep(&bufp2, ",")) != NULL; i++) {
> +		printk(KERN_DEBUG "%s: DEBUG: encoding DS |%s|\n", __func__,
> +			bufp);
> +
> +		daddr = kmalloc(sizeof(*daddr), GFP_KERNEL);
> +		if (!daddr) {
> +			printk(KERN_ERR "%s: ERROR: unable to kmalloc a device "
> +				"addr buffer.\n", __func__);
> +			goto out;
> +		}
> +
> +		daddr->r_netid.data = "tcp";
> +		daddr->r_netid.len = 3;
> +		len = strlen(bufp);
> +		daddr->r_addr.data = kzalloc(len + 4, GFP_KERNEL);

kmalloc should do since you memcpy over all of it anyway.

> +		memcpy(daddr->r_addr.data, bufp, len);
> +		/*
> +		 * append the port number.  interpreted as two more bytes
> +		 * beyond the quad: ".8.1" -> (0x80 + 0x1) = port 2049.

0x800 + 1...

I'll fix these before submitting...

Benny

> +		 */
> +		memcpy(daddr->r_addr.data + len, ".8.1", 4);
> +		daddr->r_addr.len = len + 4;
> +
> +		fdev.fl_device_list[i].fl_multipath_length = 1;
> +		fdev.fl_device_list[i].fl_multipath_list = daddr;
> +	}
> +
> +	/* have nfsd encode the device info */
> +	err = arg->func(&arg->xdr, &fdev);
> +out:
> +	for (i = 0; i < fdev.fl_device_length; i++)
> +		kfree(fdev.fl_device_list[i].fl_multipath_list);
> +	kfree(fdev.fl_device_list);
> +	kfree(fdev.fl_stripeindices_list);
> +	return err;
> +}
> +
>  #endif /* CONFIG_PNFSD */
>  
>  const struct export_operations gfs2_export_ops = {
> @@ -408,6 +534,8 @@ const struct export_operations gfs2_export_ops = {
>  	.layout_get = gfs2_layout_get,
>  	.layout_commit = gfs2_layout_commit,
>  	.layout_return = gfs2_layout_return,
> +	.get_device_iter = gfs2_get_device_iter,
> +	.get_device_info = gfs2_get_device_info,
>  #endif /* CONFIG_PNFSD */
>  };
>  



More information about the pNFS mailing list