[pnfs] [PATCH 17/20] 2.6-latest pnfs client layoutreturn
andros at umich.edu
andros at umich.edu
Wed Nov 28 16:33:18 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 | 18 +++++++++--
fs/nfs/nfs4state.c | 21 ++++++++++++-
fs/nfs/nfs4xdr.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 125 insertions(+), 5 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 7a17cbe..c710cc2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5016,8 +5016,20 @@ static int pnfs_proc_layoutcommit(struct pnfs_layoutcommit_data *data)
static int nfs4_proc_pnfs_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;
}
/*
@@ -5309,7 +5321,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