All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benny Halevy <bhalevy@primarydata.com>
To: " J. Bruce Fields" <bfields@redhat.com>
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH RFC v0 12/49] pnfsd: get device list/info
Date: Thu, 26 Sep 2013 14:40:38 -0400	[thread overview]
Message-ID: <1380220838-13228-1-git-send-email-bhalevy@primarydata.com> (raw)
In-Reply-To: <52447EA0.7070004@primarydata.com>

From: Benny Halevy <bhalevy@panasas.com>

Implement the generic handling of GETDEVICELIST and GETDEVICEINFO.

After verifying that the requested layout type is supported,
getdevlist uses the get_device_iter pnfs export method
to encode the list of deviceids and get the cookie, verifier,
and eof flag to be used be the client to iterate through
the whole device list.

Getdevinfo uses the get_device_info pnfs export method
to encode the device info for the given deviceid.

The filesystem can choose to return valid cookie and cookieverf
on eof, pointing at the end of the device list so that subsequent
calls to GETDEVIE LIST will return an empty list.

Note that with the file layout, lots of devices are sent under a
single device id, so the client will need to send a relatively
large value of maxcount.

If maxcount is 0 then just update notifications.
The nfsv4.1 spec forbids returning ETOOSMALL in this case.
It is up to the implementor of the get_device_info method
to verify the deviceid in this case and return no
info for it.

If no notifications are given represent gdir_notification as an empty
bitmap array rather than one consisting of a single zeroed entry.
Thanks to Dean Hildebrand for suggesting this optimization
and to Peter Staubach for convincing that it's worth it.

Nfsd should return sbid while getting device list so that it can operate it properly later in nfsd4_getdevinfo.

[extracted from pnfsd: Initial pNFS server implementation.]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfsd: update pNFS server ops to draft 13]
Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
[pnfsd: Fix server getdevicelist update to draft 13]
Signed-off-by: Andy Adamson<andros@umich.edu>
[pnfsd: update pNFS server ops to draft 13]
Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
[pnfsd: Fix server GETDEVICELIST to comply with NFSv4.1 Draft 13]
Signed-off-by: Ricardo Labiaga <ricardo.labiaga@netapp.com>
[pnfsd: Streamline error code checking for non-pnfs filesystems]
Signed-off-by: Dean Hildebrand <seattleplus@gmail.com>
[pnfsd: Simplify device export ops.]
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
[pnfs: fix compile problems if CONFIG_PNFS turned off - exportfs.h]
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
[pnfsd: Implement getdevlist maxcount checking.]
[pnfsd: use nfs error codes]
[pnfsd: Use 128 bit deviceid on server]
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
[pnfsd: fix warning in nfsd4_encode_devlist_iterator()]
Signed-off-by: Mike Sager <sager@netapp.com>
[pnfsd: Update getdeviceinfo for draft-19]
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
[pnfsd: encode empty getdeviceinfo notify bitmap rather than zeroed]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfsd: do not depend on the current file handle in getdeviceinfo]
[pnfsd: update export hold count]
Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
[pnfsd: Update getdevlist for draft 19]
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
[pnfsd: fix GETDEVICELIST encoding]
Signed-off-by: Mike Sager <sager@netapp.com>
[pnfsd: use nfsd4_compoundres pointer in pnfs_xdr_info]
[pnfsd: fix NFS4ERR_TOOSMALL for getdeviceinfo]
[pnfsd: enable multipage getdeviceinfo da_addr_body]
Signed-off-by: Andy Adamson <andros@netapp.com>
[pnfsd: move vfs api structures to nfsd4_pnfs.h]
[pnfsd: convert generic code to use new pnfs api]
[pnfsd: define pnfs_export_operations]
[pnfsd: obliterate old vfs api]
[pnfsd: fixup ENCODE_HEAD for getdevicelist/info]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfsd: get device list/info all layout types]
[pnfsd: check ex_pnfs in nfsd4_verify_layout]
Signed-off-by: Andy Adamson <andros@netapp.com>
[removed nfsd4_pnfs_fl_getdev{info,iter} stubs]
[pnfsd: filelayout: convert to using exp_xdr]
[pnfsd: get rid of getdevinfo notify_types]
[pnfsd: copy getdevinfo deviceid in one piece]
[pnfsd: rename deviceid_t struct pnfs_deviceid]
[pnfsd: fix cosmetic checkpatch warnings]
[pnfsd: handle s_pnfs_op==NULL]
[pnfsd: move getdevinfo xdr structure to private header]
[pnfsd: clean up getdeviceinfo export op API]
[pnfsd: getdeviceinfo deviceid needs to be const.]
[pnfsd: allow returning empty device list.]
[pnfsd: return NFS4ERR_INVAL when maxdevices is zero.]
[pnfsd: move getdevlist xdr structure to private header]
[pnfsd: dev_iter: clean up export API]
[pnfsd: rename device fsid member to sbid]
[pnfsd: use devid.sbid for locating super block in getdevinfo]
[pnfsd: fixup nfsd4_encode_getdev{list,info} to use __be32 nfserr]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfsd: Use list_move instead list_del and list_add]
Signed-off-by: Bian Naimeng <biannm@cn.fujitsu.com>
[pnfsd: using sbid instead of fsid while returning device list to client]
Signed-off-by: Zhengju Sha <shazhengju@nrchpc.ac.cn>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Benny Halevy <bhalevy@primarydata.com>
---
 fs/nfsd/export.c                |   3 +-
 fs/nfsd/nfs4pnfsd.c             |  30 ++++-
 fs/nfsd/nfs4proc.c              |  92 ++++++++++++++
 fs/nfsd/nfs4xdr.c               | 257 ++++++++++++++++++++++++++++++++++++++++
 fs/nfsd/pnfsd.h                 |   3 +
 fs/nfsd/xdr4.h                  |  22 ++++
 include/linux/nfsd/nfsd4_pnfs.h |  32 +++++
 7 files changed, 433 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index d803414..462f0df 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -377,7 +377,8 @@ static int check_export(struct inode *inode, int *flags, unsigned char *uuid)
 	}
 
 	if (inode->i_sb->s_pnfs_op &&
-	    !inode->i_sb->s_pnfs_op->layout_type) {
+	    (!inode->i_sb->s_pnfs_op->layout_type ||
+	     !inode->i_sb->s_pnfs_op->get_device_info)) {
 		dprintk("exp_export: export of invalid fs pnfs export ops.\n");
 		return -EINVAL;
 	}
