Create XDR and surrounding functions on the client for the LAYOUTRETURN command. --- linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4proc.c | 17 ++ linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4xdr.c | 78 +++++++++++- linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs4.h | 1 linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs_xdr.h | 1 linux-2.6.14-pnfs-current-dhildebz/include/linux/pnfs_xdr.h | 14 ++ 5 files changed, 101 insertions(+), 10 deletions(-) diff -puN fs/nfs/nfs4proc.c~client-layoutreturn fs/nfs/nfs4proc.c --- linux-2.6.14-pnfs-current/fs/nfs/nfs4proc.c~client-layoutreturn 2006-01-13 17:36:59.264620000 -0500 +++ linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4proc.c 2006-01-13 17:36:59.314570000 -0500 @@ -1496,6 +1496,16 @@ static int nfs4_proc_pnfs_layoutget(stru return nfs4_map_errors(rpc_call_sync(NFS_CLIENT(ino), &msg, 0)); } +static int nfs4_proc_pnfs_layoutreturn(struct nfs4_pnfs_layoutreturn* layout) +{ + struct inode* ino = layout->args->inode; + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PNFS_LAYOUTRETURN], + .rpc_argp = layout->args, + }; + return nfs4_map_errors(rpc_call_sync(NFS_CLIENT(ino), &msg, 0)); +} + static int nfs4_proc_read(struct nfs_read_data *rdata) { struct nfs4_exception exception = { }; @@ -1565,7 +1575,7 @@ static int _pnfs_proc_layoutcommit(struc return status; } -/* DH: Performs sync layoutcommit. As a note, O_DIRECT will +/* Performs sync layoutcommit. As a note, O_DIRECT will * require this, but I currently haven't modified O_DIRECT for pNFS, * and I'm not sure if I ever will as bypassing the pagecache might * be the fastest way to do this. (well, I'm sure we will @@ -2284,9 +2294,7 @@ nfs4_commit_done(struct rpc_task *task) nfs_commit_done(task); } -/* DH: Commit the data layout to the server. - * A caller must actually have a layout to call this function. - */ +/* Commit the data layout to the server. */ static void nfs4_proc_pnfs_layoutcommit_setup(struct nfs_write_data* data, int how) { @@ -3356,6 +3364,7 @@ struct nfs_rpc_ops nfs_v4_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, }; /* diff -puN fs/nfs/nfs4xdr.c~client-layoutreturn fs/nfs/nfs4xdr.c --- linux-2.6.14-pnfs-current/fs/nfs/nfs4xdr.c~client-layoutreturn 2006-01-13 17:36:59.280604000 -0500 +++ linux-2.6.14-pnfs-current-dhildebz/fs/nfs/nfs4xdr.c 2006-01-13 17:39:00.803632000 -0500 @@ -430,6 +430,13 @@ static int nfs_stat_to_errno(int); decode_putfh_maxsz + \ decode_pnfs_layoutcommit_maxsz + \ decode_getattr_maxsz) +#define encode_pnfs_layoutreturn_sz (8 + op_encode_hdr_maxsz) +#define decode_pnfs_layoutreturn_maxsz (op_decode_hdr_maxsz) +#define NFS4_enc_pnfs_layoutreturn_sz (compound_encode_hdr_maxsz + \ + encode_putfh_maxsz + \ + encode_pnfs_layoutreturn_sz) +#define NFS4_dec_pnfs_layoutreturn_sz (compound_decode_hdr_maxsz + \ + decode_pnfs_layoutreturn_maxsz) static struct { unsigned int mode; @@ -2698,7 +2705,7 @@ static int decode_attr_time_modify(struc return status; } -/* DH: The type of file system exported +/* The type of file system exported */ static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *layoutclass) { @@ -2904,7 +2911,6 @@ static int decode_getfattr(struct xdr_st if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) goto xdr_error; - if ((status = decode_attr_type(xdr, bitmap, &type)) != 0) goto xdr_error; fattr->type = nfs_type2fmt[type].nfs2type; @@ -4340,7 +4346,7 @@ out: } -/* DH: Encode request for commiting the layout information for pNFS. +/* Encode request for commiting the layout information for pNFS. */ static int encode_pnfs_layoutcommit(struct xdr_stream *xdr, const struct pnfs_layoutcommit_arg *args) { @@ -4364,7 +4370,7 @@ static int encode_pnfs_layoutcommit(stru return 0; } -/* DH: Receive a new stateid after commiting the layout +/* Receive a new stateid after commiting the layout */ static int decode_pnfs_layoutcommit(struct xdr_stream *xdr, struct rpc_rqst *req, struct pnfs_layoutcommit_res *res) { @@ -4381,7 +4387,7 @@ static int decode_pnfs_layoutcommit(stru } /* - * DH: Encode LAYOUTCOMMIT request + * Encode LAYOUTCOMMIT request */ static int nfs4_xdr_enc_pnfs_layoutcommit(struct rpc_rqst *req, uint32_t *p, struct pnfs_layoutcommit_arg *args) { @@ -4405,7 +4411,7 @@ out: } /* - * DH: Decode LAYOUTCOMMIT response + * Decode LAYOUTCOMMIT response */ static int nfs4_xdr_dec_pnfs_layoutcommit(struct rpc_rqst *rqstp, uint32_t *p, struct pnfs_layoutcommit_res *res) { @@ -4428,6 +4434,65 @@ out: return status; } +/* : Encode request to return the layout information for pNFS. +*/ +static int encode_pnfs_layoutreturn(struct xdr_stream *xdr, const struct nfs4_pnfs_layoutreturn_arg *args) +{ + uint32_t *p; + RESERVE_SPACE(4); + WRITE32(OP_LAYOUTRETURN); + WRITE64(args->clientid); + WRITE64(args->offset); + WRITE64(args->length); + WRITE32(args->iomode); + WRITE32(args->type); + return 0; +} + +static int decode_pnfs_layoutreturn(struct xdr_stream *xdr) +{ + return decode_op_hdr(xdr, OP_PUTFH); +} + +/* + * Encode LAYOUTRETURN request + */ +static int nfs4_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 = 2, + }; + int status; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_compound_hdr(&xdr, &hdr); + if ((status = encode_putfh(&xdr, NFS_FH(args->inode))) == 0) + status = encode_pnfs_layoutreturn(&xdr, args); + return status; +} + +/* + * Decode LAYOUTRETURN response + */ +static int nfs4_xdr_dec_pnfs_layoutreturn(struct rpc_rqst *rqstp, uint32_t *p) +{ + 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; + if ((status = decode_putfh(&xdr)) != 0) + goto out; + status = decode_pnfs_layoutreturn(&xdr); +out: + return status; + +} + uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus) { uint32_t bitmap[2] = {0}; @@ -4599,6 +4664,7 @@ struct rpc_procinfo nfs4_procedures[] = PROC(SETACL, enc_setacl, dec_setacl), PROC(PNFS_LAYOUTGET, enc_pnfs_layoutget, dec_pnfs_layoutget), PROC(PNFS_LAYOUTCOMMIT, enc_pnfs_layoutcommit, dec_pnfs_layoutcommit), + PROC(PNFS_LAYOUTRETURN, enc_pnfs_layoutreturn, dec_pnfs_layoutreturn), }; struct rpc_version nfs_version4 = { diff -puN include/linux/nfs4.h~client-layoutreturn include/linux/nfs4.h --- linux-2.6.14-pnfs-current/include/linux/nfs4.h~client-layoutreturn 2006-01-13 17:36:59.285599000 -0500 +++ linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs4.h 2006-01-13 17:36:59.347537000 -0500 @@ -392,6 +392,7 @@ enum { NFSPROC4_CLNT_SETACL, NFSPROC4_CLNT_PNFS_LAYOUTGET, NFSPROC4_CLNT_PNFS_LAYOUTCOMMIT, + NFSPROC4_CLNT_PNFS_LAYOUTRETURN, }; #endif diff -puN include/linux/nfs_xdr.h~client-layoutreturn include/linux/nfs_xdr.h --- linux-2.6.14-pnfs-current/include/linux/nfs_xdr.h~client-layoutreturn 2006-01-13 17:36:59.292592000 -0500 +++ linux-2.6.14-pnfs-current-dhildebz/include/linux/nfs_xdr.h 2006-01-13 17:36:59.354530000 -0500 @@ -778,6 +778,7 @@ struct nfs_rpc_ops { int (*pnfs_layoutget)(struct nfs4_pnfs_layoutget* layout); void (*pnfs_layoutcommit_setup)(struct nfs_write_data *, int how); int (*pnfs_layoutcommit) (struct nfs_write_data *); + int (*pnfs_layoutreturn)(struct nfs4_pnfs_layoutreturn* layout); }; /* diff -puN include/linux/pnfs_xdr.h~client-layoutreturn include/linux/pnfs_xdr.h --- linux-2.6.14-pnfs-current/include/linux/pnfs_xdr.h~client-layoutreturn 2006-01-13 17:36:59.297587000 -0500 +++ linux-2.6.14-pnfs-current-dhildebz/include/linux/pnfs_xdr.h 2006-01-13 17:36:59.359525000 -0500 @@ -67,4 +67,18 @@ struct pnfs_layoutcommit_res { const struct nfs_server *server; }; +struct nfs4_pnfs_layoutreturn_arg { + __u64 clientid; + __u64 offset; + __u64 length; + __u32 iomode; + __u32 type; + struct inode* inode; +}; + +struct nfs4_pnfs_layoutreturn { + struct nfs4_pnfs_layoutreturn_arg* args; + struct rpc_cred *cred; +}; + #endif /* LINUX_PNFS_XDR_H */ _