diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 247 |
1 files changed, 246 insertions, 1 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e6e8f3b9a1de..c191a9baa422 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -343,6 +343,14 @@ static int nfs4_stat_to_errno(int); | |||
343 | 1 /* FIXME: opaque lrf_body always empty at the moment */) | 343 | 1 /* FIXME: opaque lrf_body always empty at the moment */) |
344 | #define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ | 344 | #define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ |
345 | 1 + decode_stateid_maxsz) | 345 | 1 + decode_stateid_maxsz) |
346 | #define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 1) | ||
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) | ||
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) | ||
346 | #else /* CONFIG_NFS_V4_1 */ | 354 | #else /* CONFIG_NFS_V4_1 */ |
347 | #define encode_sequence_maxsz 0 | 355 | #define encode_sequence_maxsz 0 |
348 | #define decode_sequence_maxsz 0 | 356 | #define decode_sequence_maxsz 0 |
@@ -772,6 +780,26 @@ static int nfs4_stat_to_errno(int); | |||
772 | decode_sequence_maxsz + \ | 780 | decode_sequence_maxsz + \ |
773 | decode_putfh_maxsz + \ | 781 | decode_putfh_maxsz + \ |
774 | decode_layoutreturn_maxsz) | 782 | decode_layoutreturn_maxsz) |
783 | #define NFS4_enc_secinfo_no_name_sz (compound_encode_hdr_maxsz + \ | ||
784 | encode_sequence_maxsz + \ | ||
785 | encode_putrootfh_maxsz +\ | ||
786 | encode_secinfo_no_name_maxsz) | ||
787 | #define NFS4_dec_secinfo_no_name_sz (compound_decode_hdr_maxsz + \ | ||
788 | decode_sequence_maxsz + \ | ||
789 | decode_putrootfh_maxsz + \ | ||
790 | decode_secinfo_no_name_maxsz) | ||
791 | #define NFS4_enc_test_stateid_sz (compound_encode_hdr_maxsz + \ | ||
792 | encode_sequence_maxsz + \ | ||
793 | encode_test_stateid_maxsz) | ||
794 | #define NFS4_dec_test_stateid_sz (compound_decode_hdr_maxsz + \ | ||
795 | decode_sequence_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) | ||
775 | 803 | ||
776 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + | 804 | const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + |
777 | compound_encode_hdr_maxsz + | 805 | compound_encode_hdr_maxsz + |
@@ -1938,6 +1966,46 @@ encode_layoutreturn(struct xdr_stream *xdr, | |||
1938 | hdr->nops++; | 1966 | hdr->nops++; |
1939 | hdr->replen += decode_layoutreturn_maxsz; | 1967 | hdr->replen += decode_layoutreturn_maxsz; |
1940 | } | 1968 | } |
1969 | |||
1970 | static int | ||
1971 | encode_secinfo_no_name(struct xdr_stream *xdr, | ||
1972 | const struct nfs41_secinfo_no_name_args *args, | ||
1973 | struct compound_hdr *hdr) | ||
1974 | { | ||
1975 | __be32 *p; | ||
1976 | p = reserve_space(xdr, 8); | ||
1977 | *p++ = cpu_to_be32(OP_SECINFO_NO_NAME); | ||
1978 | *p++ = cpu_to_be32(args->style); | ||
1979 | hdr->nops++; | ||
1980 | hdr->replen += decode_secinfo_no_name_maxsz; | ||
1981 | return 0; | ||
1982 | } | ||
1983 | |||
1984 | static void encode_test_stateid(struct xdr_stream *xdr, | ||
1985 | struct nfs41_test_stateid_args *args, | ||
1986 | struct compound_hdr *hdr) | ||
1987 | { | ||
1988 | __be32 *p; | ||
1989 | |||
1990 | p = reserve_space(xdr, 8 + NFS4_STATEID_SIZE); | ||
1991 | *p++ = cpu_to_be32(OP_TEST_STATEID); | ||
1992 | *p++ = cpu_to_be32(1); | ||
1993 | xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE); | ||
1994 | hdr->nops++; | ||
1995 | hdr->replen += decode_test_stateid_maxsz; | ||
1996 | } | ||
1997 | |||
1998 | static 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 | } | ||
1941 | #endif /* CONFIG_NFS_V4_1 */ | 2009 | #endif /* CONFIG_NFS_V4_1 */ |
1942 | 2010 | ||
1943 | /* | 2011 | /* |
@@ -2790,6 +2858,59 @@ static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, | |||
2790 | encode_layoutreturn(xdr, args, &hdr); | 2858 | encode_layoutreturn(xdr, args, &hdr); |
2791 | encode_nops(&hdr); | 2859 | encode_nops(&hdr); |
2792 | } | 2860 | } |
2861 | |||
2862 | /* | ||
2863 | * Encode SECINFO_NO_NAME request | ||
2864 | */ | ||
2865 | static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, | ||
2866 | struct xdr_stream *xdr, | ||
2867 | struct nfs41_secinfo_no_name_args *args) | ||
2868 | { | ||
2869 | struct compound_hdr hdr = { | ||
2870 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2871 | }; | ||
2872 | |||
2873 | encode_compound_hdr(xdr, req, &hdr); | ||
2874 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2875 | encode_putrootfh(xdr, &hdr); | ||
2876 | encode_secinfo_no_name(xdr, args, &hdr); | ||
2877 | encode_nops(&hdr); | ||
2878 | return 0; | ||
2879 | } | ||
2880 | |||
2881 | /* | ||
2882 | * Encode TEST_STATEID request | ||
2883 | */ | ||
2884 | static void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req, | ||
2885 | struct xdr_stream *xdr, | ||
2886 | struct nfs41_test_stateid_args *args) | ||
2887 | { | ||
2888 | struct compound_hdr hdr = { | ||
2889 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2890 | }; | ||
2891 | |||
2892 | encode_compound_hdr(xdr, req, &hdr); | ||
2893 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2894 | encode_test_stateid(xdr, args, &hdr); | ||
2895 | encode_nops(&hdr); | ||
2896 | } | ||
2897 | |||
2898 | /* | ||
2899 | * Encode FREE_STATEID request | ||
2900 | */ | ||
2901 | static 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 | } | ||
2793 | #endif /* CONFIG_NFS_V4_1 */ | 2914 | #endif /* CONFIG_NFS_V4_1 */ |
2794 | 2915 | ||
2795 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) | 2916 | static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) |
@@ -4977,11 +5098,17 @@ static int decode_exchange_id(struct xdr_stream *xdr, | |||
4977 | if (unlikely(status)) | 5098 | if (unlikely(status)) |
4978 | return status; | 5099 | return status; |
4979 | 5100 | ||
4980 | /* Throw away server_scope */ | 5101 | /* Save server_scope */ |
4981 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); | 5102 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
4982 | if (unlikely(status)) | 5103 | if (unlikely(status)) |
4983 | return status; | 5104 | return status; |
4984 | 5105 | ||
5106 | if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) | ||
5107 | return -EIO; | ||
5108 | |||
5109 | memcpy(res->server_scope->server_scope, dummy_str, dummy); | ||
5110 | res->server_scope->server_scope_sz = dummy; | ||
5111 | |||
4985 | /* Throw away Implementation id array */ | 5112 | /* Throw away Implementation id array */ |
4986 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); | 5113 | status = decode_opaque_inline(xdr, &dummy, &dummy_str); |
4987 | if (unlikely(status)) | 5114 | if (unlikely(status)) |
@@ -5322,6 +5449,55 @@ out_overflow: | |||
5322 | print_overflow_msg(__func__, xdr); | 5449 | print_overflow_msg(__func__, xdr); |
5323 | return -EIO; | 5450 | return -EIO; |
5324 | } | 5451 | } |
5452 | |||
5453 | static int decode_test_stateid(struct xdr_stream *xdr, | ||
5454 | struct nfs41_test_stateid_res *res) | ||
5455 | { | ||
5456 | __be32 *p; | ||
5457 | int status; | ||
5458 | int num_res; | ||
5459 | |||
5460 | status = decode_op_hdr(xdr, OP_TEST_STATEID); | ||
5461 | if (status) | ||
5462 | return status; | ||
5463 | |||
5464 | p = xdr_inline_decode(xdr, 4); | ||
5465 | if (unlikely(!p)) | ||
5466 | goto out_overflow; | ||
5467 | num_res = be32_to_cpup(p++); | ||
5468 | if (num_res != 1) | ||
5469 | goto out; | ||
5470 | |||
5471 | p = xdr_inline_decode(xdr, 4); | ||
5472 | if (unlikely(!p)) | ||
5473 | goto out_overflow; | ||
5474 | res->status = be32_to_cpup(p++); | ||
5475 | return res->status; | ||
5476 | out_overflow: | ||
5477 | print_overflow_msg(__func__, xdr); | ||
5478 | out: | ||
5479 | return -EIO; | ||
5480 | } | ||
5481 | |||
5482 | static 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; | ||
5497 | out_overflow: | ||
5498 | print_overflow_msg(__func__, xdr); | ||
5499 | return -EIO; | ||
5500 | } | ||
5325 | #endif /* CONFIG_NFS_V4_1 */ | 5501 | #endif /* CONFIG_NFS_V4_1 */ |
5326 | 5502 | ||
5327 | /* | 5503 | /* |
@@ -6461,6 +6637,72 @@ static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, | |||
6461 | out: | 6637 | out: |
6462 | return status; | 6638 | return status; |
6463 | } | 6639 | } |
6640 | |||
6641 | /* | ||
6642 | * Decode SECINFO_NO_NAME response | ||
6643 | */ | ||
6644 | static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp, | ||
6645 | struct xdr_stream *xdr, | ||
6646 | struct nfs4_secinfo_res *res) | ||
6647 | { | ||
6648 | struct compound_hdr hdr; | ||
6649 | int status; | ||
6650 | |||
6651 | status = decode_compound_hdr(xdr, &hdr); | ||
6652 | if (status) | ||
6653 | goto out; | ||
6654 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6655 | if (status) | ||
6656 | goto out; | ||
6657 | status = decode_putrootfh(xdr); | ||
6658 | if (status) | ||
6659 | goto out; | ||
6660 | status = decode_secinfo(xdr, res); | ||
6661 | out: | ||
6662 | return status; | ||
6663 | } | ||
6664 | |||
6665 | /* | ||
6666 | * Decode TEST_STATEID response | ||
6667 | */ | ||
6668 | static int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp, | ||
6669 | struct xdr_stream *xdr, | ||
6670 | struct nfs41_test_stateid_res *res) | ||
6671 | { | ||
6672 | struct compound_hdr hdr; | ||
6673 | int status; | ||
6674 | |||
6675 | status = decode_compound_hdr(xdr, &hdr); | ||
6676 | if (status) | ||
6677 | goto out; | ||
6678 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6679 | if (status) | ||
6680 | goto out; | ||
6681 | status = decode_test_stateid(xdr, res); | ||
6682 | out: | ||
6683 | return status; | ||
6684 | } | ||
6685 | |||
6686 | /* | ||
6687 | * Decode FREE_STATEID response | ||
6688 | */ | ||
6689 | static 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); | ||
6703 | out: | ||
6704 | return status; | ||
6705 | } | ||
6464 | #endif /* CONFIG_NFS_V4_1 */ | 6706 | #endif /* CONFIG_NFS_V4_1 */ |
6465 | 6707 | ||
6466 | /** | 6708 | /** |
@@ -6663,6 +6905,9 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
6663 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), | 6905 | PROC(LAYOUTGET, enc_layoutget, dec_layoutget), |
6664 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), | 6906 | PROC(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), |
6665 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), | 6907 | PROC(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), |
6908 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), | ||
6909 | PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), | ||
6910 | PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), | ||
6666 | #endif /* CONFIG_NFS_V4_1 */ | 6911 | #endif /* CONFIG_NFS_V4_1 */ |
6667 | }; | 6912 | }; |
6668 | 6913 | ||