diff --git a/fs/nfsd/nfs4pnfsd.c b/fs/nfsd/nfs4pnfsd.c
index 9a7cbc9..d219e42 100644
--- a/fs/nfsd/nfs4pnfsd.c
+++ b/fs/nfsd/nfs4pnfsd.c
@@ -118,7 +118,29 @@ struct sbid_tracker {
 	return id;
 }
 
-static u64
+struct super_block *
+find_sbid_id(u64 id)
+{
+	struct sbid_tracker *sbid;
+	struct super_block *sb = NULL;
+	unsigned long hash_idx = id & SBID_HASH_MASK;
+	int pos = 0;
+
+	spin_lock(&layout_lock);
+	list_for_each_entry (sbid, &sbid_hashtbl[hash_idx], hash) {
+		pos++;
+		if (sbid->id != id)
+			continue;
+		if (pos > 1)
+			list_move(&sbid->hash, &sbid_hashtbl[hash_idx]);
+		sb = sbid->sb;
+		break;
+	}
+	spin_unlock(&layout_lock);
+	return sb;
+}
+
+u64
 find_create_sbid(struct super_block *sb)
 {
 	struct sbid_tracker *sbid;
@@ -131,10 +153,8 @@ struct sbid_tracker {
 		pos++;
 		if (sbid->sb != sb)
 			continue;
-		if (pos > 1) {
-			list_del(&sbid->hash);
-			list_add(&sbid->hash, &sbid_hashtbl[hash_idx]);
-		}
+		if (pos > 1)
+			list_move(&sbid->hash, &sbid_hashtbl[hash_idx]);
 		id = sbid->id;
 		break;
 	}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 576b635..feea3a9 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1146,6 +1146,87 @@ static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
 out:
 	return status;
 }
