diff options
author | Bryan Schumaker <bjschuma@netapp.com> | 2011-06-02 14:59:08 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-07-12 13:40:27 -0400 |
commit | 7d9747947ae66d8f6a9a9a023a3a5e28df6a536e (patch) | |
tree | f0fc49559d1653e7e1e8597cf07f9f04cff9d237 /fs/nfs/nfs4xdr.c | |
parent | fca78d6d2c77f87d7dbee89bbe4836a44da881e2 (diff) |
NFS: Added TEST_STATEID call
This patch adds in the xdr for doing a TEST_STATEID call with a single
stateid. RFC 5661 allows multiple stateids to be tested in a single
call, but only testing one keeps things simpler for now.
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.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c8c069a6319b..7d914d9e7584 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -345,6 +345,9 @@ static int nfs4_stat_to_errno(int); | |||
345 | 1 + decode_stateid_maxsz) | 345 | 1 + decode_stateid_maxsz) |
346 | #define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 1) | 346 | #define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 1) |
347 | #define decode_secinfo_no_name_maxsz decode_secinfo_maxsz | 347 | #define decode_secinfo_no_name_maxsz decode_secinfo_maxsz |
348 | #define encode_test_stateid_maxsz (op_encode_hdr_maxsz + 2 + \ | ||
349 | XDR_QUADLEN(NFS4_STATEID_SIZE)) | ||
350 | #define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1) | ||
348 | #else /* CONFIG_NFS_V4_1 */ | 351 | #else /* CONFIG_NFS_V4_1 */ |
349 | #define encode_sequence_maxsz 0 | 352 | #define encode_sequence_maxsz 0 |
350 | #define decode_sequence_maxsz 0 | 353 | #define decode_sequence_maxsz 0 |
@@ -782,6 +785,12 @@ static int nfs4_stat_to_errno(int); | |||
782 | decode_sequence_maxsz + \ | 785 | decode_sequence_maxsz + \ |
783 | decode_putrootfh_maxsz + \ | 786 | decode_putrootfh_maxsz + \ |
784 | decode_secinfo_no_name_maxsz) | 787 | decode_secinfo_no_name_maxsz) |
788 | #define NFS4_enc_test_stateid_sz (compound_encode_hdr_maxsz + \ | ||
789 | encode_sequence_maxsz + \ | ||
790 | encode_test_stateid_maxsz) | ||
791 | #define NFS4_dec_test_stateid_sz (compound_decode_hdr_maxsz + \ | ||
792 | decode_sequence_maxsz + \ | ||
793 | decode_test_stateid_maxsz) | ||
785 | 794 | ||
786 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + | 795 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + |
787 | compound_encode_hdr_maxsz + | 796 | compound_encode_hdr_maxsz + |
@@ -1962,6 +1971,20 @@ encode_secinfo_no_name(struct xdr_stream *xdr, | |||
1962 | hdr->replen += decode_secinfo_no_name_maxsz; | 1971 | hdr->replen += decode_secinfo_no_name_maxsz; |
1963 | return 0; | 1972 | return 0; |
1964 | } | 1973 | } |
1974 | |||
1975 | static void encode_test_stateid(struct xdr_stream *xdr, | ||
1976 | struct nfs41_test_stateid_args *args, | ||
1977 | struct compound_hdr *hdr) | ||
1978 | { | ||
1979 | __be32 *p; | ||
1980 | |||
1981 | p = reserve_space(xdr, 8 + NFS4_STATEID_SIZE); | ||
1982 | *p++ = cpu_to_be32(OP_TEST_STATEID); | ||
1983 | *p++ = cpu_to_be32(1); | ||
1984 | xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); | ||
1985 | hdr->nops++; | ||
1986 | hdr->replen += decode_test_stateid_maxsz; | ||
1987 | } | ||
1965 | #endif /* CONFIG_NFS_V4_1 */ | 1988 | #endif /* CONFIG_NFS_V4_1 */ |
1966 | 1989 | ||
1967 | /* | 1990 | /* |
@@ -2833,6 +2856,23 @@ static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, | |||
2833 | encode_nops(&hdr); | 2856 | encode_nops(&hdr); |
2834 | return 0; | 2857 | return 0; |
2835 | } | 2858 | } |
2859 | |||
2860 | /* | ||
2861 | * Encode TEST_STATEID request | ||
2862 | */ | ||
2863 | static void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req, | ||
2864 | struct xdr_stream *xdr, | ||
2865 | struct nfs41_test_stateid_args *args) | ||
2866 | { | ||
2867 | struct compound_hdr hdr = { | ||
2868 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2869 | }; | ||
2870 | |||
2871 | encode_compound_hdr(xdr, req, &hdr); | ||
2872 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2873 | encode_test_stateid(xdr, args, &hdr); | ||
2874 | encode_nops(&hdr); | ||
2875 | } | ||
2836 | #endif /* CONFIG_NFS_V4_1 */ | 2876 | #endif /* CONFIG_NFS_V4_1 */ |
2837 | 2877 | ||
2838 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | 2878 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) |
@@ -5371,6 +5411,35 @@ out_overflow: | |||
5371 | print_overflow_msg(__func__, xdr); | 5411 | print_overflow_msg(__func__, xdr); |
5372 | return -EIO; | 5412 | return -EIO; |
5373 | } | 5413 | } |
5414 | |||
5415 | static int decode_test_stateid(struct xdr_stream *xdr, | ||
5416 | struct nfs41_test_stateid_res *res) | ||
5417 | { | ||
5418 | __be32 *p; | ||
5419 | int status; | ||
5420 | int num_res; | ||
5421 | |||
5422 | status = decode_op_hdr(xdr, OP_TEST_STATEID); | ||
5423 | if (status) | ||
5424 | return status; | ||
5425 | |||
5426 | p = xdr_inline_decode(xdr, 4); | ||
5427 | if (unlikely(!p)) | ||
5428 | goto out_overflow; | ||
5429 | num_res = be32_to_cpup(p++); | ||
5430 | if (num_res != 1) | ||
5431 | goto out; | ||
5432 | |||
5433 | p = xdr_inline_decode(xdr, 4); | ||
5434 | if (unlikely(!p)) | ||
5435 | goto out_overflow; | ||
5436 | res->status = be32_to_cpup(p++); | ||
5437 | return res->status; | ||
5438 | out_overflow: | ||
5439 | print_overflow_msg(__func__, xdr); | ||
5440 | out: | ||
5441 | return -EIO; | ||
5442 | } | ||
5374 | #endif /* CONFIG_NFS_V4_1 */ | 5443 | #endif /* CONFIG_NFS_V4_1 */ |
5375 | 5444 | ||
5376 | /* | 5445 | /* |
@@ -6534,6 +6603,27 @@ static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp, | |||
6534 | out: | 6603 | out: |
6535 | return status; | 6604 | return status; |
6536 | } | 6605 | } |
6606 | |||
6607 | /* | ||
6608 | * Decode TEST_STATEID response | ||
6609 | */ | ||
6610 | static int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp, | ||
6611 | struct xdr_stream *xdr, | ||
6612 | struct nfs41_test_stateid_res *res) | ||
6613 | { | ||
6614 | struct compound_hdr hdr; | ||
6615 | int status; | ||
6616 | |||
6617 | status = decode_compound_hdr(xdr, &hdr); | ||
6618 | if (status) | ||
6619 | goto out; | ||
6620 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6621 | if (status) | ||
6622 | goto out; | ||
6623 | status = decode_test_stateid(xdr, res); | ||
6624 | out: | ||
6625 | return status; | ||
6626 | } | ||
6537 | #endif /* CONFIG_NFS_V4_1 */ | 6627 | #endif /* CONFIG_NFS_V4_1 */ |
6538 | 6628 | ||
6539 | /** | 6629 | /** |
@@ -6737,6 +6827,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
6737 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), | 6827 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), |
6738 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), | 6828 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), |
6739 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), | 6829 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), |
6830 | PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), | ||
6740 | #endif /* CONFIG_NFS_V4_1 */ | 6831 | #endif /* CONFIG_NFS_V4_1 */ |
6741 | }; | 6832 | }; |
6742 | 6833 | ||