[pnfs] pnfs/gfs2 stubs

david m. richter richterd at citi.umich.edu
Mon May 5 16:23:47 EDT 2008


On Mon, 5 May 2008, Frank Filz wrote:

> On Fri, 2008-05-02 at 16:10 -0400, William A. (Andy) Adamson wrote:
> > i have a patch that fixes print_ds_list. i'll submit it asap
> 
> Ok, I think I figured out how to fix print_ds_list, unfortunately, my
> system is still crashing and not being very helpful. I can't get
> anything to show up in /var/log/messages and I don't have serial console
> set up, so all I get is the last 25 lines of log information or so. The
> current crash is in mount.nfs process, but the stack makes no sense
> whatsoever:
> 
> dump_trace
> print_trace_address
> print_trace_log_lvl
> show_trace
> dump_stack
> 
> That's it, no hint of a system call...

	hm, gak.  does anything change if you don't set the ->layout_get() 
or ->layout_return() export ops?  that is, can you see the client mount 
and do GETDEVICELIST and GETDEVICEINFO and, thereafter, cat a file or 
something and see it start doing layout processing, fail when nothing's 
available, and then do a plain-vanilla READ?

	d..

 
> Here's a patch encompassing what I'm currently working with. I will
> follow with another message with what I had before applying David's
> patch (which I did completely manually because it was so simple and
> would have conflicted with my changes anyway, requiring manual merge):
> 
> diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
> index 334c7f8..9840c0f 100644
> --- a/fs/gfs2/ops_export.c
> +++ b/fs/gfs2/ops_export.c
> @@ -15,6 +15,17 @@
>  #include <linux/gfs2_ondisk.h>
>  #include <linux/crc32.h>
>  #include <linux/lm_interface.h>
> +#ifdef CONFIG_PNFSD
> +#include <linux/nfs4.h>
> +#include <linux/sunrpc/svc.h>
> +#include <linux/nfsd/nfsfh.h>
> +#include <linux/nfsd/state.h>
> +#include <linux/nfsd/nfsd4_pnfs.h>
> +#include <linux/nfsd/pnfsd.h>
> +#include <linux/nfs_fs.h>
> +#include <linux/nfs4_pnfs.h>
> +#include <linux/nfsd/nfs4layoutxdr.h>
> +#endif
>  
>  #include "gfs2.h"
>  #include "incore.h"
> @@ -294,11 +305,209 @@ static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
>  	}
>  }
>  
> +#ifdef CONFIG_PNFSD
> +/* Retrieve and encode a layout onto the xdr stream.
> + * Args:
> + * inode - inode for which to retrieve layout
> + * arg.xdr - xdr stream for encoding
> + * arg.func - Optional function called by file system to encode
> + * layout on xdr stream.
> + */
> +static int gfs2_layout_get(struct inode *inode,
> +			   struct pnfs_layoutget_arg *arg)
> +{
> +	int i, left, fhlen;
> +	struct pnfs_filelayout_layout *layout = NULL;
> +	struct knfsd_fh *fh_list = NULL;
> +	int rc = 0;
> +	int num_dests = 1;			/*FSFTEMP*/
> +
> +	printk(KERN_WARNING "gfs2_layout_get got here!\n");
> +	/* Set layout indep response args */
> +	arg->seg.layout_type = LAYOUT_NFSV4_FILES;
> +	arg->seg.offset = 0;
> +	arg->seg.length = inode->i_sb->s_maxbytes;        /* The maximum file size */
> +
> +	fhlen = sizeof(struct knfsd_fh) * num_dests;
> +	left = arg->xdr.maxcount - sizeof(struct pnfs_filelayout_layout) - fhlen;
> +	if (left < 0) {
> +		rc = -ETOOSMALL;
> +		goto error;
> +	}
> +
> +	layout = kmalloc(sizeof(struct pnfs_filelayout_layout), GFP_KERNEL);
> +	if (layout == NULL) {
> +		rc = -ENOMEM;
> +		goto error;
> +	}
> +
> +	/* Set file layout response args */
> +	layout->lg_layout_type = LAYOUT_NFSV4_FILES;
> +	layout->lg_stripe_type = STRIPE_SPARSE;
> +	layout->lg_commit_through_mds = true;
> +	layout->lg_stripe_unit = inode->i_sb->s_blocksize;	/*preferred size*/
> +	layout->lg_fh_length = num_dests;
> +	layout->device_id.pnfs_fsid = arg->fsid;
> +	layout->device_id.pnfs_devid = 1;			/*FSFTEMP*/
> +	layout->lg_first_stripe_index = 0;			/*FSFTEMP*/
> +
> +	fh_list = kmalloc(fhlen, GFP_KERNEL);
> +	if (fh_list == NULL) {
> +		rc = -ENOMEM;
> +		goto error;
> +	}
> +
> +	memset(fh_list, 0, fhlen);
> +	layout->lg_fh_list = fh_list;
> +
> +	for (i = 0; i < num_dests; i++)
> +		memcpy(&fh_list[i], arg->fh, sizeof(struct knfsd_fh));
> +
> +	/* Call nfsd code to encode layout */
> +	rc = arg->func(&arg->xdr, layout);
> +
> +exit:
> +	if (layout)
> +		kfree(layout);
> +	if (fh_list)
> +		kfree(fh_list);
> +	return rc;
> +
> +error:
> +	arg->seg.length = 0;
> +	goto exit;
> +}
> +
> +/* pNFS: commit changes to layout */
> +static int gfs2_layout_commit(struct inode *inode, void *p)
> +{
> +	return 0;
> +}
> +
> +/* pNFS: returns the layout */
> +static int gfs2_layout_return(struct inode *inode, void *p)
> +{
> +	return 0;
> +}
> +
> +/* pNFS: Returns the supported pnfs_layouttype4. */
> +static int gfs2_layout_type(void)
> +{
> +	return LAYOUT_NFSV4_FILES;
> +}
> +
> +/* dmr XXX: stub it in; eventually this should be called by the MDS' ccsd
> + *  (or whatever daemon) downcall handler, yes?
> + */
> +static int gfs2_cb_get_state(struct super_block *sb, void *state)
> +{
> +	struct pnfs_get_state *gs = (struct pnfs_get_state *)state;
> +	
> +	printk(KERN_WARNING "%s: stub called for i_ino %lx\n", __FUNCTION__, gs->ino);
> +
> +	/* dmr XXX: this will be replaced by a call into nfs4_pnfs_cb_get_state(),
> +	 * although i'm not yet sure how we'll get the superblock without something
> +	 * simple like... um, a filehandle.
> +	 */
> +	return 0;
> +}
> +
> +/* dmr XXX: only needed on DS, but stub it in */
> +static int gfs2_get_state(struct inode *inode, void *fh, void *state)
> +{
> +	struct pnfs_get_state *gs = (struct pnfs_get_state *)state;
> +
> +	gs->ino = inode->i_ino;
> +	printk(KERN_WARNING "%s: stub called for '%s' (i_ino %lx)\n", __FUNCTION__, (list_entry(inode->i_dentry.next, struct dentry, d_alias))->d_iname, gs->ino);
> +
> +	/* dmr XXX: 
> +	 * 'state' is a struct pnfs_get_state.
> +	 *  ->dsid needs to be filled in here
> +	 *  ->stid should've been filled in by caller (nfsv4_ds_get_state())
> +	 */
> +
> +	if (inode->i_sb->s_export_op->cb_get_state != gfs2_cb_get_state)
> +		printk("%s: WARNING: somehow the export_op cb_get_state ISN'T gfs2_cb_get_state(?)\n", __FUNCTION__);
> +	/* dmr XXX: this will be replaced by the backchannel call to the MDS */
> +	return gfs2_cb_get_state(NULL, gs);
> +}
> +
> +/* pNFS: returns the verifier */
> +static void gfs2_get_verifier(struct super_block *sb, u32 *p)
> +{
> +}
> +
> +/* dmr XXX: */
> +static int gfs2_get_device_iter(struct super_block *sb, struct pnfs_deviter_arg *arg)
> +{
> +	printk(KERN_WARNING "gfs2_get_device_iter\n");
> +	/* XXX: verify layout type */
> +	if (arg->cookie == 0) {
> +		/* dmr XXX: cookie/verf are basically ignored: now or for good? */
> +		arg->cookie = 1;
> +		arg->verf = 1; 
> +		/* one deviceid covers all filelayout devs, so we only ever return it */
> +		arg->devid = 1;
> +	} else
> +		arg->eof = 1;
> +
> +	return 0;
> +}
> +
> +/* dmr XXX: */
> +static int gfs2_get_device_info(struct super_block *sb, struct pnfs_devinfo_arg *arg)
> +{
> +	int err;
> +	struct pnfs_filelayout_device fdev;
> +	struct pnfs_filelayout_multipath mpath;
> +	struct pnfs_filelayout_devaddr daddr;
> +
> +	printk(KERN_WARNING "gfs2_get_device_info\n");
> +	/* XXX: verify layout type */
> +	if (arg->devid.pnfs_devid != 1) {
> +		printk("%s: WARNING: didn't receive a deviceid of 1 (got: 0x%x)\n", __FUNCTION__, arg->devid);
> +		/* XXX: this can't actually be right */
> +		return 1;
> +	}
> +
> +	/* no notifications for file layout -- we only have the 1 deviceid */
> +	arg->notify_types = 0;
> +
> +	fdev.fl_device_length = 1;
> +	fdev.fl_device_list = &mpath;
> +	mpath.fl_multipath_length = 1;
> +	mpath.fl_multipath_list = &daddr;
> +	daddr.r_netid.data = "tcp";
> +	daddr.r_netid.len = 3;
> +	daddr.r_addr.data = "9.47.66.22.8.1";
> +	daddr.r_addr.len = strlen(daddr.r_addr.data);
> +
> +	fdev.fl_stripeindices_length = fdev.fl_device_length;
> +	fdev.fl_stripeindices_list[0] = 0;
> +
> +	err = arg->func(&arg->xdr, &fdev);
> +	printk("%s: ->func() returned %d\n", __FUNCTION__, err);
> +
> +	return err;
> +}
> +#endif /* CONFIG_PNFSD */
> +
>  const struct export_operations gfs2_export_ops = {
>  	.encode_fh = gfs2_encode_fh,
>  	.fh_to_dentry = gfs2_fh_to_dentry,
>  	.fh_to_parent = gfs2_fh_to_parent,
>  	.get_name = gfs2_get_name,
>  	.get_parent = gfs2_get_parent,
> +#ifdef CONFIG_PNFSD
> +	/* dmr XXX: see comments above */
> +	.layout_type = gfs2_layout_type,
> +	.cb_get_state = gfs2_cb_get_state,
> +	.get_state = gfs2_get_state,
> +	.get_device_iter = gfs2_get_device_iter,
> +	.get_device_info = gfs2_get_device_info,
> +	.layout_get = gfs2_layout_get,
> +	.layout_return = gfs2_layout_return,
> +	.get_verifier = gfs2_get_verifier,
> +#endif /* CONFIG_PNFSD */
>  };
>  
> diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
> index 59ca50a..521ad00 100644
> --- a/fs/nfs/nfs4filelayoutdev.c
> +++ b/fs/nfs/nfs4filelayoutdev.c
> @@ -67,16 +67,22 @@ void
>  print_ds_list(struct nfs4_pnfs_dev *fdev)
>  {
>  	struct nfs4_pnfs_ds *ds;
> +	u32 flags = 0;
>  	int i;
>  
> -	ds = fdev->ds_list[0];
> +	//ds = fdev->ds_list[0];
>  	for (i = 0; i < fdev->num_ds; i++) {
> -		dprintk("        ip_addr %x\n", ntohl(ds->ds_ip_addr));
> -		dprintk("        port %hu\n", ntohs(ds->ds_port));
> -		dprintk("        client %p\n", ds->ds_clp);
> -		dprintk("        cl_exchange_flags %x\n",
> -				    ds->ds_clp->cl_exchange_flags);
> -		ds++;
> +		ds = fdev->ds_list[i];
> +		dprintk("        ds %d (%p):\n", i, ds);
> +		if (ds == 0)
> +			continue;
> +		if (ds->ds_clp != 0)
> +			flags = ds->ds_clp->cl_exchange_flags;
> +		dprintk("            ip_addr %x\n", ntohl(ds->ds_ip_addr));
> +		dprintk("            port %hu\n", ntohs(ds->ds_port));
> +		dprintk("            client %p\n", ds->ds_clp);
> +		dprintk("            cl_exchange_flags %x\n", flags);
> +		//ds++;
>  	}
>  }
>  
> @@ -483,9 +489,15 @@ decode_and_add_ds(uint32_t **pp, struct filelayout_mount_type *mt)
>  			__func__, len);
>  		goto out_err;
>  	}
> +	if (len <= 11) {
> +		printk("%s: ERROR: Device ip/port too short (%d)\n",
> +			__func__, len);
> +		goto out_err;
> +	}
>  	COPYMEM(r_addr, len);
>  	*pp = p;
>  	r_addr[len] = '\0';
> +	dprintk("%s r_addr=%s\n", __func__, r_addr);
>  	sscanf(r_addr, "%d.%d.%d.%d.%d.%d", &tmp[0], &tmp[1],
>  	       &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
>  	ip_addr = htonl((tmp[0]<<24) | (tmp[1]<<16) | (tmp[2]<<8) | (tmp[3]));
> 
> 
> 
> 


More information about the pNFS mailing list