+
+static __be32
+nfsd4_getdevlist(struct svc_rqst *rqstp,
+		struct nfsd4_compound_state *cstate,
+		struct nfsd4_pnfs_getdevlist *gdlp)
+{
+	struct super_block *sb;
+	struct svc_fh *current_fh = &cstate->current_fh;
+	int status;
+
+	dprintk("%s: type %u maxdevices %u cookie %llu verf %llu\n",
+		__func__, gdlp->gd_layout_type, gdlp->gd_maxdevices,
+		gdlp->gd_cookie, gdlp->gd_verf);
+
+
+	status = fh_verify(rqstp, current_fh, 0, NFSD_MAY_NOP);
+	if (status)
+		goto out;
+
+	status = nfserr_inval;
+	sb = current_fh->fh_dentry->d_inode->i_sb;
+	if (!sb)
+		goto out;
+
+	/* We must be able to encode at list one device */
+	if (!gdlp->gd_maxdevices)
+		goto out;
+
+	/* Ensure underlying file system supports pNFS and,
+	 * if so, the requested layout type
+	 */
+	status = nfsd4_layout_verify(sb, current_fh->fh_export,
+				     gdlp->gd_layout_type);
+	if (status)
+		goto out;
+
+	/* Do nothing if underlying file system does not support
+	 * getdevicelist */
+	if (!sb->s_pnfs_op->get_device_iter) {
+		status = nfserr_notsupp;
+		goto out;
+	}
+
+	/* Set up arguments so device can be retrieved at encode time */
+	gdlp->gd_fhp = &cstate->current_fh;
+out:
+	return status;
+}
+
+static __be32
+nfsd4_getdevinfo(struct svc_rqst *rqstp,
+		struct nfsd4_compound_state *cstate,
+		struct nfsd4_pnfs_getdevinfo *gdp)
+{
+	struct super_block *sb;
+	int status;
+
+	dprintk("%s: layout_type %u dev_id %llx:%llx maxcnt %u\n",
+	       __func__, gdp->gd_layout_type, gdp->gd_devid.sbid,
+	       gdp->gd_devid.devid, gdp->gd_maxcount);
+
+	status = nfserr_inval;
+	sb = find_sbid_id(gdp->gd_devid.sbid);
+	dprintk("%s: sb %p\n", __func__, sb);
+	if (!sb) {
+		status = nfserr_noent;
+		goto out;
+	}
+
+	/* Ensure underlying file system supports pNFS and,
+	 * if so, the requested layout type
+	 */
+	status = nfsd4_layout_verify(sb, NULL, gdp->gd_layout_type);
+	if (status)
+		goto out;
+
+	/* Set up arguments so device can be retrieved at encode time */
+	gdp->gd_sb = sb;
+out:
+	return status;
+}
 #endif /* CONFIG_PNFSD */
 
 /*
@@ -1879,6 +1960,17 @@ static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd
 		.op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
 		.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
 	},
+#if defined(CONFIG_PNFSD)
+	[OP_GETDEVICELIST] = {
+		.op_func = (nfsd4op_func)nfsd4_getdevlist,
+		.op_name = "OP_GETDEVICELIST",
+	},
+	[OP_GETDEVICEINFO] = {
+		.op_func = (nfsd4op_func)nfsd4_getdevinfo,
+		.op_flags = ALLOWED_WITHOUT_FH,
+		.op_name = "OP_GETDEVICEINFO",
+	},
+#endif /* CONFIG_PNFSD */
 };
 
 #ifdef NFSD_DEBUG
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index d9454fe..a761514 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -46,6 +46,7 @@
 #include <linux/utsname.h>
 #include <linux/pagemap.h>
 #include <linux/sunrpc/svcauth_gss.h>
+#include <linux/exportfs.h>
 
 #include "idmap.h"
 #include "acl.h"
@@ -54,6 +55,7 @@
 #include "state.h"
 #include "cache.h"
 #include "netns.h"
+#include "pnfsd.h"
 
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
 #include <linux/security.h>
@@ -1484,6 +1486,42 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
 	DECODE_TAIL;
 }
 
