[pnfs] [PATCH 17/23] 2.6-latest pnfs client layoutreturn

andros at umich.edu andros at umich.edu
Thu Dec 13 15:51:43 EST 2007


From: Andy Adamson <andros at umich.edu>

Implement the layoutreturn operation.

Signed-off by: Andy Adamson<andros at umich.edu>
---
 fs/nfs/inode.c     |    3 ++
 fs/nfs/nfs4proc.c  |   20 +++++++++--
 fs/nfs/nfs4state.c |   21 ++++++++++++-
 fs/nfs/nfs4xdr.c   |   88 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 126 insertions(+), 6 deletions(-)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b7beb0f..2eb53c5 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1140,6 +1140,9 @@ void nfs4_clear_inode(struct inode *inode)
 	nfs_inode_return_delegation(inode);
 	/* First call standard NFS clear_inode() code */
 	nfs_clear_inode(inode);
+#ifdef CONFIG_PNFS
+	pnfs_return_layout(inode, NULL);
+#endif /* CONFIG_PNFS */
 }
 #endif
 
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c6d1bbd..e3b0f4a 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5012,10 +5012,22 @@ static int pnfs_proc_layoutcommit(struct pnfs_layoutcommit_data *data)
 	return -1;
 }
 
-static int nfs4_proc_pnfs_layoutreturn(struct nfs4_pnfs_layoutreturn* layout)
+static int pnfs4_proc_layoutreturn(struct nfs4_pnfs_layoutreturn* layout)
 {
-	/* XXX Need to implement */
-	return -1;
+	struct inode* ino = layout->args->inode;
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PNFS_LAYOUTRETURN],
+		.rpc_argp = layout->args,
+		.rpc_resp = layout->res,
+	};
+	int status;
+	NFS4_VALIDATE_STATE(NFS_SERVER(ino));
+
+	status = NFS4_RPC_CALL_SYNC(NFS_SERVER(ino), NFS_CLIENT(ino), &msg,
+						layout->args, layout->res, 0);
+	dprintk("NFS reply layoutreturn: %d\n", status);
+
+	return status;
 }
 
 /*
@@ -5307,7 +5319,7 @@ const struct nfs_rpc_ops pnfs_v41_clientops = {
 	.pnfs_layoutget      = nfs4_proc_pnfs_layoutget,
 	.pnfs_layoutcommit_setup = nfs4_proc_pnfs_layoutcommit_setup,
 	.pnfs_layoutcommit       = pnfs_proc_layoutcommit,
-	.pnfs_layoutreturn       = nfs4_proc_pnfs_layoutreturn,
+	.pnfs_layoutreturn       = pnfs4_proc_layoutreturn,
 	.validate_sequence_args = nfs41_validate_seq_args,
 	.increment_open_seqid = nfs41_increment_open_seqid,
 	.increment_lock_seqid = nfs41_increment_lock_seqid,
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0623c71..c70983a 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -53,6 +53,11 @@
 #include "callback.h"
 #include "delegation.h"
 #include "internal.h"
+#ifdef CONFIG_PNFS
+#include <linux/pnfs_xdr.h>
+#include <linux/nfs4_pnfs.h>
+#include "pnfs.h"
+#endif /* CONFIG_PNFS */
 
 #define OPENOWNER_POOL_SIZE	8
 
@@ -481,12 +486,26 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mod
 	if (!call_close) {
 		nfs4_put_open_state(state);
 		nfs4_put_state_owner(owner);
-	} else
+	} else {
+#ifdef CONFIG_PNFS
+	struct nfs_inode *nfsi = NFS_I(state->inode);
+
+	if (nfsi->current_layout && nfsi->current_layout->roc_iomode) {
+		struct nfs4_pnfs_layout_segment range;
+
+		range.iomode = nfsi->current_layout->roc_iomode;
+		range.offset = 0;
+		range.length = NFS4_LENGTH_EOF;
+		pnfs_return_layout(state->inode, &range);
+	}
+#endif /* CONFIG_PNFS */
 		nfs4_do_close(path, state, wait);
+	}
 }
 
 void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
 {
+
 	__nfs4_close(path, state, mode, 0);
 }
 
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 556ac0a..51e1e93 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -279,6 +279,8 @@ static int nr_sequence_quads = 0;
 				   NFS4_PNFS_DEV_MAXSIZE)
 #define encode_pnfs_layoutget_sz (op_encode_hdr_maxsz + 13)
 #define decode_pnfs_layoutget_maxsz (op_decode_hdr_maxsz + 8)
+#define encode_pnfs_layoutreturn_sz	(8 + op_encode_hdr_maxsz)
+#define decode_pnfs_layoutreturn_maxsz	(op_decode_hdr_maxsz)
 #endif /* CONFIG_PNFS */
 
 #define NFS40_enc_compound_sz	(1024)  /* XXX: large enough? */
