aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c247
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
776const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 804const 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
1970static int
1971encode_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
1984static 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
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}
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 */
2865static 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 */
2884static 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 */
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}
2793#endif /* CONFIG_NFS_V4_1 */ 2914#endif /* CONFIG_NFS_V4_1 */
2794 2915
2795static 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)
@@ -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
5453static 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;
5476out_overflow:
5477 print_overflow_msg(__func__, xdr);
5478out:
5479 return -EIO;
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}
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,
6461out: 6637out:
6462 return status; 6638 return status;
6463} 6639}
6640
6641/*
6642 * Decode SECINFO_NO_NAME response
6643 */
6644static 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);
6661out:
6662 return status;
6663}
6664
6665/*
6666 * Decode TEST_STATEID response
6667 */
6668static 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);
6682out:
6683 return status;
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}
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