[pnfs] [PATCH] pnfs: Notify device ID changes

Marc Eshel eshel at almaden.ibm.com
Wed May 21 15:10:28 EDT 2008


From: Marc Eshel <eshel at almaden.ibm.com>
Signed-off-by: Marc Eshel <eshel at almaden.ibm.com>


---

 fs/nfs/callback.h      |    9 +++++++++
 fs/nfs/callback_proc.c |   30 ++++++++++++++++++++++++++++++
 fs/nfs/callback_xdr.c  |   42 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 80 insertions(+), 1 deletions(-)

diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index 15baf2a..c2e3b22 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -83,6 +83,13 @@ struct cb_pnfs_layoutrecallargs {
 	uint32_t		cbl_layoutchanged;
 	nfs4_stateid		cbl_stateid;
 };
+struct cb_pnfs_devicenotifyargs {
+	struct sockaddr		*cbd_addr;
+	uint32_t		cbd_notify_type;
+	uint32_t		cbd_layout_type;
+	struct pnfs_deviceid    cbd_dev_id;
+	uint32_t		cbd_immediate;
+};
 #endif /* CONFIG_PNFS */
 
 struct referring_call {
@@ -140,6 +147,8 @@ extern void nfs_callback_down(void);
 #if defined(CONFIG_PNFS)
 extern unsigned pnfs_cb_layoutrecall(struct cb_pnfs_layoutrecallargs *args,
 				     void *dummy);
+extern unsigned pnfs_cb_devicenotify(struct cb_pnfs_devicenotifyargs *args,
+				     void *dummy);
 #endif /* CONFIG_PNFS */
 extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
 				       struct cb_sequenceres *res);
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 79e161a..ba7fea1 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -299,6 +299,36 @@ out:
 	return res;
 }
 
+unsigned pnfs_cb_devicenotify(struct cb_pnfs_devicenotifyargs *args,
+			      void *dummy)
+{
+	struct nfs_server *server;
+	struct nfs_client *clp;
+	unsigned res;
+
+	res = htonl(NFS4ERR_INVAL);
+	clp = nfs_find_client(args->cbd_addr, 4);
+	if (clp == NULL) {
+		dprintk("%s: no client for addr %u.%u.%u.%u\n",
+			__func__, NIPQUAD(args->cbd_addr));
+		goto out;
+	}
+
+	/* ??? fix me, until we have a way to find dev_id */
+	list_for_each_entry(server, &clp->cl_superblocks, client_link)
+		if (server->pnfs_curr_ld &&
+			server->pnfs_curr_ld->ld_io_ops &&
+			server->pnfs_curr_ld->ld_io_ops->uninitialize_mountpoint)
+				server->pnfs_curr_ld->ld_io_ops->uninitialize_mountpoint(
+					server->pnfs_mountid);
+
+	res = 0;
+	nfs_put_client(clp);
+out:
+	dprintk("%s: exit with status = %d\n", __func__, ntohl(res));
+	return res;
+}
+
 #endif /* defined(CONFIG_PNFS) */
 
 #if defined(CONFIG_NFS_V4_1)
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 08764c4..9ae8742 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -22,6 +22,7 @@
 
 #if defined(CONFIG_PNFS)
 #define CB_OP_LAYOUTRECALL_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ)
+#define CB_OP_DEVICENOTIFY_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ)
 #endif /* CONFIG_PNFS */
 
 #if defined(CONFIG_NFS_V4_1)
@@ -281,6 +282,39 @@ out:
 	return status;
 }
 
+static unsigned decode_pnfs_devicenotify_args(struct svc_rqst *rqstp,
+					struct xdr_stream *xdr,
+					struct cb_pnfs_devicenotifyargs *args)
+{
+	uint32_t *p;
+	unsigned status = 0;
+
+	args->cbd_addr = svc_addr(rqstp);
+	p = read_buf(xdr, 3 * sizeof(uint32_t) + NFS4_PNFS_DEVICEID4_SIZE);
+	if (unlikely(p == NULL)) {
+		status = htonl(NFS4ERR_RESOURCE);
+		goto out;
+	}
+
+	args->cbd_notify_type = ntohl(*p++);
+	args->cbd_layout_type = ntohl(*p++);
+
+	COPYMEM(args->cbd_dev_id.data, NFS4_PNFS_DEVICEID4_SIZE);
+
+	if (args->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) {
+		args->cbd_immediate =  ntohl(*p++);
+	}
+        else
+        	args->cbd_immediate = 0;
+
+	dprintk("%s: type %d layout %d immediate %d\n",
+		__func__, args->cbd_notify_type, args->cbd_layout_type,
+		args->cbd_immediate);
+out:
+	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
+	return status;
+}
+
 #endif /* CONFIG_PNFS */
 
 #if defined(CONFIG_NFS_V4_1)
@@ -628,6 +662,7 @@ process_op:
 			break;
 
 		case OP_CB_LAYOUTRECALL:
+		case OP_CB_NOTIFY_DEVICEID:
 #if defined(CONFIG_PNFS)
 			goto process_op;
 #else
@@ -640,7 +675,6 @@ process_op:
 		case OP_CB_RECALL_SLOT:
 		case OP_CB_WANTS_CANCELLED:
 		case OP_CB_NOTIFY_LOCK:
-		case OP_CB_NOTIFY_DEVICEID:
 			op = &callback_ops[0];
 			status = htonl(NFS4ERR_NOTSUPP);
 			break;
@@ -750,6 +784,12 @@ static struct callback_op callback_ops[] = {
 			(callback_decode_arg_t)decode_pnfs_layoutrecall_args,
 		.res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ,
 	},
+	[OP_CB_NOTIFY_DEVICEID] = {
+		.process_op = (callback_process_op_t)pnfs_cb_devicenotify,
+		.decode_args =
+			(callback_decode_arg_t)decode_pnfs_devicenotify_args,
+		.res_maxsize = CB_OP_DEVICENOTIFY_RES_MAXSZ,
+	},
 #endif /* CONFIG_PNFS */
 #if defined(CONFIG_NFS_V4_1)
 	[OP_CB_SEQUENCE] = {


More information about the pNFS mailing list