+#if defined(CONFIG_PNFSD)
+static __be32
+nfsd4_decode_getdevlist(struct nfsd4_compoundargs *argp,
+			struct nfsd4_pnfs_getdevlist *gdevl)
+{
+	DECODE_HEAD;
+
+	READ_BUF(16 + sizeof(nfs4_verifier));
+	READ32(gdevl->gd_layout_type);
+	READ32(gdevl->gd_maxdevices);
+	READ64(gdevl->gd_cookie);
+	COPYMEM(&gdevl->gd_verf, sizeof(nfs4_verifier));
+
+	DECODE_TAIL;
+}
+
+static __be32
+nfsd4_decode_getdevinfo(struct nfsd4_compoundargs *argp,
+			struct nfsd4_pnfs_getdevinfo *gdev)
+{
+	u32 num;
+	DECODE_HEAD;
+
+	READ_BUF(12 + sizeof(struct nfsd4_pnfs_deviceid));
+	READ64(gdev->gd_devid.sbid);
+	READ64(gdev->gd_devid.devid);
+	READ32(gdev->gd_layout_type);
+	READ32(gdev->gd_maxcount);
+	READ32(num);
+	if (num)
+		READ_BUF(4); /* TODO: for now, just skip notify_types */
+
+	DECODE_TAIL;
+}
+#endif /* CONFIG_PNFSD */
+
 static __be32
 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
 {
@@ -1585,11 +1623,19 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
 	[OP_DESTROY_SESSION]	= (nfsd4_dec)nfsd4_decode_destroy_session,
 	[OP_FREE_STATEID]	= (nfsd4_dec)nfsd4_decode_free_stateid,
 	[OP_GET_DIR_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
+#if defined(CONFIG_PNFSD)
+	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_getdevinfo,
+	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_getdevlist,
+	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_notsupp,
+	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_notsupp,
+	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_notsupp,
+#else  /* CONFIG_PNFSD */
 	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_notsupp,
 	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
 	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_notsupp,
 	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_notsupp,
 	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_notsupp,
+#endif /* CONFIG_PNFSD */
 	[OP_SECINFO_NO_NAME]	= (nfsd4_dec)nfsd4_decode_secinfo_no_name,
 	[OP_SEQUENCE]		= (nfsd4_dec)nfsd4_decode_sequence,
 	[OP_SET_SSV]		= (nfsd4_dec)nfsd4_decode_notsupp,
@@ -3519,6 +3565,209 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
 	return nfserr;
 }
 
+#if defined(CONFIG_PNFSD)
+
+/* Uses the export interface to iterate through the available devices
+ * and encodes them on the response stream.
+ */
+static  __be32
+nfsd4_encode_devlist_iterator(struct nfsd4_compoundres *resp,
+			      struct nfsd4_pnfs_getdevlist *gdevl,
+			      unsigned int *dev_count)
+{
+	struct super_block *sb = gdevl->gd_fhp->fh_dentry->d_inode->i_sb;
+	__be32 nfserr;
+	int status;
+	__be32 *p;
+	struct nfsd4_pnfs_dev_iter_res res = {
+		.gd_cookie = gdevl->gd_cookie,
+		.gd_verf = gdevl->gd_verf,
+		.gd_eof = 0
+	};
+	u64 sbid;
+
+	dprintk("%s: Begin\n", __func__);
+
+	sbid = find_create_sbid(sb);
+	*dev_count = 0;
+	do {
+		status = sb->s_pnfs_op->get_device_iter(sb,
+							gdevl->gd_layout_type,
+							&res);
+		if (status) {
+			if (status == -ENOENT) {
+				res.gd_eof = 1;
+				/* return success */
+				break;
+			}
+			nfserr = nfserrno(status);
+			goto out_err;
+		}
+
+		/* Encode device id and layout type */
+		RESERVE_SPACE(sizeof(struct nfsd4_pnfs_deviceid));
+		WRITE64(sbid);
+		WRITE64(res.gd_devid);	/* devid minor */
+		ADJUST_ARGS();
+		(*dev_count)++;
+	} while (*dev_count < gdevl->gd_maxdevices && !res.gd_eof);
+	gdevl->gd_cookie = res.gd_cookie;
+	gdevl->gd_verf = res.gd_verf;
+	gdevl->gd_eof = res.gd_eof;
+	nfserr = nfs_ok;
+out_err:
+	dprintk("%s: Encoded %u devices\n", __func__, *dev_count);
+	return nfserr;
+}
+
+/* Encodes the response of get device list.
+*/
+static __be32
+nfsd4_encode_getdevlist(struct nfsd4_compoundres *resp, __be32 nfserr,
+			struct nfsd4_pnfs_getdevlist *gdevl)
+{
+	unsigned int dev_count = 0, lead_count;
+	u32 *p_in = resp->p;
+	__be32 *p;
+
+	dprintk("%s: err %d\n", __func__, nfserr);
+	if (nfserr)
+		return nfserr;
+
+	/* Ensure we have room for cookie, verifier, and devlist len,
+	 * which we will backfill in after we encode as many devices as possible
+	 */
+	lead_count = 8 + sizeof(nfs4_verifier) + 4;
+	RESERVE_SPACE(lead_count);
+	/* skip past these values */
+	p += XDR_QUADLEN(lead_count);
+	ADJUST_ARGS();
+
+	/* Iterate over as many device ids as possible on the xdr stream */
+	nfserr = nfsd4_encode_devlist_iterator(resp, gdevl, &dev_count);
+	if (nfserr)
+		goto out_err;
+
+	/* Backfill in cookie, verf and number of devices encoded */
+	p = p_in;
+	WRITE64(gdevl->gd_cookie);
+	WRITEMEM(&gdevl->gd_verf, sizeof(nfs4_verifier));
+	WRITE32(dev_count);
+
+	/* Skip over devices */
+	p += XDR_QUADLEN(dev_count * sizeof(struct nfsd4_pnfs_deviceid));
+	ADJUST_ARGS();
+
+	/* are we at the end of devices? */
+	RESERVE_SPACE(4);
+	WRITE32(gdevl->gd_eof);
+	ADJUST_ARGS();
+
+	dprintk("%s: done.\n", __func__);
+
+	nfserr = nfs_ok;
+out:
+	return nfserr;
+out_err:
+	p = p_in;
+	ADJUST_ARGS();
+	goto out;
+}
+
+/* For a given device id, have the file system retrieve and encode the
+ * associated device.  For file layout, the encoding function is
+ * passed down to the file system.  The file system then has the option
+ * of using this encoding function or one of its own.
+ *
+ * Note: the file system must return the XDR size of struct device_addr4
+ * da_addr_body in pnfs_xdr_info.bytes_written on NFS4ERR_TOOSMALL for the
+ * gdir_mincount calculation.
+ */
+static __be32
+nfsd4_encode_getdevinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
+			struct nfsd4_pnfs_getdevinfo *gdev)
+{
+	struct super_block *sb;
+	int maxcount = 0, type_notify_len = 12;
+	__be32 *p, *p_save = NULL, *p_in = resp->p;
+	struct exp_xdr_stream xdr;
+
+	dprintk("%s: err %d\n", __func__, nfserr);
+	if (nfserr)
+		return nfserr;
+
+	sb = gdev->gd_sb;
+
+	if (gdev->gd_maxcount != 0) {
+		/* FIXME: this will be bound by the session max response */
+		maxcount = svc_max_payload(resp->rqstp);
+		if (maxcount > gdev->gd_maxcount)
+			maxcount = gdev->gd_maxcount;
+
+		/* Ensure have room for type and notify field */
+		maxcount -= type_notify_len;
+		if (maxcount < 0) {
+			nfserr = -ETOOSMALL;
+			goto toosmall;
+		}
+	}
+
+	RESERVE_SPACE(4);
+	WRITE32(gdev->gd_layout_type);
+	ADJUST_ARGS();
+
+	/* If maxcount is 0 then just update notifications */
+	if (gdev->gd_maxcount == 0)
+		goto handle_notifications;
+
+	xdr.p = p_save = resp->p;
+	xdr.end = resp->end;
+	if (xdr.end - xdr.p > exp_xdr_qwords(maxcount & ~3))
+		xdr.end = xdr.p + exp_xdr_qwords(maxcount & ~3);
+
+	nfserr = sb->s_pnfs_op->get_device_info(sb, &xdr, gdev->gd_layout_type,
+						&gdev->gd_devid);
+	if (nfserr) {
+		/* Rewind to the beginning */
+		p = p_in;
+		ADJUST_ARGS();
+		if (nfserr == -ETOOSMALL)
+			goto toosmall;
+		printk(KERN_ERR "%s: export ERROR %d\n", __func__, nfserr);
+		goto out;
+	}
+
+	/* The file system should never write 0 bytes without
+	 * returning an error
+	 */
+	BUG_ON(xdr.p == p_save);
+	BUG_ON(xdr.p > xdr.end);
+
+	/* Update the xdr stream with the number of bytes encoded
+	 * by the file system.
+	 */
+	p = xdr.p;
+	ADJUST_ARGS();
+
+handle_notifications:
+	/* Encode supported device notifications.
+	 * Note: Currently none are supported.
+	 */
+	RESERVE_SPACE(4);
+	WRITE32(0);
+	ADJUST_ARGS();
+
+out:
+	return nfserrno(nfserr);
+toosmall:
+	dprintk("%s: maxcount too small\n", __func__);
+	RESERVE_SPACE(4);
+	WRITE32((p_save ? (xdr.p - p_save) * 4 : 0) + type_notify_len);
+	ADJUST_ARGS();
+	goto out;
+}
+#endif /* CONFIG_PNFSD */
+
 static __be32
 nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
 {
@@ -3579,11 +3828,19 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
 	[OP_DESTROY_SESSION]	= (nfsd4_enc)nfsd4_encode_destroy_session,
 	[OP_FREE_STATEID]	= (nfsd4_enc)nfsd4_encode_free_stateid,
 	[OP_GET_DIR_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
+#if defined(CONFIG_PNFSD)
+	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_getdevinfo,
+	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_getdevlist,
+	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_noop,
+	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_noop,
+	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
+#else  /* CONFIG_PNFSD */
 	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_noop,
 	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
 	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_noop,
 	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_noop,
 	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
+#endif /* CONFIG_PNFSD */
 	[OP_SECINFO_NO_NAME]	= (nfsd4_enc)nfsd4_encode_secinfo_no_name,
 	[OP_SEQUENCE]		= (nfsd4_enc)nfsd4_encode_sequence,
 	[OP_SET_SSV]		= (nfsd4_enc)nfsd4_encode_noop,
diff --git a/fs/nfsd/pnfsd.h b/fs/nfsd/pnfsd.h
index 29ea2e7..cfcfc9a 100644
--- a/fs/nfsd/pnfsd.h
+++ b/fs/nfsd/pnfsd.h
@@ -38,4 +38,7 @@
 
 #include "xdr4.h"
 
+u64 find_create_sbid(struct super_block *);
+struct super_block *find_sbid_id(u64);
+
 #endif /* LINUX_NFSD_PNFSD_H */
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index b3ed644..faf37bc 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -37,6 +37,8 @@
 #ifndef _LINUX_NFSD_XDR4_H
 #define _LINUX_NFSD_XDR4_H
 
+#include <linux/nfsd/nfsd4_pnfs.h>
+
 #include "state.h"
 #include "nfsd.h"
 
@@ -430,6 +432,22 @@ struct nfsd4_reclaim_complete {
 	u32 rca_one_fs;
 };
 
+struct nfsd4_pnfs_getdevinfo {
+	struct nfsd4_pnfs_deviceid gd_devid;	/* request */
+	u32			gd_layout_type;	/* request */
+	u32			gd_maxcount;	/* request */
+	struct super_block	*gd_sb;
+};
+
+struct nfsd4_pnfs_getdevlist {
+	u32             gd_layout_type;	/* request */
+	u32		gd_maxdevices;	/* request */
+	u64		gd_cookie;	/* request - response */
+	u64		gd_verf;	/* request - response */
+	struct svc_fh	*gd_fhp;	/* response */
+	u32		gd_eof;		/* response */
+};
+
 struct nfsd4_op {
 	int					opnum;
 	__be32					status;
@@ -475,6 +493,10 @@ struct nfsd4_op {
 		struct nfsd4_reclaim_complete	reclaim_complete;
 		struct nfsd4_test_stateid	test_stateid;
 		struct nfsd4_free_stateid	free_stateid;
+#if defined(CONFIG_PNFSD)
+		struct nfsd4_pnfs_getdevlist	pnfs_getdevlist;
+		struct nfsd4_pnfs_getdevinfo	pnfs_getdevinfo;
+#endif /* CONFIG_PNFSD */
 	} u;
 	struct nfs4_replay *			replay;
 };
diff --git a/include/linux/nfsd/nfsd4_pnfs.h b/include/linux/nfsd/nfsd4_pnfs.h
index d44669e..53a0bb7 100644
--- a/include/linux/nfsd/nfsd4_pnfs.h
+++ b/include/linux/nfsd/nfsd4_pnfs.h
@@ -35,6 +35,19 @@
 #define _LINUX_NFSD_NFSD4_PNFS_H
 
 #include <linux/exportfs.h>
+#include <linux/exp_xdr.h>
+
+struct nfsd4_pnfs_deviceid {
+	u64	sbid;			/* per-superblock unique ID */
+	u64	devid;			/* filesystem-wide unique device ID */
+};
+
+struct nfsd4_pnfs_dev_iter_res {
+	u64		gd_cookie;	/* request/repsonse */
+	u64		gd_verf;	/* request/repsonse */
+	u64		gd_devid;	/* response */
+	u32		gd_eof;		/* response */
+};
 
 /*
  * pNFS export operations vector.
@@ -49,6 +62,25 @@
 struct pnfs_export_operations {
 	/* Returns the supported pnfs_layouttype4. */
 	int (*layout_type) (struct super_block *);
+
+	/* Encode device info onto the xdr stream. */
+	int (*get_device_info) (struct super_block *,
+				struct exp_xdr_stream *,
+				u32 layout_type,
+				const struct nfsd4_pnfs_deviceid *);
+
+	/* Retrieve all available devices via an iterator.
+	 * arg->cookie == 0 indicates the beginning of the list,
+	 * otherwise arg->verf is used to verify that the list hasn't changed
+	 * while retrieved.
+	 *
+	 * On output, the filesystem sets the devid based on the current cookie
+	 * and sets res->cookie and res->verf corresponding to the next entry.
+	 * When the last entry in the list is retrieved, res->eof is set to 1.
+	 */
+	int (*get_device_iter) (struct super_block *,
+				u32 layout_type,
+				struct nfsd4_pnfs_dev_iter_res *);
 };
 
 #endif /* _LINUX_NFSD_NFSD4_PNFS_H */
-- 
1.8.3.1


  parent reply	other threads:[~2013-09-26 18:40 UTC|newest]

Thread overview: 141+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-26 18:36 [PATCH RFC v0 0/49] pnfsd-dlm Benny Halevy
2013-09-26 18:39 ` [PATCH RFC v0 01/49] pnfsd: Define CONFIG_PNFSD Benny Halevy
2013-09-26 18:39 ` [PATCH RFC v0 02/49] pnfsd: define NFSDDBG_PNFS Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 03/49] pnfsd: return pnfs flags on exchange_id Benny Halevy
2013-09-26 21:55   ` J. Bruce Fields
2013-09-27  1:09     ` Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 04/49] pnfsd: don't set up back channel on create_session for ds Benny Halevy
2013-09-26 22:01   ` J. Bruce Fields
2013-09-27  1:20     ` Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 05/49] pnfsd: introduce pnfsd header files Benny Halevy
2013-09-29 11:43   ` Christoph Hellwig
2013-09-29 12:12     ` Benny Halevy
2013-09-29 12:13       ` Christoph Hellwig
2013-09-29 12:20         ` Benny Halevy
2013-09-29 12:21           ` Christoph Hellwig
2013-09-29 12:35             ` Christoph Hellwig
2013-09-30 15:23               ` Benny Halevy
2013-10-01 13:19                 ` Christoph Hellwig
2013-10-01  1:05               ` Boaz Harrosh
2013-10-01 13:33                 ` Christoph Hellwig
2013-10-02 11:35                   ` Benny Halevy
2013-10-02 16:06                     ` Christoph Hellwig
2013-10-01 20:30               ` J. Bruce Fields
2013-10-02 11:36                 ` Benny Halevy
2013-10-02 16:07                   ` Christoph Hellwig
2013-10-03  6:02                     ` Benny Halevy
2013-10-03  9:55                       ` Christoph Hellwig
2013-10-03 12:29                         ` Benny Halevy
2013-10-03 12:37                           ` Christoph Hellwig
2013-10-03 13:12                           ` Ric Wheeler
2013-10-03 13:17                             ` Christoph Hellwig
2013-10-03 13:18                               ` Ric Wheeler
2013-10-03 14:19                                 ` Benny Halevy
2013-10-03 14:21                                   ` Christoph Hellwig
2013-10-03 14:24                                     ` Ric Wheeler
2013-10-03 14:38                                       ` Benny Halevy
2013-10-01  1:41           ` Boaz Harrosh
2013-10-01 19:43           ` J. Bruce Fields
2013-09-26 18:40 ` [PATCH RFC v0 06/49] pnfsd: define pnfs_export_operations Benny Halevy
2013-09-27 14:39   ` J. Bruce Fields
2013-09-29 10:53     ` Benny Halevy
2013-09-29 12:14   ` Christoph Hellwig
2013-09-26 18:40 ` [PATCH RFC v0 07/49] pnfsd: add pnfs export option Benny Halevy
2013-09-27 14:36   ` J. Bruce Fields
2013-09-29 10:51     ` Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 08/49] pnfsd: layout verify Benny Halevy
2013-09-27 14:44   ` J. Bruce Fields
2013-09-29 11:16     ` Benny Halevy
2013-10-01 20:38       ` J. Bruce Fields
2013-10-02 11:42         ` Benny Halevy
2013-10-01 22:12       ` J. Bruce Fields
2013-09-26 18:40 ` [PATCH RFC v0 09/49] pnfsd: initial stub Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 10/49] pnfsd: use sbid hash table to map super_blocks to devid major identifiers Benny Halevy
2013-10-01 22:14   ` J. Bruce Fields
2013-10-02 14:32     ` Benny Halevy
2013-10-02 15:24       ` J. Bruce Fields
2013-10-11 19:56   ` Christoph Hellwig
2013-10-13  6:11     ` Benny Halevy
2013-10-13 11:08       ` Christoph Hellwig
2013-10-13 12:44         ` Benny Halevy
2013-10-14 14:15           ` Christoph Hellwig
2013-09-26 18:40 ` [PATCH RFC v0 11/49] NFSD: introduce exp_xdr.h Benny Halevy
2013-09-29 12:15   ` Christoph Hellwig
2013-09-30 15:25     ` Benny Halevy
2013-09-26 18:40 ` Benny Halevy [this message]
2013-09-26 18:40 ` [PATCH RFC v0 13/49] pnfsd: filelayout: get device list/info Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 14/49] pnfsd: provide helper for xdr encoding of deviceid Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 15/49] pnfsd: add helper functions for identifying DS filehandles Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 16/49] pnfsd: accept all ds stateids Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 17/49] DEBUG: nfsd: more client_lock asserts Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 18/49] pnfsd: nfs4_assert_state_locked Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 19/49] pnfsd: layout get Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 20/49] pnfsd: filelayout: layout encoding Benny Halevy
2013-09-29 12:16   ` Christoph Hellwig
2013-10-01  1:15     ` Boaz Harrosh
2013-10-01 13:34       ` Christoph Hellwig
2013-10-01  6:04     ` Benny Halevy
2013-10-02 14:27     ` Benny Halevy
2013-10-02 16:09       ` Christoph Hellwig
2013-09-26 18:41 ` [PATCH RFC v0 21/49] nfsd: no need to unhash_stid before free Benny Halevy
2013-10-11 19:37   ` Christoph Hellwig
2013-10-13  6:23     ` Benny Halevy
2013-10-13 19:28       ` J. Bruce Fields
2013-09-26 18:41 ` [PATCH RFC v0 22/49] nfsd: cleanup free_stid Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 23/49] pnfsd: layout state allocation Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 24/49] pnfsd: process the layout stateid Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 25/49] pnfsd: layout state per client tracking Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 26/49] pnfsd: layout state per file tracking Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 27/49] pnfsd: hash layouts on layout state Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 28/49] pnfsd: support layout segment merging Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 29/49] pnfsd: support layout_type attribute Benny Halevy
2013-09-29 12:17   ` Christoph Hellwig
2013-10-01  1:21     ` Boaz Harrosh
2013-10-01  8:32       ` Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 30/49] pnfsd: make pnfs server return layout_blksize when the client asks for it Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 31/49] pnfsd: add support for per-file layout_types attribute Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 32/49] pnfsd: per block device dlm data server list cache Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 33/49] pnfsd: Add IP address validation to nfsd4_set_pnfs_dlm_device() Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 34/49] pnfsd: new nfsd filesystem file: pnfs_dlm_device Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 35/49] pnfsd: nfsd4_pnfs_dlm_getdeviter Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 36/49] pnfsd: nfsd4_pnfs_dlm_getdevinfo Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 37/49] pnfsd: make /proc/fs/nfsd/pnfs_dlm_device report dlm device list Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 38/49] pnfsd: nfsd4_pnfs_dlm_layoutget Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 39/49] pnfsd: DLM file layout only support read iomode layouts Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 40/49] pnfsd: add dlm file layout layout-type Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 41/49] pnfsd: dlm pnfs_export_operations Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 42/49] pnfsd: gfs2: use generic file layout pnfs operations vector Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 43/49] pnfsd: release state lock around iput in put_nfs4_file Benny Halevy
2013-09-29 12:19   ` Christoph Hellwig
2013-10-01 13:31     ` Benny Halevy
2013-10-01 13:37       ` Christoph Hellwig
2013-10-02 14:17         ` Benny Halevy
2013-10-02 15:26         ` J. Bruce Fields
2013-10-11 19:47   ` Christoph Hellwig
2013-10-13  6:26     ` Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 44/49] posix_acl: resolve compile dependency in posix_acl.h Benny Halevy
2013-09-29 12:19   ` Christoph Hellwig
2013-10-02 14:17     ` Benny Halevy
     [not found]   ` <1380220974-14716-1-git-send-email-bhalevy-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2013-10-02 14:36     ` [PATCH] " Benny Halevy
2013-10-02 14:36       ` Benny Halevy
2013-10-09 22:41       ` Andrew Morton
     [not found]         ` <20131009154109.13c7248c53b97d96194ca8f9-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
