aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
authorBryan Schumaker <bjschuma@netapp.com>2011-06-02 14:59:09 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-07-12 13:40:28 -0400
commit9aeda35fd643eba683fdb8dba8907fa796a85dda (patch)
treedf797ea6f4eca0601edcdf941ac678d11c79a07a /fs/nfs/nfs4xdr.c
parent7d9747947ae66d8f6a9a9a023a3a5e28df6a536e (diff)
NFS: added FREE_STATEID call
FREE_STATEID is used to tell the server that we want to free a stateid that no longer has any locks associated with it. This allows the client to reclaim locks without encountering edge conditions documented in section 8.4.3 of RFC 5661. Signed-off-by: Bryan Schumaker <bjschuma@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 7d914d9e7584..c191a9baa422 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -348,6 +348,9 @@ static int nfs4_stat_to_errno(int);
348#define encode_test_stateid_maxsz (op_encode_hdr_maxsz + 2 + \ 348#define encode_test_stateid_maxsz (op_encode_hdr_maxsz + 2 + \
349 XDR_QUADLEN(NFS4_STATEID_SIZE)) 349 XDR_QUADLEN(NFS4_STATEID_SIZE))
350#define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1) 350#define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1)
351#define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \
352 XDR_QUADLEN(NFS4_STATEID_SIZE))
353#define decode_free_stateid_maxsz (op_decode_hdr_maxsz + 1)
351#else /* CONFIG_NFS_V4_1 */ 354#else /* CONFIG_NFS_V4_1 */
352#define encode_sequence_maxsz 0 355#define encode_sequence_maxsz 0
353#define decode_sequence_maxsz 0 356#define decode_sequence_maxsz 0
@@ -791,6 +794,12 @@ static int nfs4_stat_to_errno(int);
791#define NFS4_dec_test_stateid_sz (compound_decode_hdr_maxsz + \ 794#define NFS4_dec_test_stateid_sz (compound_decode_hdr_maxsz + \
792 decode_sequence_maxsz + \ 795 decode_sequence_maxsz + \
793 decode_test_stateid_maxsz) 796 decode_test_stateid_maxsz)
797#define NFS4_enc_free_stateid_sz (compound_encode_hdr_maxsz + \
798 encode_sequence_maxsz + \
799 encode_free_stateid_maxsz)
800#define NFS4_dec_free_stateid_sz (compound_decode_hdr_maxsz + \
801 decode_sequence_maxsz + \
802 decode_free_stateid_maxsz)
794 803
795const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 804const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
796 compound_encode_hdr_maxsz + 805 compound_encode_hdr_maxsz +
@@ -1985,6 +1994,18 @@ static void encode_test_stateid(struct xdr_stream *xdr,
1985 hdr->nops++; 1994 hdr->nops++;
1986 hdr->replen += decode_test_stateid_maxsz; 1995 hdr->replen += decode_test_stateid_maxsz;
1987} 1996}
1997
1998static void encode_free_stateid(struct xdr_stream *xdr,
1999 struct nfs41_free_stateid_args *args,
2000 struct compound_hdr *hdr)
2001{
2002 __be32 *p;
2003 p = reserve_space(xdr, 4 + NFS4_STATEID_SIZE);
2004 *p++ = cpu_to_be32(OP_FREE_STATEID);
2005 xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE);
2006 hdr->nops++;
2007 hdr->replen += decode_free_stateid_maxsz;
2008}
1988#endif /* CONFIG_NFS_V4_1 */ 2009#endif /* CONFIG_NFS_V4_1 */
1989 2010
1990/* 2011/*
@@ -2873,6 +2894,23 @@ static void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req,
2873 encode_test_stateid(xdr, args, &hdr); 2894 encode_test_stateid(xdr, args, &hdr);
2874 encode_nops(&hdr); 2895 encode_nops(&hdr);
2875} 2896}
2897
2898/*
2899 * Encode FREE_STATEID request
2900 */
2901static void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req,
2902 struct xdr_stream *xdr,
2903 struct nfs41_free_stateid_args *args)
2904{
2905 struct compound_hdr hdr = {
2906 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
2907 };
2908
2909 encode_compound_hdr(xdr, req, &hdr);
2910 encode_sequence(xdr, &args->seq_args, &hdr);
2911 encode_free_stateid(xdr, args, &hdr);
2912 encode_nops(&hdr);
2913}
2876#endif /* CONFIG_NFS_V4_1 */ 2914#endif /* CONFIG_NFS_V4_1 */
2877 2915
2878static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) 2916static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
@@ -5440,6 +5478,26 @@ out_overflow:
5440out: 5478out:
5441 return -EIO; 5479 return -EIO;
5442} 5480}
5481
5482static int decode_free_stateid(struct xdr_stream *xdr,
5483 struct nfs41_free_stateid_res *res)
5484{
5485 __be32 *p;
5486 int status;
5487
5488 status = decode_op_hdr(xdr, OP_FREE_STATEID);
5489 if (status)
5490 return status;
5491
5492 p = xdr_inline_decode(xdr, 4);
5493 if (unlikely(!p))
5494 goto out_overflow;
5495 res->status = be32_to_cpup(p++);
5496 return res->status;
5497out_overflow:
5498 print_overflow_msg(__func__, xdr);
5499 return -EIO;
5500}
5443#endif /* CONFIG_NFS_V4_1 */ 5501#endif /* CONFIG_NFS_V4_1 */
5444 5502
5445/* 5503/*
@@ -6624,6 +6682,27 @@ static int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp,
6624out: 6682out:
6625 return status; 6683 return status;
6626} 6684}
6685
6686/*
6687 * Decode FREE_STATEID response
6688 */
6689static int nfs4_xdr_dec_free_stateid(struct rpc_rqst *rqstp,
6690 struct xdr_stream *xdr,
6691 struct nfs41_free_stateid_res *res)
6692{
6693 struct compound_hdr hdr;
6694 int status;
6695
6696 status = decode_compound_hdr(xdr, &hdr);
6697 if (status)
6698 goto out;
6699 status = decode_sequence(xdr, &res->seq_res, rqstp);
6700 if (status)
6701 goto out;
6702 status = decode_free_stateid(xdr, res);
6703out:
6704 return status;
6705}
6627#endif /* CONFIG_NFS_V4_1 */ 6706#endif /* CONFIG_NFS_V4_1 */
6628 6707
6629/** 6708/**
@@ -6828,6 +6907,7 @@ struct rpc_procinfo nfs4_procedures[] = {
6828 PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), 6907 PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn),
6829 PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), 6908 PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name),
6830 PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), 6909 PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid),
6910 PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid),
6831#endif /* CONFIG_NFS_V4_1 */ 6911#endif /* CONFIG_NFS_V4_1 */
6832}; 6912};
6833 6913