@@ -742,6 +744,14 @@ static int nr_sequence_quads = 0;
 				    decode_sequence_maxsz + \
                                     decode_putfh_maxsz +        \
                                     decode_pnfs_layoutget_maxsz)
+#define NFS41_enc_pnfs_layoutreturn_sz	(compound_encode_hdr_maxsz +    \
+					encode_sequence_maxsz +\
+					encode_putfh_maxsz +           \
+					encode_pnfs_layoutreturn_sz)
+#define NFS41_dec_pnfs_layoutreturn_sz	(compound_decode_hdr_maxsz +    \
+					decode_sequence_maxsz + \
+					decode_putfh_maxsz +           \
+					decode_pnfs_layoutreturn_maxsz)
 #endif /* CONFIG_PNFS */
 
 static struct {
@@ -1778,6 +1788,27 @@ static int encode_pnfs_layoutget(struct xdr_stream *xdr, const struct nfs4_pnfs_
                args->maxcount);
         return 0;
 }
+/*
+ * Encode request to return a pNFS layout.  Sent to the MDS
+ */
+static int encode_pnfs_layoutreturn(struct xdr_stream *xdr, const struct nfs4_pnfs_layoutreturn_arg *args)
+{
+	uint32_t *p;
+
+	RESERVE_SPACE(20);
+	WRITE32(OP_LAYOUTRETURN);
+	WRITE32(args->reclaim);
+	WRITE32(args->layout_type);
+	WRITE32(args->lseg.iomode);
+	WRITE32(args->return_type);
+	if (args->return_type == RETURN_FILE) {
+		RESERVE_SPACE(16);
+		WRITE64(args->lseg.offset);
+		WRITE64(args->lseg.length);
+	}
+	return 0;
+}
+
 #endif /* CONFIG_PNFS */
 
 /*
@@ -3438,6 +3469,28 @@ static int nfs41_xdr_enc_pnfs_layoutget(struct rpc_rqst *req, uint32_t *p, struc
         return status;
 }
 
+/*
+ * Encode LAYOUTRETURN request
+ */
+static int nfs41_xdr_enc_pnfs_layoutreturn(struct rpc_rqst *req, uint32_t *p, struct nfs4_pnfs_layoutreturn_arg *args)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr = {
+		.nops = 3,
+	};
+	int status;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_compound_hdr(&xdr, &hdr, 1);
+	encode_sequence(&xdr, &args->seq_args);
+	status = encode_putfh(&xdr, NFS_FH(args->inode));
+	if (status)
+		goto out;
+	status = encode_pnfs_layoutreturn(&xdr, args);
+out:
+	return status;
+}
+
 #endif /* CONFIG_PNFS */
 
 /*
@@ -5336,7 +5389,15 @@ static int decode_pnfs_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, s
         COPYMEM(res->layout.buf, res->layout.len);
         return 0;
 }
-#endif /* CONFIG_PNFS */
+/*
+ * Decode LAYOUTRETURN reply
+ */
+static int decode_pnfs_layoutreturn(struct xdr_stream *xdr)
+{
+	return decode_op_hdr(xdr, OP_LAYOUTRETURN);
+}
+
+ #endif /* CONFIG_PNFS */
 
 /*
  * Decode OPEN_DOWNGRADE response
@@ -7215,6 +7276,30 @@ out:
 
 }
 
+/*
+ * Decode LAYOUTRETURN response
+ */
+static int nfs41_xdr_dec_pnfs_layoutreturn(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_pnfs_layoutreturn_res *res)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_sequence(&xdr, &res->seq_res);
+	if (status)
+		goto out;
+	status = decode_putfh(&xdr);
+	if (status)
+		goto out;
+	status = decode_pnfs_layoutreturn(&xdr);
+out:
+	return status;
+}
+
 #endif /* CONFIG_PNFS */
 
 __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
@@ -7433,6 +7518,7 @@ struct rpc_procinfo	nfs41_procedures[] = {
   PROC(PNFS_GETDEVICELIST, enc_pnfs_getdevicelist, dec_pnfs_getdevicelist, 1),
   PROC(PNFS_GETDEVICEINFO, enc_pnfs_getdeviceinfo, dec_pnfs_getdeviceinfo, 1),
   PROC(PNFS_LAYOUTGET,	enc_pnfs_layoutget,	dec_pnfs_layoutget, 1),
+  PROC(PNFS_LAYOUTRETURN, enc_pnfs_layoutreturn,  dec_pnfs_layoutreturn, 1),
 #endif /* CONFIG_PNFS */
 };
 #endif
-- 
1.5.0.2



More information about the pNFS mailing list