From: Andy Adamson <andros@xxxxxxxxxx> Place the layoutcommi operation prior to the close operation in the close compound so that the filehandle is still valid. If the layoutcommit fails, a retry of the close compound, which retries with rpc_restart_call_prepare and so calls pnfs_roc again, will not include the layoutcommit operation, as the layoutcommit_needed test will be false having been satisfied by the failed compound. Signed-off-by: Andy Adamson <andros@xxxxxxxxxx> Signed-off-by: Fred Isaman <iisaman@xxxxxxxxxx> --- fs/nfs/nfs4xdr.c | 5 +++++ fs/nfs/pnfs.c | 9 ++++++++- include/linux/nfs_xdr.h | 2 ++ 3 files changed, 15 insertions(+), 1 deletions(-) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 1c8a3c4..bc97b33 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -2135,6 +2135,8 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea encode_compound_hdr(&xdr, req, &hdr); encode_sequence(&xdr, &args->seq_args, &hdr); encode_putfh(&xdr, args->fh, &hdr); + if (args->op_bitmask & NFS4_HAS_LAYOUTCOMMIT) /* layoutcommit set */ + encode_layoutcommit(&xdr, &args->lc_args, &hdr); encode_close(&xdr, args, &hdr); encode_getfattr(&xdr, args->bitmask, &hdr); if (args->op_bitmask & NFS4_HAS_LAYOUTRETURN) /* layoutreturn set */ @@ -5704,6 +5706,9 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos status = decode_putfh(&xdr); if (status) goto out; + /* We pay no attention to the layoutcommit return */ + if (res->op_bitmask & NFS4_HAS_LAYOUTCOMMIT) + decode_layoutcommit(&xdr); status = decode_close(&xdr, res); if (status != 0) goto out; diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 521ee9d..6724dc4 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -634,7 +634,6 @@ pnfs_return_layout_barrier(struct nfs_inode *nfsi, * Return on close * * No LAYOUTRETURNS can be sent when BULK RECALL flag is set. - * FIXME: add layoutcommit operation if layoutcommit_needed is true. */ bool pnfs_roc(struct nfs4_closedata *data) @@ -662,6 +661,14 @@ pnfs_roc(struct nfs4_closedata *data) } if (found == false) goto out_nolayout; + + /* Add layoutcommit operation if needed */ + if (layoutcommit_needed(NFS_I(data->inode))) { + pnfs_layoutcommit_setup(data->inode, &data->arg.lc_args, false); + data->res.op_bitmask |= NFS4_HAS_LAYOUTCOMMIT; + data->arg.op_bitmask |= NFS4_HAS_LAYOUTCOMMIT; + } + /* Stop new and drop response to outstanding LAYOUTGETS */ lo->plh_block_lgets++; lo->plh_outstanding++; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 851b09f..d4c4804 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -353,6 +353,7 @@ struct nfs_open_confirmres { /* op_bitmask bits */ #define NFS4_HAS_LAYOUTRETURN 0x01 +#define NFS4_HAS_LAYOUTCOMMIT 0x02 struct nfs_closeargs { struct nfs_fh * fh; @@ -361,6 +362,7 @@ struct nfs_closeargs { fmode_t fmode; const u32 * bitmask; u32 op_bitmask; /* which optional ops to encode */ + struct nfs4_layoutcommit_op_args lc_args; /* optional */ struct nfs4_layoutreturn_args lr_args; /* optional */ struct nfs4_sequence_args seq_args; }; -- 1.7.2.1 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html