2013-10-10  8:49           ` Benny Halevy
2013-10-10  8:49             ` Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 45/49] nfs: resolve compile dependency in nfs_xdr.h Benny Halevy
2013-09-29 12:19   ` Christoph Hellwig
2013-10-02 14:19     ` Benny Halevy
2013-09-26 18:43 ` [PATCH RFC v0 46/49] pnfsd: layout return generic implementation Benny Halevy
2013-09-26 18:43 ` [PATCH RFC v0 47/49] pnfsd: pnfs_expire_client Benny Halevy
2013-09-26 18:43 ` [PATCH RFC v0 48/49] pnfsd: return on close Benny Halevy
2013-09-26 18:43 ` [PATCH RFC v0 49/49] pnfsd: dlm set return_on_close to true Benny Halevy
2013-09-26 19:44 ` [PATCH RFC v0 0/49] pnfsd-dlm J. Bruce Fields
2013-09-26 20:06   ` Benny Halevy
2013-09-27 13:31 ` Boaz Harrosh
2013-09-27 13:34   ` Benny Halevy
2013-09-27 16:37     ` Boaz Harrosh
2013-09-27 20:19       ` Benny Halevy
2013-10-01  0:23         ` Boaz Harrosh
2013-10-01  0:29           ` Boaz Harrosh
2013-10-02  6:02           ` Benny Halevy
2013-09-29 11:42 ` Christoph Hellwig
2013-09-29 11:54   ` Benny Halevy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1380220838-13228-1-git-send-email-bhalevy@primarydata.com \
    --to=bhalevy@primarydata.com \
    --cc=bfields@redhat.com \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.