xref: /linux/fs/nfs/nfs42xdr.c (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21c6dcbe5SAnna Schumaker /*
31c6dcbe5SAnna Schumaker  * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
41c6dcbe5SAnna Schumaker  */
51c6dcbe5SAnna Schumaker #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
61c6dcbe5SAnna Schumaker #define __LINUX_FS_NFS_NFS4_2XDR_H
71c6dcbe5SAnna Schumaker 
8be3a5d23STrond Myklebust #include "nfs42.h"
9be3a5d23STrond Myklebust 
1064edd55dSAnna Schumaker /* Not limited by NFS itself, limited by the generic xattr code */
1164edd55dSAnna Schumaker #define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
1264edd55dSAnna Schumaker 
13f4ac1674SAnna Schumaker #define encode_fallocate_maxsz		(encode_stateid_maxsz + \
14f4ac1674SAnna Schumaker 					 2 /* offset */ + \
15f4ac1674SAnna Schumaker 					 2 /* length */)
162e72448bSAnna Schumaker #define NFS42_WRITE_RES_SIZE		(1 /* wr_callback_id size */ +\
172e72448bSAnna Schumaker 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
182e72448bSAnna Schumaker 					 2 /* wr_count */ + \
192e72448bSAnna Schumaker 					 1 /* wr_committed */ + \
202e72448bSAnna Schumaker 					 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
21f4ac1674SAnna Schumaker #define encode_allocate_maxsz		(op_encode_hdr_maxsz + \
22f4ac1674SAnna Schumaker 					 encode_fallocate_maxsz)
23f4ac1674SAnna Schumaker #define decode_allocate_maxsz		(op_decode_hdr_maxsz)
242e72448bSAnna Schumaker #define encode_copy_maxsz		(op_encode_hdr_maxsz +          \
252e72448bSAnna Schumaker 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
262e72448bSAnna Schumaker 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
271d38f3f0SOlga Kornievskaia 					 2 + 2 + 2 + 1 + 1 + 1 +\
281d38f3f0SOlga Kornievskaia 					 1 + /* One cnr_source_server */\
291d38f3f0SOlga Kornievskaia 					 1 + /* nl4_type */ \
301d38f3f0SOlga Kornievskaia 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
312e72448bSAnna Schumaker #define decode_copy_maxsz		(op_decode_hdr_maxsz + \
322e72448bSAnna Schumaker 					 NFS42_WRITE_RES_SIZE + \
332e72448bSAnna Schumaker 					 1 /* cr_consecutive */ + \
342e72448bSAnna Schumaker 					 1 /* cr_synchronous */)
35cb95deeaSOlga Kornievskaia #define encode_offload_cancel_maxsz	(op_encode_hdr_maxsz + \
36cb95deeaSOlga Kornievskaia 					 XDR_QUADLEN(NFS4_STATEID_SIZE))
37cb95deeaSOlga Kornievskaia #define decode_offload_cancel_maxsz	(op_decode_hdr_maxsz)
380491567bSOlga Kornievskaia #define encode_copy_notify_maxsz	(op_encode_hdr_maxsz + \
390491567bSOlga Kornievskaia 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
400491567bSOlga Kornievskaia 					 1 + /* nl4_type */ \
410491567bSOlga Kornievskaia 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
420491567bSOlga Kornievskaia #define decode_copy_notify_maxsz	(op_decode_hdr_maxsz + \
430491567bSOlga Kornievskaia 					 3 + /* cnr_lease_time */\
440491567bSOlga Kornievskaia 					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
450491567bSOlga Kornievskaia 					 1 + /* Support 1 cnr_source_server */\
460491567bSOlga Kornievskaia 					 1 + /* nl4_type */ \
470491567bSOlga Kornievskaia 					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
48624bd5b7SAnna Schumaker #define encode_deallocate_maxsz		(op_encode_hdr_maxsz + \
49624bd5b7SAnna Schumaker 					 encode_fallocate_maxsz)
50624bd5b7SAnna Schumaker #define decode_deallocate_maxsz		(op_decode_hdr_maxsz)
51c5675526SAnna Schumaker #define encode_read_plus_maxsz		(op_encode_hdr_maxsz + \
52c5675526SAnna Schumaker 					 encode_stateid_maxsz + 3)
53f8527028SAnna Schumaker #define NFS42_READ_PLUS_DATA_SEGMENT_SIZE \
54f8527028SAnna Schumaker 					(1 /* data_content4 */ + \
55c5675526SAnna Schumaker 					 2 /* data_info4.di_offset */ + \
56f8527028SAnna Schumaker 					 1 /* data_info4.di_length */)
578d18f6c5SAnna Schumaker #define NFS42_READ_PLUS_HOLE_SEGMENT_SIZE \
588d18f6c5SAnna Schumaker 					(1 /* data_content4 */ + \
598d18f6c5SAnna Schumaker 					 2 /* data_info4.di_offset */ + \
608d18f6c5SAnna Schumaker 					 2 /* data_info4.di_length */)
618d18f6c5SAnna Schumaker #define READ_PLUS_SEGMENT_SIZE_DIFF	(NFS42_READ_PLUS_HOLE_SEGMENT_SIZE - \
628d18f6c5SAnna Schumaker 					 NFS42_READ_PLUS_DATA_SEGMENT_SIZE)
63c5675526SAnna Schumaker #define decode_read_plus_maxsz		(op_decode_hdr_maxsz + \
64c5675526SAnna Schumaker 					 1 /* rpr_eof */ + \
65c5675526SAnna Schumaker 					 1 /* rpr_contents count */ + \
668d18f6c5SAnna Schumaker 					 NFS42_READ_PLUS_HOLE_SEGMENT_SIZE)
671c6dcbe5SAnna Schumaker #define encode_seek_maxsz		(op_encode_hdr_maxsz + \
681c6dcbe5SAnna Schumaker 					 encode_stateid_maxsz + \
691c6dcbe5SAnna Schumaker 					 2 /* offset */ + \
701c6dcbe5SAnna Schumaker 					 1 /* whence */)
711c6dcbe5SAnna Schumaker #define decode_seek_maxsz		(op_decode_hdr_maxsz + \
721c6dcbe5SAnna Schumaker 					 1 /* eof */ + \
731c6dcbe5SAnna Schumaker 					 1 /* whence */ + \
741c6dcbe5SAnna Schumaker 					 2 /* offset */ + \
751c6dcbe5SAnna Schumaker 					 2 /* length */)
76be3a5d23STrond Myklebust #define encode_io_info_maxsz		4
77be3a5d23STrond Myklebust #define encode_layoutstats_maxsz	(op_decode_hdr_maxsz + \
78be3a5d23STrond Myklebust 					2 /* offset */ + \
79be3a5d23STrond Myklebust 					2 /* length */ + \
80be3a5d23STrond Myklebust 					encode_stateid_maxsz + \
81be3a5d23STrond Myklebust 					encode_io_info_maxsz + \
82be3a5d23STrond Myklebust 					encode_io_info_maxsz + \
83be3a5d23STrond Myklebust 					1 /* opaque devaddr4 length */ + \
84be3a5d23STrond Myklebust 					XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
85be3a5d23STrond Myklebust #define decode_layoutstats_maxsz	(op_decode_hdr_maxsz)
863eb86093STrond Myklebust #define encode_device_error_maxsz	(XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
873eb86093STrond Myklebust 					1 /* status */ + 1 /* opnum */)
883eb86093STrond Myklebust #define encode_layouterror_maxsz	(op_decode_hdr_maxsz + \
893eb86093STrond Myklebust 					2 /* offset */ + \
903eb86093STrond Myklebust 					2 /* length */ + \
913eb86093STrond Myklebust 					encode_stateid_maxsz + \
923eb86093STrond Myklebust 					1 /* Array size */ + \
933eb86093STrond Myklebust 					encode_device_error_maxsz)
943eb86093STrond Myklebust #define decode_layouterror_maxsz	(op_decode_hdr_maxsz)
9536022770SPeng Tao #define encode_clone_maxsz		(encode_stateid_maxsz + \
9636022770SPeng Tao 					encode_stateid_maxsz + \
9736022770SPeng Tao 					2 /* src offset */ + \
9836022770SPeng Tao 					2 /* dst offset */ + \
9936022770SPeng Tao 					2 /* count */)
10036022770SPeng Tao #define decode_clone_maxsz		(op_decode_hdr_maxsz)
10164edd55dSAnna Schumaker #define encode_getxattr_maxsz		(op_encode_hdr_maxsz + 1 + \
10264edd55dSAnna Schumaker 					 nfs4_xattr_name_maxsz)
10364edd55dSAnna Schumaker #define decode_getxattr_maxsz		(op_decode_hdr_maxsz + 1 + pagepad_maxsz)
10464edd55dSAnna Schumaker #define encode_setxattr_maxsz		(op_encode_hdr_maxsz + \
10564edd55dSAnna Schumaker 					 1 + nfs4_xattr_name_maxsz + 1)
10664edd55dSAnna Schumaker #define decode_setxattr_maxsz		(op_decode_hdr_maxsz + decode_change_info_maxsz)
10764edd55dSAnna Schumaker #define encode_listxattrs_maxsz		(op_encode_hdr_maxsz + 2 + 1)
10864edd55dSAnna Schumaker #define decode_listxattrs_maxsz		(op_decode_hdr_maxsz + 2 + 1 + 1 + 1)
10964edd55dSAnna Schumaker #define encode_removexattr_maxsz	(op_encode_hdr_maxsz + 1 + \
11064edd55dSAnna Schumaker 					 nfs4_xattr_name_maxsz)
11164edd55dSAnna Schumaker #define decode_removexattr_maxsz	(op_decode_hdr_maxsz + \
11264edd55dSAnna Schumaker 					 decode_change_info_maxsz)
1131c6dcbe5SAnna Schumaker 
114f4ac1674SAnna Schumaker #define NFS4_enc_allocate_sz		(compound_encode_hdr_maxsz + \
1151a3466aeSAnna Schumaker 					 encode_sequence_maxsz + \
116f4ac1674SAnna Schumaker 					 encode_putfh_maxsz + \
1179a51940bSAnna Schumaker 					 encode_allocate_maxsz + \
1189a51940bSAnna Schumaker 					 encode_getattr_maxsz)
119f4ac1674SAnna Schumaker #define NFS4_dec_allocate_sz		(compound_decode_hdr_maxsz + \
1201a3466aeSAnna Schumaker 					 decode_sequence_maxsz + \
121f4ac1674SAnna Schumaker 					 decode_putfh_maxsz + \
1229a51940bSAnna Schumaker 					 decode_allocate_maxsz + \
1239a51940bSAnna Schumaker 					 decode_getattr_maxsz)
1242e72448bSAnna Schumaker #define NFS4_enc_copy_sz		(compound_encode_hdr_maxsz + \
1251a3466aeSAnna Schumaker 					 encode_sequence_maxsz + \
1262e72448bSAnna Schumaker 					 encode_putfh_maxsz + \
1272e72448bSAnna Schumaker 					 encode_savefh_maxsz + \
1282e72448bSAnna Schumaker 					 encode_putfh_maxsz + \
129e0926934SOlga Kornievskaia 					 encode_copy_maxsz + \
130e0926934SOlga Kornievskaia 					 encode_commit_maxsz)
1312e72448bSAnna Schumaker #define NFS4_dec_copy_sz		(compound_decode_hdr_maxsz + \
1321a3466aeSAnna Schumaker 					 decode_sequence_maxsz + \
1332e72448bSAnna Schumaker 					 decode_putfh_maxsz + \
1342e72448bSAnna Schumaker 					 decode_savefh_maxsz + \
1352e72448bSAnna Schumaker 					 decode_putfh_maxsz + \
136e0926934SOlga Kornievskaia 					 decode_copy_maxsz + \
137e0926934SOlga Kornievskaia 					 decode_commit_maxsz)
138cb95deeaSOlga Kornievskaia #define NFS4_enc_offload_cancel_sz	(compound_encode_hdr_maxsz + \
1391a3466aeSAnna Schumaker 					 encode_sequence_maxsz + \
140cb95deeaSOlga Kornievskaia 					 encode_putfh_maxsz + \
141cb95deeaSOlga Kornievskaia 					 encode_offload_cancel_maxsz)
142cb95deeaSOlga Kornievskaia #define NFS4_dec_offload_cancel_sz	(compound_decode_hdr_maxsz + \
1431a3466aeSAnna Schumaker 					 decode_sequence_maxsz + \
144cb95deeaSOlga Kornievskaia 					 decode_putfh_maxsz + \
145cb95deeaSOlga Kornievskaia 					 decode_offload_cancel_maxsz)
1460491567bSOlga Kornievskaia #define NFS4_enc_copy_notify_sz		(compound_encode_hdr_maxsz + \
1470491567bSOlga Kornievskaia 					 encode_putfh_maxsz + \
1480491567bSOlga Kornievskaia 					 encode_copy_notify_maxsz)
1490491567bSOlga Kornievskaia #define NFS4_dec_copy_notify_sz		(compound_decode_hdr_maxsz + \
1500491567bSOlga Kornievskaia 					 decode_putfh_maxsz + \
1510491567bSOlga Kornievskaia 					 decode_copy_notify_maxsz)
152624bd5b7SAnna Schumaker #define NFS4_enc_deallocate_sz		(compound_encode_hdr_maxsz + \
1531a3466aeSAnna Schumaker 					 encode_sequence_maxsz + \
154624bd5b7SAnna Schumaker 					 encode_putfh_maxsz + \
1559a51940bSAnna Schumaker 					 encode_deallocate_maxsz + \
1569a51940bSAnna Schumaker 					 encode_getattr_maxsz)
157624bd5b7SAnna Schumaker #define NFS4_dec_deallocate_sz		(compound_decode_hdr_maxsz + \
1581a3466aeSAnna Schumaker 					 decode_sequence_maxsz + \
159624bd5b7SAnna Schumaker 					 decode_putfh_maxsz + \
1609a51940bSAnna Schumaker 					 decode_deallocate_maxsz + \
1619a51940bSAnna Schumaker 					 decode_getattr_maxsz)
162c5675526SAnna Schumaker #define NFS4_enc_read_plus_sz		(compound_encode_hdr_maxsz + \
163c5675526SAnna Schumaker 					 encode_sequence_maxsz + \
164c5675526SAnna Schumaker 					 encode_putfh_maxsz + \
165c5675526SAnna Schumaker 					 encode_read_plus_maxsz)
166c5675526SAnna Schumaker #define NFS4_dec_read_plus_sz		(compound_decode_hdr_maxsz + \
167c5675526SAnna Schumaker 					 decode_sequence_maxsz + \
168c5675526SAnna Schumaker 					 decode_putfh_maxsz + \
169c5675526SAnna Schumaker 					 decode_read_plus_maxsz)
1701c6dcbe5SAnna Schumaker #define NFS4_enc_seek_sz		(compound_encode_hdr_maxsz + \
1711a3466aeSAnna Schumaker 					 encode_sequence_maxsz + \
1721c6dcbe5SAnna Schumaker 					 encode_putfh_maxsz + \
1731c6dcbe5SAnna Schumaker 					 encode_seek_maxsz)
1741c6dcbe5SAnna Schumaker #define NFS4_dec_seek_sz		(compound_decode_hdr_maxsz + \
1751a3466aeSAnna Schumaker 					 decode_sequence_maxsz + \
1761c6dcbe5SAnna Schumaker 					 decode_putfh_maxsz + \
1771c6dcbe5SAnna Schumaker 					 decode_seek_maxsz)
178be3a5d23STrond Myklebust #define NFS4_enc_layoutstats_sz		(compound_encode_hdr_maxsz + \
179be3a5d23STrond Myklebust 					 encode_sequence_maxsz + \
180be3a5d23STrond Myklebust 					 encode_putfh_maxsz + \
181be3a5d23STrond Myklebust 					 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
182be3a5d23STrond Myklebust #define NFS4_dec_layoutstats_sz		(compound_decode_hdr_maxsz + \
183be3a5d23STrond Myklebust 					 decode_sequence_maxsz + \
184be3a5d23STrond Myklebust 					 decode_putfh_maxsz + \
185be3a5d23STrond Myklebust 					 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
1863eb86093STrond Myklebust #define NFS4_enc_layouterror_sz		(compound_encode_hdr_maxsz + \
1873eb86093STrond Myklebust 					 encode_sequence_maxsz + \
1883eb86093STrond Myklebust 					 encode_putfh_maxsz + \
1893eb86093STrond Myklebust 					 NFS42_LAYOUTERROR_MAX * \
1903eb86093STrond Myklebust 					 encode_layouterror_maxsz)
1913eb86093STrond Myklebust #define NFS4_dec_layouterror_sz		(compound_decode_hdr_maxsz + \
1923eb86093STrond Myklebust 					 decode_sequence_maxsz + \
1933eb86093STrond Myklebust 					 decode_putfh_maxsz + \
1943eb86093STrond Myklebust 					 NFS42_LAYOUTERROR_MAX * \
1953eb86093STrond Myklebust 					 decode_layouterror_maxsz)
19636022770SPeng Tao #define NFS4_enc_clone_sz		(compound_encode_hdr_maxsz + \
19736022770SPeng Tao 					 encode_sequence_maxsz + \
19836022770SPeng Tao 					 encode_putfh_maxsz + \
19936022770SPeng Tao 					 encode_savefh_maxsz + \
20036022770SPeng Tao 					 encode_putfh_maxsz + \
20136022770SPeng Tao 					 encode_clone_maxsz + \
20236022770SPeng Tao 					 encode_getattr_maxsz)
20336022770SPeng Tao #define NFS4_dec_clone_sz		(compound_decode_hdr_maxsz + \
20436022770SPeng Tao 					 decode_sequence_maxsz + \
20536022770SPeng Tao 					 decode_putfh_maxsz + \
20636022770SPeng Tao 					 decode_savefh_maxsz + \
20736022770SPeng Tao 					 decode_putfh_maxsz + \
20836022770SPeng Tao 					 decode_clone_maxsz + \
20936022770SPeng Tao 					 decode_getattr_maxsz)
21004a5da69SFrank van der Linden #define NFS4_enc_getxattr_sz		(compound_encode_hdr_maxsz + \
21104a5da69SFrank van der Linden 					 encode_sequence_maxsz + \
21204a5da69SFrank van der Linden 					 encode_putfh_maxsz + \
21304a5da69SFrank van der Linden 					 encode_getxattr_maxsz)
21404a5da69SFrank van der Linden #define NFS4_dec_getxattr_sz		(compound_decode_hdr_maxsz + \
21504a5da69SFrank van der Linden 					 decode_sequence_maxsz + \
21604a5da69SFrank van der Linden 					 decode_putfh_maxsz + \
21704a5da69SFrank van der Linden 					 decode_getxattr_maxsz)
21804a5da69SFrank van der Linden #define NFS4_enc_setxattr_sz		(compound_encode_hdr_maxsz + \
21904a5da69SFrank van der Linden 					 encode_sequence_maxsz + \
22004a5da69SFrank van der Linden 					 encode_putfh_maxsz + \
22186e2e1f6SAnna Schumaker 					 encode_setxattr_maxsz + \
22286e2e1f6SAnna Schumaker 					 encode_getattr_maxsz)
22304a5da69SFrank van der Linden #define NFS4_dec_setxattr_sz		(compound_decode_hdr_maxsz + \
22404a5da69SFrank van der Linden 					 decode_sequence_maxsz + \
22504a5da69SFrank van der Linden 					 decode_putfh_maxsz + \
22686e2e1f6SAnna Schumaker 					 decode_setxattr_maxsz + \
22786e2e1f6SAnna Schumaker 					 decode_getattr_maxsz)
22804a5da69SFrank van der Linden #define NFS4_enc_listxattrs_sz		(compound_encode_hdr_maxsz + \
22904a5da69SFrank van der Linden 					 encode_sequence_maxsz + \
23004a5da69SFrank van der Linden 					 encode_putfh_maxsz + \
23104a5da69SFrank van der Linden 					 encode_listxattrs_maxsz)
23204a5da69SFrank van der Linden #define NFS4_dec_listxattrs_sz		(compound_decode_hdr_maxsz + \
23304a5da69SFrank van der Linden 					 decode_sequence_maxsz + \
23404a5da69SFrank van der Linden 					 decode_putfh_maxsz + \
23504a5da69SFrank van der Linden 					 decode_listxattrs_maxsz)
23604a5da69SFrank van der Linden #define NFS4_enc_removexattr_sz		(compound_encode_hdr_maxsz + \
23704a5da69SFrank van der Linden 					 encode_sequence_maxsz + \
23804a5da69SFrank van der Linden 					 encode_putfh_maxsz + \
23904a5da69SFrank van der Linden 					 encode_removexattr_maxsz)
24004a5da69SFrank van der Linden #define NFS4_dec_removexattr_sz		(compound_decode_hdr_maxsz + \
24104a5da69SFrank van der Linden 					 decode_sequence_maxsz + \
24204a5da69SFrank van der Linden 					 decode_putfh_maxsz + \
24304a5da69SFrank van der Linden 					 decode_removexattr_maxsz)
24404a5da69SFrank van der Linden 
24504a5da69SFrank van der Linden /*
24604a5da69SFrank van der Linden  * These values specify the maximum amount of data that is not
24704a5da69SFrank van der Linden  * associated with the extended attribute name or extended
24804a5da69SFrank van der Linden  * attribute list in the SETXATTR, GETXATTR and LISTXATTR
24904a5da69SFrank van der Linden  * respectively.
25004a5da69SFrank van der Linden  */
25104a5da69SFrank van der Linden const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
25204a5da69SFrank van der Linden 					compound_encode_hdr_maxsz +
25304a5da69SFrank van der Linden 					encode_sequence_maxsz +
25404a5da69SFrank van der Linden 					encode_putfh_maxsz + 1 +
25504a5da69SFrank van der Linden 					nfs4_xattr_name_maxsz)
25604a5da69SFrank van der Linden 					* XDR_UNIT);
25704a5da69SFrank van der Linden 
25804a5da69SFrank van der Linden const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
25904a5da69SFrank van der Linden 					compound_decode_hdr_maxsz +
26004a5da69SFrank van der Linden 					decode_sequence_maxsz +
26104a5da69SFrank van der Linden 					decode_putfh_maxsz + 1) * XDR_UNIT);
26204a5da69SFrank van der Linden 
26304a5da69SFrank van der Linden const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
26404a5da69SFrank van der Linden 					compound_decode_hdr_maxsz +
26504a5da69SFrank van der Linden 					decode_sequence_maxsz +
26604a5da69SFrank van der Linden 					decode_putfh_maxsz + 3) * XDR_UNIT);
26704a5da69SFrank van der Linden 
encode_fallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args)268f4ac1674SAnna Schumaker static void encode_fallocate(struct xdr_stream *xdr,
2690096d39bSChristoph Hellwig 			     const struct nfs42_falloc_args *args)
270f4ac1674SAnna Schumaker {
271f4ac1674SAnna Schumaker 	encode_nfs4_stateid(xdr, &args->falloc_stateid);
272f4ac1674SAnna Schumaker 	encode_uint64(xdr, args->falloc_offset);
273f4ac1674SAnna Schumaker 	encode_uint64(xdr, args->falloc_length);
274f4ac1674SAnna Schumaker }
275f4ac1674SAnna Schumaker 
encode_allocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)276f4ac1674SAnna Schumaker static void encode_allocate(struct xdr_stream *xdr,
2770096d39bSChristoph Hellwig 			    const struct nfs42_falloc_args *args,
278f4ac1674SAnna Schumaker 			    struct compound_hdr *hdr)
279f4ac1674SAnna Schumaker {
280f4ac1674SAnna Schumaker 	encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
281f4ac1674SAnna Schumaker 	encode_fallocate(xdr, args);
282f4ac1674SAnna Schumaker }
283f4ac1674SAnna Schumaker 
encode_nl4_server(struct xdr_stream * xdr,const struct nl4_server * ns)2840491567bSOlga Kornievskaia static void encode_nl4_server(struct xdr_stream *xdr,
2850491567bSOlga Kornievskaia 			      const struct nl4_server *ns)
2860491567bSOlga Kornievskaia {
2870491567bSOlga Kornievskaia 	encode_uint32(xdr, ns->nl4_type);
2880491567bSOlga Kornievskaia 	switch (ns->nl4_type) {
2890491567bSOlga Kornievskaia 	case NL4_NAME:
2900491567bSOlga Kornievskaia 	case NL4_URL:
2910491567bSOlga Kornievskaia 		encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
2920491567bSOlga Kornievskaia 		break;
2930491567bSOlga Kornievskaia 	case NL4_NETADDR:
2940491567bSOlga Kornievskaia 		encode_string(xdr, ns->u.nl4_addr.netid_len,
2950491567bSOlga Kornievskaia 			      ns->u.nl4_addr.netid);
2960491567bSOlga Kornievskaia 		encode_string(xdr, ns->u.nl4_addr.addr_len,
2970491567bSOlga Kornievskaia 			      ns->u.nl4_addr.addr);
2980491567bSOlga Kornievskaia 		break;
2990491567bSOlga Kornievskaia 	default:
3000491567bSOlga Kornievskaia 		WARN_ON_ONCE(1);
3010491567bSOlga Kornievskaia 	}
3020491567bSOlga Kornievskaia }
3030491567bSOlga Kornievskaia 
encode_copy(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)3042e72448bSAnna Schumaker static void encode_copy(struct xdr_stream *xdr,
3050096d39bSChristoph Hellwig 			const struct nfs42_copy_args *args,
3062e72448bSAnna Schumaker 			struct compound_hdr *hdr)
3072e72448bSAnna Schumaker {
3082e72448bSAnna Schumaker 	encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
3092e72448bSAnna Schumaker 	encode_nfs4_stateid(xdr, &args->src_stateid);
3102e72448bSAnna Schumaker 	encode_nfs4_stateid(xdr, &args->dst_stateid);
3112e72448bSAnna Schumaker 
3122e72448bSAnna Schumaker 	encode_uint64(xdr, args->src_pos);
3132e72448bSAnna Schumaker 	encode_uint64(xdr, args->dst_pos);
3142e72448bSAnna Schumaker 	encode_uint64(xdr, args->count);
3152e72448bSAnna Schumaker 
3162e72448bSAnna Schumaker 	encode_uint32(xdr, 1); /* consecutive = true */
31762164f31SOlga Kornievskaia 	encode_uint32(xdr, args->sync);
3181d38f3f0SOlga Kornievskaia 	if (args->cp_src == NULL) { /* intra-ssc */
3191d38f3f0SOlga Kornievskaia 		encode_uint32(xdr, 0); /* no src server list */
3201d38f3f0SOlga Kornievskaia 		return;
3211d38f3f0SOlga Kornievskaia 	}
3221d38f3f0SOlga Kornievskaia 	encode_uint32(xdr, 1); /* supporting 1 server */
3231d38f3f0SOlga Kornievskaia 	encode_nl4_server(xdr, args->cp_src);
3242e72448bSAnna Schumaker }
3252e72448bSAnna Schumaker 
encode_copy_commit(struct xdr_stream * xdr,const struct nfs42_copy_args * args,struct compound_hdr * hdr)326fd42ba82SAnna Schumaker static void encode_copy_commit(struct xdr_stream *xdr,
327fd42ba82SAnna Schumaker 			  const struct nfs42_copy_args *args,
328fd42ba82SAnna Schumaker 			  struct compound_hdr *hdr)
329fd42ba82SAnna Schumaker {
330fd42ba82SAnna Schumaker 	__be32 *p;
331fd42ba82SAnna Schumaker 
332fd42ba82SAnna Schumaker 	encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
333fd42ba82SAnna Schumaker 	p = reserve_space(xdr, 12);
334fd42ba82SAnna Schumaker 	p = xdr_encode_hyper(p, args->dst_pos);
335fd42ba82SAnna Schumaker 	*p = cpu_to_be32(args->count);
336fd42ba82SAnna Schumaker }
337fd42ba82SAnna Schumaker 
encode_offload_cancel(struct xdr_stream * xdr,const struct nfs42_offload_status_args * args,struct compound_hdr * hdr)338cb95deeaSOlga Kornievskaia static void encode_offload_cancel(struct xdr_stream *xdr,
339cb95deeaSOlga Kornievskaia 				  const struct nfs42_offload_status_args *args,
340cb95deeaSOlga Kornievskaia 				  struct compound_hdr *hdr)
341cb95deeaSOlga Kornievskaia {
342cb95deeaSOlga Kornievskaia 	encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
343cb95deeaSOlga Kornievskaia 	encode_nfs4_stateid(xdr, &args->osa_stateid);
344cb95deeaSOlga Kornievskaia }
345cb95deeaSOlga Kornievskaia 
encode_copy_notify(struct xdr_stream * xdr,const struct nfs42_copy_notify_args * args,struct compound_hdr * hdr)3460491567bSOlga Kornievskaia static void encode_copy_notify(struct xdr_stream *xdr,
3470491567bSOlga Kornievskaia 			       const struct nfs42_copy_notify_args *args,
3480491567bSOlga Kornievskaia 			       struct compound_hdr *hdr)
3490491567bSOlga Kornievskaia {
3500491567bSOlga Kornievskaia 	encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
3510491567bSOlga Kornievskaia 	encode_nfs4_stateid(xdr, &args->cna_src_stateid);
3520491567bSOlga Kornievskaia 	encode_nl4_server(xdr, &args->cna_dst);
3530491567bSOlga Kornievskaia }
3540491567bSOlga Kornievskaia 
encode_deallocate(struct xdr_stream * xdr,const struct nfs42_falloc_args * args,struct compound_hdr * hdr)355624bd5b7SAnna Schumaker static void encode_deallocate(struct xdr_stream *xdr,
3560096d39bSChristoph Hellwig 			      const struct nfs42_falloc_args *args,
357624bd5b7SAnna Schumaker 			      struct compound_hdr *hdr)
358624bd5b7SAnna Schumaker {
359624bd5b7SAnna Schumaker 	encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
360624bd5b7SAnna Schumaker 	encode_fallocate(xdr, args);
361624bd5b7SAnna Schumaker }
362624bd5b7SAnna Schumaker 
encode_read_plus(struct xdr_stream * xdr,const struct nfs_pgio_args * args,struct compound_hdr * hdr)363c5675526SAnna Schumaker static void encode_read_plus(struct xdr_stream *xdr,
364c5675526SAnna Schumaker 			     const struct nfs_pgio_args *args,
365c5675526SAnna Schumaker 			     struct compound_hdr *hdr)
366c5675526SAnna Schumaker {
367c5675526SAnna Schumaker 	encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr);
368c5675526SAnna Schumaker 	encode_nfs4_stateid(xdr, &args->stateid);
369c5675526SAnna Schumaker 	encode_uint64(xdr, args->offset);
370c5675526SAnna Schumaker 	encode_uint32(xdr, args->count);
371c5675526SAnna Schumaker }
372c5675526SAnna Schumaker 
encode_seek(struct xdr_stream * xdr,const struct nfs42_seek_args * args,struct compound_hdr * hdr)3731c6dcbe5SAnna Schumaker static void encode_seek(struct xdr_stream *xdr,
3740096d39bSChristoph Hellwig 			const struct nfs42_seek_args *args,
3751c6dcbe5SAnna Schumaker 			struct compound_hdr *hdr)
3761c6dcbe5SAnna Schumaker {
3771c6dcbe5SAnna Schumaker 	encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
3781c6dcbe5SAnna Schumaker 	encode_nfs4_stateid(xdr, &args->sa_stateid);
3791c6dcbe5SAnna Schumaker 	encode_uint64(xdr, args->sa_offset);
3801c6dcbe5SAnna Schumaker 	encode_uint32(xdr, args->sa_what);
3811c6dcbe5SAnna Schumaker }
3821c6dcbe5SAnna Schumaker 
encode_layoutstats(struct xdr_stream * xdr,const struct nfs42_layoutstat_args * args,struct nfs42_layoutstat_devinfo * devinfo,struct compound_hdr * hdr)383be3a5d23STrond Myklebust static void encode_layoutstats(struct xdr_stream *xdr,
3840096d39bSChristoph Hellwig 			       const struct nfs42_layoutstat_args *args,
385be3a5d23STrond Myklebust 			       struct nfs42_layoutstat_devinfo *devinfo,
386be3a5d23STrond Myklebust 			       struct compound_hdr *hdr)
387be3a5d23STrond Myklebust {
388be3a5d23STrond Myklebust 	__be32 *p;
389be3a5d23STrond Myklebust 
390be3a5d23STrond Myklebust 	encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
391be3a5d23STrond Myklebust 	p = reserve_space(xdr, 8 + 8);
392be3a5d23STrond Myklebust 	p = xdr_encode_hyper(p, devinfo->offset);
393be3a5d23STrond Myklebust 	p = xdr_encode_hyper(p, devinfo->length);
394be3a5d23STrond Myklebust 	encode_nfs4_stateid(xdr, &args->stateid);
395be3a5d23STrond Myklebust 	p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
396be3a5d23STrond Myklebust 	p = xdr_encode_hyper(p, devinfo->read_count);
397be3a5d23STrond Myklebust 	p = xdr_encode_hyper(p, devinfo->read_bytes);
398be3a5d23STrond Myklebust 	p = xdr_encode_hyper(p, devinfo->write_count);
399be3a5d23STrond Myklebust 	p = xdr_encode_hyper(p, devinfo->write_bytes);
400be3a5d23STrond Myklebust 	p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
401be3a5d23STrond Myklebust 			NFS4_DEVICEID4_SIZE);
402be3a5d23STrond Myklebust 	/* Encode layoutupdate4 */
403be3a5d23STrond Myklebust 	*p++ = cpu_to_be32(devinfo->layout_type);
404422c93c8STrond Myklebust 	if (devinfo->ld_private.ops)
405422c93c8STrond Myklebust 		devinfo->ld_private.ops->encode(xdr, args,
406422c93c8STrond Myklebust 				&devinfo->ld_private);
407be3a5d23STrond Myklebust 	else
408be3a5d23STrond Myklebust 		encode_uint32(xdr, 0);
409be3a5d23STrond Myklebust }
410be3a5d23STrond Myklebust 
encode_clone(struct xdr_stream * xdr,const struct nfs42_clone_args * args,struct compound_hdr * hdr)41136022770SPeng Tao static void encode_clone(struct xdr_stream *xdr,
4120096d39bSChristoph Hellwig 			 const struct nfs42_clone_args *args,
41336022770SPeng Tao 			 struct compound_hdr *hdr)
41436022770SPeng Tao {
41536022770SPeng Tao 	__be32 *p;
41636022770SPeng Tao 
41736022770SPeng Tao 	encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
41836022770SPeng Tao 	encode_nfs4_stateid(xdr, &args->src_stateid);
41936022770SPeng Tao 	encode_nfs4_stateid(xdr, &args->dst_stateid);
42036022770SPeng Tao 	p = reserve_space(xdr, 3*8);
42136022770SPeng Tao 	p = xdr_encode_hyper(p, args->src_offset);
42236022770SPeng Tao 	p = xdr_encode_hyper(p, args->dst_offset);
42336022770SPeng Tao 	xdr_encode_hyper(p, args->count);
42436022770SPeng Tao }
42536022770SPeng Tao 
encode_device_error(struct xdr_stream * xdr,const struct nfs42_device_error * error)4263eb86093STrond Myklebust static void encode_device_error(struct xdr_stream *xdr,
4273eb86093STrond Myklebust 				const struct nfs42_device_error *error)
4283eb86093STrond Myklebust {
4293eb86093STrond Myklebust 	__be32 *p;
4303eb86093STrond Myklebust 
4313eb86093STrond Myklebust 	p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
4323eb86093STrond Myklebust 	p = xdr_encode_opaque_fixed(p, error->dev_id.data,
4333eb86093STrond Myklebust 			NFS4_DEVICEID4_SIZE);
4343eb86093STrond Myklebust 	*p++ = cpu_to_be32(error->status);
4353eb86093STrond Myklebust 	*p = cpu_to_be32(error->opnum);
4363eb86093STrond Myklebust }
4373eb86093STrond Myklebust 
encode_layouterror(struct xdr_stream * xdr,const struct nfs42_layout_error * args,struct compound_hdr * hdr)4383eb86093STrond Myklebust static void encode_layouterror(struct xdr_stream *xdr,
4393eb86093STrond Myklebust 			       const struct nfs42_layout_error *args,
4403eb86093STrond Myklebust 			       struct compound_hdr *hdr)
4413eb86093STrond Myklebust {
4423eb86093STrond Myklebust 	__be32 *p;
4433eb86093STrond Myklebust 
4443eb86093STrond Myklebust 	encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
4453eb86093STrond Myklebust 	p = reserve_space(xdr, 8 + 8);
4463eb86093STrond Myklebust 	p = xdr_encode_hyper(p, args->offset);
4473eb86093STrond Myklebust 	p = xdr_encode_hyper(p, args->length);
4483eb86093STrond Myklebust 	encode_nfs4_stateid(xdr, &args->stateid);
4493eb86093STrond Myklebust 	p = reserve_space(xdr, 4);
4503eb86093STrond Myklebust 	*p = cpu_to_be32(1);
4513eb86093STrond Myklebust 	encode_device_error(xdr, &args->errors[0]);
4523eb86093STrond Myklebust }
4533eb86093STrond Myklebust 
encode_setxattr(struct xdr_stream * xdr,const struct nfs42_setxattrargs * arg,struct compound_hdr * hdr)4543e1f0212SFrank van der Linden static void encode_setxattr(struct xdr_stream *xdr,
4553e1f0212SFrank van der Linden 			    const struct nfs42_setxattrargs *arg,
4563e1f0212SFrank van der Linden 			    struct compound_hdr *hdr)
4573e1f0212SFrank van der Linden {
4583e1f0212SFrank van der Linden 	__be32 *p;
4593e1f0212SFrank van der Linden 
4603e1f0212SFrank van der Linden 	BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
4613e1f0212SFrank van der Linden 	BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
4623e1f0212SFrank van der Linden 
4633e1f0212SFrank van der Linden 	encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
4643e1f0212SFrank van der Linden 	p = reserve_space(xdr, 4);
4653e1f0212SFrank van der Linden 	*p = cpu_to_be32(arg->xattr_flags);
4663e1f0212SFrank van der Linden 	encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
4673e1f0212SFrank van der Linden 	p = reserve_space(xdr, 4);
4683e1f0212SFrank van der Linden 	*p = cpu_to_be32(arg->xattr_len);
4693e1f0212SFrank van der Linden 	if (arg->xattr_len)
4703e1f0212SFrank van der Linden 		xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
4713e1f0212SFrank van der Linden }
4723e1f0212SFrank van der Linden 
encode_getxattr(struct xdr_stream * xdr,const char * name,struct compound_hdr * hdr)4733e1f0212SFrank van der Linden static void encode_getxattr(struct xdr_stream *xdr, const char *name,
4743e1f0212SFrank van der Linden 			    struct compound_hdr *hdr)
4753e1f0212SFrank van der Linden {
4763e1f0212SFrank van der Linden 	encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
4773e1f0212SFrank van der Linden 	encode_string(xdr, strlen(name), name);
4783e1f0212SFrank van der Linden }
4793e1f0212SFrank van der Linden 
encode_removexattr(struct xdr_stream * xdr,const char * name,struct compound_hdr * hdr)4803e1f0212SFrank van der Linden static void encode_removexattr(struct xdr_stream *xdr, const char *name,
4813e1f0212SFrank van der Linden 			       struct compound_hdr *hdr)
4823e1f0212SFrank van der Linden {
4833e1f0212SFrank van der Linden 	encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
4843e1f0212SFrank van der Linden 	encode_string(xdr, strlen(name), name);
4853e1f0212SFrank van der Linden }
4863e1f0212SFrank van der Linden 
encode_listxattrs(struct xdr_stream * xdr,const struct nfs42_listxattrsargs * arg,struct compound_hdr * hdr)4873e1f0212SFrank van der Linden static void encode_listxattrs(struct xdr_stream *xdr,
4883e1f0212SFrank van der Linden 			     const struct nfs42_listxattrsargs *arg,
4893e1f0212SFrank van der Linden 			     struct compound_hdr *hdr)
4903e1f0212SFrank van der Linden {
4913e1f0212SFrank van der Linden 	__be32 *p;
4923e1f0212SFrank van der Linden 
4936c2190b3SChuck Lever 	encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
4943e1f0212SFrank van der Linden 
4953e1f0212SFrank van der Linden 	p = reserve_space(xdr, 12);
4963e1f0212SFrank van der Linden 	if (unlikely(!p))
4973e1f0212SFrank van der Linden 		return;
4983e1f0212SFrank van der Linden 
4993e1f0212SFrank van der Linden 	p = xdr_encode_hyper(p, arg->cookie);
5003e1f0212SFrank van der Linden 	/*
5013e1f0212SFrank van der Linden 	 * RFC 8276 says to specify the full max length of the LISTXATTRS
5023e1f0212SFrank van der Linden 	 * XDR reply. Count is set to the XDR length of the names array
5033e1f0212SFrank van der Linden 	 * plus the EOF marker. So, add the cookie and the names count.
5043e1f0212SFrank van der Linden 	 */
5053e1f0212SFrank van der Linden 	*p = cpu_to_be32(arg->count + 8 + 4);
5063e1f0212SFrank van der Linden }
5073e1f0212SFrank van der Linden 
5081c6dcbe5SAnna Schumaker /*
509f4ac1674SAnna Schumaker  * Encode ALLOCATE request
510f4ac1674SAnna Schumaker  */
nfs4_xdr_enc_allocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)511f4ac1674SAnna Schumaker static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
512f4ac1674SAnna Schumaker 				  struct xdr_stream *xdr,
5130096d39bSChristoph Hellwig 				  const void *data)
514f4ac1674SAnna Schumaker {
5150096d39bSChristoph Hellwig 	const struct nfs42_falloc_args *args = data;
516f4ac1674SAnna Schumaker 	struct compound_hdr hdr = {
517f4ac1674SAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
518f4ac1674SAnna Schumaker 	};
519f4ac1674SAnna Schumaker 
520f4ac1674SAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
521f4ac1674SAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
522f4ac1674SAnna Schumaker 	encode_putfh(xdr, args->falloc_fh, &hdr);
523f4ac1674SAnna Schumaker 	encode_allocate(xdr, args, &hdr);
5249a51940bSAnna Schumaker 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
525f4ac1674SAnna Schumaker 	encode_nops(&hdr);
526f4ac1674SAnna Schumaker }
527f4ac1674SAnna Schumaker 
528f4ac1674SAnna Schumaker /*
5292e72448bSAnna Schumaker  * Encode COPY request
5302e72448bSAnna Schumaker  */
nfs4_xdr_enc_copy(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)5312e72448bSAnna Schumaker static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
5322e72448bSAnna Schumaker 			      struct xdr_stream *xdr,
5330096d39bSChristoph Hellwig 			      const void *data)
5342e72448bSAnna Schumaker {
5350096d39bSChristoph Hellwig 	const struct nfs42_copy_args *args = data;
5362e72448bSAnna Schumaker 	struct compound_hdr hdr = {
5372e72448bSAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
5382e72448bSAnna Schumaker 	};
5392e72448bSAnna Schumaker 
5402e72448bSAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
5412e72448bSAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
5422e72448bSAnna Schumaker 	encode_putfh(xdr, args->src_fh, &hdr);
5432e72448bSAnna Schumaker 	encode_savefh(xdr, &hdr);
5442e72448bSAnna Schumaker 	encode_putfh(xdr, args->dst_fh, &hdr);
5452e72448bSAnna Schumaker 	encode_copy(xdr, args, &hdr);
54662164f31SOlga Kornievskaia 	if (args->sync)
547e0926934SOlga Kornievskaia 		encode_copy_commit(xdr, args, &hdr);
5482e72448bSAnna Schumaker 	encode_nops(&hdr);
5492e72448bSAnna Schumaker }
5502e72448bSAnna Schumaker 
5512e72448bSAnna Schumaker /*
552cb95deeaSOlga Kornievskaia  * Encode OFFLOAD_CANEL request
553cb95deeaSOlga Kornievskaia  */
nfs4_xdr_enc_offload_cancel(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)554cb95deeaSOlga Kornievskaia static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
555cb95deeaSOlga Kornievskaia 					struct xdr_stream *xdr,
556cb95deeaSOlga Kornievskaia 					const void *data)
557cb95deeaSOlga Kornievskaia {
558cb95deeaSOlga Kornievskaia 	const struct nfs42_offload_status_args *args = data;
559cb95deeaSOlga Kornievskaia 	struct compound_hdr hdr = {
560cb95deeaSOlga Kornievskaia 		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
561cb95deeaSOlga Kornievskaia 	};
562cb95deeaSOlga Kornievskaia 
563cb95deeaSOlga Kornievskaia 	encode_compound_hdr(xdr, req, &hdr);
564cb95deeaSOlga Kornievskaia 	encode_sequence(xdr, &args->osa_seq_args, &hdr);
565cb95deeaSOlga Kornievskaia 	encode_putfh(xdr, args->osa_src_fh, &hdr);
566cb95deeaSOlga Kornievskaia 	encode_offload_cancel(xdr, args, &hdr);
567cb95deeaSOlga Kornievskaia 	encode_nops(&hdr);
568cb95deeaSOlga Kornievskaia }
569cb95deeaSOlga Kornievskaia 
570cb95deeaSOlga Kornievskaia /*
5710491567bSOlga Kornievskaia  * Encode COPY_NOTIFY request
5720491567bSOlga Kornievskaia  */
nfs4_xdr_enc_copy_notify(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)5730491567bSOlga Kornievskaia static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
5740491567bSOlga Kornievskaia 				     struct xdr_stream *xdr,
5750491567bSOlga Kornievskaia 				     const void *data)
5760491567bSOlga Kornievskaia {
5770491567bSOlga Kornievskaia 	const struct nfs42_copy_notify_args *args = data;
5780491567bSOlga Kornievskaia 	struct compound_hdr hdr = {
5790491567bSOlga Kornievskaia 		.minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
5800491567bSOlga Kornievskaia 	};
5810491567bSOlga Kornievskaia 
5820491567bSOlga Kornievskaia 	encode_compound_hdr(xdr, req, &hdr);
5830491567bSOlga Kornievskaia 	encode_sequence(xdr, &args->cna_seq_args, &hdr);
5840491567bSOlga Kornievskaia 	encode_putfh(xdr, args->cna_src_fh, &hdr);
5850491567bSOlga Kornievskaia 	encode_copy_notify(xdr, args, &hdr);
5860491567bSOlga Kornievskaia 	encode_nops(&hdr);
5870491567bSOlga Kornievskaia }
5880491567bSOlga Kornievskaia 
5890491567bSOlga Kornievskaia /*
590624bd5b7SAnna Schumaker  * Encode DEALLOCATE request
591624bd5b7SAnna Schumaker  */
nfs4_xdr_enc_deallocate(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)592624bd5b7SAnna Schumaker static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
593624bd5b7SAnna Schumaker 				    struct xdr_stream *xdr,
5940096d39bSChristoph Hellwig 				    const void *data)
595624bd5b7SAnna Schumaker {
5960096d39bSChristoph Hellwig 	const struct nfs42_falloc_args *args = data;
597624bd5b7SAnna Schumaker 	struct compound_hdr hdr = {
598624bd5b7SAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
599624bd5b7SAnna Schumaker 	};
600624bd5b7SAnna Schumaker 
601624bd5b7SAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
602624bd5b7SAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
603624bd5b7SAnna Schumaker 	encode_putfh(xdr, args->falloc_fh, &hdr);
604624bd5b7SAnna Schumaker 	encode_deallocate(xdr, args, &hdr);
6059a51940bSAnna Schumaker 	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
606624bd5b7SAnna Schumaker 	encode_nops(&hdr);
607624bd5b7SAnna Schumaker }
608624bd5b7SAnna Schumaker 
609624bd5b7SAnna Schumaker /*
610c5675526SAnna Schumaker  * Encode READ_PLUS request
611c5675526SAnna Schumaker  */
nfs4_xdr_enc_read_plus(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)612c5675526SAnna Schumaker static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
613c5675526SAnna Schumaker 				   struct xdr_stream *xdr,
614c5675526SAnna Schumaker 				   const void *data)
615c5675526SAnna Schumaker {
616c5675526SAnna Schumaker 	const struct nfs_pgio_args *args = data;
617c5675526SAnna Schumaker 	struct compound_hdr hdr = {
618c5675526SAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
619c5675526SAnna Schumaker 	};
620c5675526SAnna Schumaker 
621c5675526SAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
622c5675526SAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
623c5675526SAnna Schumaker 	encode_putfh(xdr, args->fh, &hdr);
624c5675526SAnna Schumaker 	encode_read_plus(xdr, args, &hdr);
625c5675526SAnna Schumaker 
6268d18f6c5SAnna Schumaker 	rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count,
6278d18f6c5SAnna Schumaker 				hdr.replen - READ_PLUS_SEGMENT_SIZE_DIFF);
628c5675526SAnna Schumaker 	encode_nops(&hdr);
629c5675526SAnna Schumaker }
630c5675526SAnna Schumaker 
631c5675526SAnna Schumaker /*
6321c6dcbe5SAnna Schumaker  * Encode SEEK request
6331c6dcbe5SAnna Schumaker  */
nfs4_xdr_enc_seek(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)6341c6dcbe5SAnna Schumaker static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
6351c6dcbe5SAnna Schumaker 			      struct xdr_stream *xdr,
6360096d39bSChristoph Hellwig 			      const void *data)
6371c6dcbe5SAnna Schumaker {
6380096d39bSChristoph Hellwig 	const struct nfs42_seek_args *args = data;
6391c6dcbe5SAnna Schumaker 	struct compound_hdr hdr = {
6401c6dcbe5SAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
6411c6dcbe5SAnna Schumaker 	};
6421c6dcbe5SAnna Schumaker 
6431c6dcbe5SAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
6441c6dcbe5SAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
6451c6dcbe5SAnna Schumaker 	encode_putfh(xdr, args->sa_fh, &hdr);
6461c6dcbe5SAnna Schumaker 	encode_seek(xdr, args, &hdr);
6471c6dcbe5SAnna Schumaker 	encode_nops(&hdr);
6481c6dcbe5SAnna Schumaker }
6491c6dcbe5SAnna Schumaker 
650be3a5d23STrond Myklebust /*
651be3a5d23STrond Myklebust  * Encode LAYOUTSTATS request
652be3a5d23STrond Myklebust  */
nfs4_xdr_enc_layoutstats(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)653be3a5d23STrond Myklebust static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
654be3a5d23STrond Myklebust 				     struct xdr_stream *xdr,
6550096d39bSChristoph Hellwig 				     const void *data)
656be3a5d23STrond Myklebust {
6570096d39bSChristoph Hellwig 	const struct nfs42_layoutstat_args *args = data;
658be3a5d23STrond Myklebust 	int i;
659be3a5d23STrond Myklebust 
660be3a5d23STrond Myklebust 	struct compound_hdr hdr = {
661be3a5d23STrond Myklebust 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
662be3a5d23STrond Myklebust 	};
663be3a5d23STrond Myklebust 
664be3a5d23STrond Myklebust 	encode_compound_hdr(xdr, req, &hdr);
665be3a5d23STrond Myklebust 	encode_sequence(xdr, &args->seq_args, &hdr);
666be3a5d23STrond Myklebust 	encode_putfh(xdr, args->fh, &hdr);
667be3a5d23STrond Myklebust 	WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
668be3a5d23STrond Myklebust 	for (i = 0; i < args->num_dev; i++)
669be3a5d23STrond Myklebust 		encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
670be3a5d23STrond Myklebust 	encode_nops(&hdr);
671be3a5d23STrond Myklebust }
672be3a5d23STrond Myklebust 
67336022770SPeng Tao /*
67436022770SPeng Tao  * Encode CLONE request
67536022770SPeng Tao  */
nfs4_xdr_enc_clone(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)67636022770SPeng Tao static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
67736022770SPeng Tao 			       struct xdr_stream *xdr,
6780096d39bSChristoph Hellwig 			       const void *data)
67936022770SPeng Tao {
6800096d39bSChristoph Hellwig 	const struct nfs42_clone_args *args = data;
68136022770SPeng Tao 	struct compound_hdr hdr = {
68236022770SPeng Tao 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
68336022770SPeng Tao 	};
68436022770SPeng Tao 
68536022770SPeng Tao 	encode_compound_hdr(xdr, req, &hdr);
68636022770SPeng Tao 	encode_sequence(xdr, &args->seq_args, &hdr);
68736022770SPeng Tao 	encode_putfh(xdr, args->src_fh, &hdr);
68836022770SPeng Tao 	encode_savefh(xdr, &hdr);
68936022770SPeng Tao 	encode_putfh(xdr, args->dst_fh, &hdr);
69036022770SPeng Tao 	encode_clone(xdr, args, &hdr);
69136022770SPeng Tao 	encode_getfattr(xdr, args->dst_bitmask, &hdr);
69236022770SPeng Tao 	encode_nops(&hdr);
69336022770SPeng Tao }
69436022770SPeng Tao 
6953eb86093STrond Myklebust /*
6963eb86093STrond Myklebust  * Encode LAYOUTERROR request
6973eb86093STrond Myklebust  */
nfs4_xdr_enc_layouterror(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)6983eb86093STrond Myklebust static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
6993eb86093STrond Myklebust 				     struct xdr_stream *xdr,
7003eb86093STrond Myklebust 				     const void *data)
7013eb86093STrond Myklebust {
7023eb86093STrond Myklebust 	const struct nfs42_layouterror_args *args = data;
7033eb86093STrond Myklebust 	struct compound_hdr hdr = {
7043eb86093STrond Myklebust 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
7053eb86093STrond Myklebust 	};
7063eb86093STrond Myklebust 	int i;
7073eb86093STrond Myklebust 
7083eb86093STrond Myklebust 	encode_compound_hdr(xdr, req, &hdr);
7093eb86093STrond Myklebust 	encode_sequence(xdr, &args->seq_args, &hdr);
7103eb86093STrond Myklebust 	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
7113eb86093STrond Myklebust 	for (i = 0; i < args->num_errors; i++)
7123eb86093STrond Myklebust 		encode_layouterror(xdr, &args->errors[i], &hdr);
7133eb86093STrond Myklebust 	encode_nops(&hdr);
7143eb86093STrond Myklebust }
7153eb86093STrond Myklebust 
71631f1bd8fSAnna Schumaker /*
71731f1bd8fSAnna Schumaker  * Encode SETXATTR request
71831f1bd8fSAnna Schumaker  */
nfs4_xdr_enc_setxattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)71931f1bd8fSAnna Schumaker static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
72031f1bd8fSAnna Schumaker 				  const void *data)
72131f1bd8fSAnna Schumaker {
72231f1bd8fSAnna Schumaker 	const struct nfs42_setxattrargs *args = data;
72331f1bd8fSAnna Schumaker 	struct compound_hdr hdr = {
72431f1bd8fSAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
72531f1bd8fSAnna Schumaker 	};
72631f1bd8fSAnna Schumaker 
72731f1bd8fSAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
72831f1bd8fSAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
72931f1bd8fSAnna Schumaker 	encode_putfh(xdr, args->fh, &hdr);
73031f1bd8fSAnna Schumaker 	encode_setxattr(xdr, args, &hdr);
73186e2e1f6SAnna Schumaker 	encode_getfattr(xdr, args->bitmask, &hdr);
73231f1bd8fSAnna Schumaker 	encode_nops(&hdr);
73331f1bd8fSAnna Schumaker }
73431f1bd8fSAnna Schumaker 
73531f1bd8fSAnna Schumaker /*
73631f1bd8fSAnna Schumaker  * Encode GETXATTR request
73731f1bd8fSAnna Schumaker  */
nfs4_xdr_enc_getxattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)73831f1bd8fSAnna Schumaker static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
73931f1bd8fSAnna Schumaker 				  const void *data)
74031f1bd8fSAnna Schumaker {
74131f1bd8fSAnna Schumaker 	const struct nfs42_getxattrargs *args = data;
74231f1bd8fSAnna Schumaker 	struct compound_hdr hdr = {
74331f1bd8fSAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
74431f1bd8fSAnna Schumaker 	};
74531f1bd8fSAnna Schumaker 	uint32_t replen;
74631f1bd8fSAnna Schumaker 
74731f1bd8fSAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
74831f1bd8fSAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
74931f1bd8fSAnna Schumaker 	encode_putfh(xdr, args->fh, &hdr);
75031f1bd8fSAnna Schumaker 	replen = hdr.replen + op_decode_hdr_maxsz + 1;
75131f1bd8fSAnna Schumaker 	encode_getxattr(xdr, args->xattr_name, &hdr);
75231f1bd8fSAnna Schumaker 
75331f1bd8fSAnna Schumaker 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
75431f1bd8fSAnna Schumaker 				replen);
75531f1bd8fSAnna Schumaker 
75631f1bd8fSAnna Schumaker 	encode_nops(&hdr);
75731f1bd8fSAnna Schumaker }
75831f1bd8fSAnna Schumaker 
75931f1bd8fSAnna Schumaker /*
76031f1bd8fSAnna Schumaker  * Encode LISTXATTR request
76131f1bd8fSAnna Schumaker  */
nfs4_xdr_enc_listxattrs(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)76231f1bd8fSAnna Schumaker static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
76331f1bd8fSAnna Schumaker 				    struct xdr_stream *xdr, const void *data)
76431f1bd8fSAnna Schumaker {
76531f1bd8fSAnna Schumaker 	const struct nfs42_listxattrsargs *args = data;
76631f1bd8fSAnna Schumaker 	struct compound_hdr hdr = {
76731f1bd8fSAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
76831f1bd8fSAnna Schumaker 	};
76931f1bd8fSAnna Schumaker 	uint32_t replen;
77031f1bd8fSAnna Schumaker 
77131f1bd8fSAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
77231f1bd8fSAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
77331f1bd8fSAnna Schumaker 	encode_putfh(xdr, args->fh, &hdr);
77431f1bd8fSAnna Schumaker 	replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1;
77531f1bd8fSAnna Schumaker 	encode_listxattrs(xdr, args, &hdr);
77631f1bd8fSAnna Schumaker 
77731f1bd8fSAnna Schumaker 	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen);
77831f1bd8fSAnna Schumaker 
77931f1bd8fSAnna Schumaker 	encode_nops(&hdr);
78031f1bd8fSAnna Schumaker }
78131f1bd8fSAnna Schumaker 
78231f1bd8fSAnna Schumaker /*
78331f1bd8fSAnna Schumaker  * Encode REMOVEXATTR request
78431f1bd8fSAnna Schumaker  */
nfs4_xdr_enc_removexattr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)78531f1bd8fSAnna Schumaker static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
78631f1bd8fSAnna Schumaker 				     struct xdr_stream *xdr, const void *data)
78731f1bd8fSAnna Schumaker {
78831f1bd8fSAnna Schumaker 	const struct nfs42_removexattrargs *args = data;
78931f1bd8fSAnna Schumaker 	struct compound_hdr hdr = {
79031f1bd8fSAnna Schumaker 		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
79131f1bd8fSAnna Schumaker 	};
79231f1bd8fSAnna Schumaker 
79331f1bd8fSAnna Schumaker 	encode_compound_hdr(xdr, req, &hdr);
79431f1bd8fSAnna Schumaker 	encode_sequence(xdr, &args->seq_args, &hdr);
79531f1bd8fSAnna Schumaker 	encode_putfh(xdr, args->fh, &hdr);
79631f1bd8fSAnna Schumaker 	encode_removexattr(xdr, args->xattr_name, &hdr);
79731f1bd8fSAnna Schumaker 	encode_nops(&hdr);
79831f1bd8fSAnna Schumaker }
79931f1bd8fSAnna Schumaker 
decode_allocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)800f4ac1674SAnna Schumaker static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
801f4ac1674SAnna Schumaker {
802f4ac1674SAnna Schumaker 	return decode_op_hdr(xdr, OP_ALLOCATE);
803f4ac1674SAnna Schumaker }
804f4ac1674SAnna Schumaker 
decode_write_response(struct xdr_stream * xdr,struct nfs42_write_res * res)8052e72448bSAnna Schumaker static int decode_write_response(struct xdr_stream *xdr,
8062e72448bSAnna Schumaker 				 struct nfs42_write_res *res)
8072e72448bSAnna Schumaker {
8082e72448bSAnna Schumaker 	__be32 *p;
80967aa7444SOlga Kornievskaia 	int status, count;
8102e72448bSAnna Schumaker 
81167aa7444SOlga Kornievskaia 	p = xdr_inline_decode(xdr, 4);
8122e72448bSAnna Schumaker 	if (unlikely(!p))
813eb72f484SChuck Lever 		return -EIO;
81467aa7444SOlga Kornievskaia 	count = be32_to_cpup(p);
81567aa7444SOlga Kornievskaia 	if (count > 1)
8166fdf339bSTrond Myklebust 		return -EREMOTEIO;
81767aa7444SOlga Kornievskaia 	else if (count == 1) {
81867aa7444SOlga Kornievskaia 		status = decode_opaque_fixed(xdr, &res->stateid,
81967aa7444SOlga Kornievskaia 				NFS4_STATEID_SIZE);
82067aa7444SOlga Kornievskaia 		if (unlikely(status))
821eb72f484SChuck Lever 			return -EIO;
8226fdf339bSTrond Myklebust 	}
82367aa7444SOlga Kornievskaia 	p = xdr_inline_decode(xdr, 8 + 4);
82467aa7444SOlga Kornievskaia 	if (unlikely(!p))
825eb72f484SChuck Lever 		return -EIO;
8262e72448bSAnna Schumaker 	p = xdr_decode_hyper(p, &res->count);
8272e72448bSAnna Schumaker 	res->verifier.committed = be32_to_cpup(p);
8282e72448bSAnna Schumaker 	return decode_verifier(xdr, &res->verifier.verifier);
8292e72448bSAnna Schumaker }
8302e72448bSAnna Schumaker 
decode_nl4_server(struct xdr_stream * xdr,struct nl4_server * ns)8310491567bSOlga Kornievskaia static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
8320491567bSOlga Kornievskaia {
8330491567bSOlga Kornievskaia 	struct nfs42_netaddr *naddr;
8340491567bSOlga Kornievskaia 	uint32_t dummy;
8350491567bSOlga Kornievskaia 	char *dummy_str;
8360491567bSOlga Kornievskaia 	__be32 *p;
8370491567bSOlga Kornievskaia 	int status;
8380491567bSOlga Kornievskaia 
8390491567bSOlga Kornievskaia 	/* nl_type */
8400491567bSOlga Kornievskaia 	p = xdr_inline_decode(xdr, 4);
8410491567bSOlga Kornievskaia 	if (unlikely(!p))
8420491567bSOlga Kornievskaia 		return -EIO;
8430491567bSOlga Kornievskaia 	ns->nl4_type = be32_to_cpup(p);
8440491567bSOlga Kornievskaia 	switch (ns->nl4_type) {
8450491567bSOlga Kornievskaia 	case NL4_NAME:
8460491567bSOlga Kornievskaia 	case NL4_URL:
8470491567bSOlga Kornievskaia 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
8480491567bSOlga Kornievskaia 		if (unlikely(status))
8490491567bSOlga Kornievskaia 			return status;
8500491567bSOlga Kornievskaia 		if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
8510491567bSOlga Kornievskaia 			return -EIO;
8520491567bSOlga Kornievskaia 		memcpy(&ns->u.nl4_str, dummy_str, dummy);
8530491567bSOlga Kornievskaia 		ns->u.nl4_str_sz = dummy;
8540491567bSOlga Kornievskaia 		break;
8550491567bSOlga Kornievskaia 	case NL4_NETADDR:
8560491567bSOlga Kornievskaia 		naddr = &ns->u.nl4_addr;
8570491567bSOlga Kornievskaia 
8580491567bSOlga Kornievskaia 		/* netid string */
8590491567bSOlga Kornievskaia 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
8600491567bSOlga Kornievskaia 		if (unlikely(status))
8610491567bSOlga Kornievskaia 			return status;
8620491567bSOlga Kornievskaia 		if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
8630491567bSOlga Kornievskaia 			return -EIO;
8640491567bSOlga Kornievskaia 		naddr->netid_len = dummy;
8650491567bSOlga Kornievskaia 		memcpy(naddr->netid, dummy_str, naddr->netid_len);
8660491567bSOlga Kornievskaia 
8670491567bSOlga Kornievskaia 		/* uaddr string */
8680491567bSOlga Kornievskaia 		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
8690491567bSOlga Kornievskaia 		if (unlikely(status))
8700491567bSOlga Kornievskaia 			return status;
8710491567bSOlga Kornievskaia 		if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
8720491567bSOlga Kornievskaia 			return -EIO;
8730491567bSOlga Kornievskaia 		naddr->addr_len = dummy;
8740491567bSOlga Kornievskaia 		memcpy(naddr->addr, dummy_str, naddr->addr_len);
8750491567bSOlga Kornievskaia 		break;
8760491567bSOlga Kornievskaia 	default:
8770491567bSOlga Kornievskaia 		WARN_ON_ONCE(1);
8780491567bSOlga Kornievskaia 		return -EIO;
8790491567bSOlga Kornievskaia 	}
8800491567bSOlga Kornievskaia 	return 0;
8810491567bSOlga Kornievskaia }
8820491567bSOlga Kornievskaia 
decode_copy_requirements(struct xdr_stream * xdr,struct nfs42_copy_res * res)8832e72448bSAnna Schumaker static int decode_copy_requirements(struct xdr_stream *xdr,
8842e72448bSAnna Schumaker 				    struct nfs42_copy_res *res) {
8852e72448bSAnna Schumaker 	__be32 *p;
8862e72448bSAnna Schumaker 
8872e72448bSAnna Schumaker 	p = xdr_inline_decode(xdr, 4 + 4);
8882e72448bSAnna Schumaker 	if (unlikely(!p))
889eb72f484SChuck Lever 		return -EIO;
8902e72448bSAnna Schumaker 
8912e72448bSAnna Schumaker 	res->consecutive = be32_to_cpup(p++);
8922e72448bSAnna Schumaker 	res->synchronous = be32_to_cpup(p++);
8932e72448bSAnna Schumaker 	return 0;
8942e72448bSAnna Schumaker }
8952e72448bSAnna Schumaker 
decode_copy(struct xdr_stream * xdr,struct nfs42_copy_res * res)8962e72448bSAnna Schumaker static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
8972e72448bSAnna Schumaker {
8982e72448bSAnna Schumaker 	int status;
8992e72448bSAnna Schumaker 
9002e72448bSAnna Schumaker 	status = decode_op_hdr(xdr, OP_COPY);
9012e72448bSAnna Schumaker 	if (status == NFS4ERR_OFFLOAD_NO_REQS) {
9022e72448bSAnna Schumaker 		status = decode_copy_requirements(xdr, res);
9032e72448bSAnna Schumaker 		if (status)
9042e72448bSAnna Schumaker 			return status;
9052e72448bSAnna Schumaker 		return NFS4ERR_OFFLOAD_NO_REQS;
9062e72448bSAnna Schumaker 	} else if (status)
9072e72448bSAnna Schumaker 		return status;
9082e72448bSAnna Schumaker 
9092e72448bSAnna Schumaker 	status = decode_write_response(xdr, &res->write_res);
9102e72448bSAnna Schumaker 	if (status)
9112e72448bSAnna Schumaker 		return status;
9122e72448bSAnna Schumaker 
9132e72448bSAnna Schumaker 	return decode_copy_requirements(xdr, res);
9142e72448bSAnna Schumaker }
9152e72448bSAnna Schumaker 
decode_offload_cancel(struct xdr_stream * xdr,struct nfs42_offload_status_res * res)916cb95deeaSOlga Kornievskaia static int decode_offload_cancel(struct xdr_stream *xdr,
917cb95deeaSOlga Kornievskaia 				 struct nfs42_offload_status_res *res)
918cb95deeaSOlga Kornievskaia {
919cb95deeaSOlga Kornievskaia 	return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
920cb95deeaSOlga Kornievskaia }
921cb95deeaSOlga Kornievskaia 
decode_copy_notify(struct xdr_stream * xdr,struct nfs42_copy_notify_res * res)9220491567bSOlga Kornievskaia static int decode_copy_notify(struct xdr_stream *xdr,
9230491567bSOlga Kornievskaia 			      struct nfs42_copy_notify_res *res)
9240491567bSOlga Kornievskaia {
9250491567bSOlga Kornievskaia 	__be32 *p;
9260491567bSOlga Kornievskaia 	int status, count;
9270491567bSOlga Kornievskaia 
9280491567bSOlga Kornievskaia 	status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
9290491567bSOlga Kornievskaia 	if (status)
9300491567bSOlga Kornievskaia 		return status;
9310491567bSOlga Kornievskaia 	/* cnr_lease_time */
9320491567bSOlga Kornievskaia 	p = xdr_inline_decode(xdr, 12);
9330491567bSOlga Kornievskaia 	if (unlikely(!p))
9340491567bSOlga Kornievskaia 		return -EIO;
9350491567bSOlga Kornievskaia 	p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
9360491567bSOlga Kornievskaia 	res->cnr_lease_time.nseconds = be32_to_cpup(p);
9370491567bSOlga Kornievskaia 
9380491567bSOlga Kornievskaia 	status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
9390491567bSOlga Kornievskaia 	if (unlikely(status))
9400491567bSOlga Kornievskaia 		return -EIO;
9410491567bSOlga Kornievskaia 
9420491567bSOlga Kornievskaia 	/* number of source addresses */
9430491567bSOlga Kornievskaia 	p = xdr_inline_decode(xdr, 4);
9440491567bSOlga Kornievskaia 	if (unlikely(!p))
9450491567bSOlga Kornievskaia 		return -EIO;
9460491567bSOlga Kornievskaia 
9470491567bSOlga Kornievskaia 	count = be32_to_cpup(p);
9480491567bSOlga Kornievskaia 	if (count > 1)
9490491567bSOlga Kornievskaia 		pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
9500491567bSOlga Kornievskaia 			 __func__, count);
9510491567bSOlga Kornievskaia 
9520491567bSOlga Kornievskaia 	status = decode_nl4_server(xdr, &res->cnr_src);
9530491567bSOlga Kornievskaia 	if (unlikely(status))
9540491567bSOlga Kornievskaia 		return -EIO;
9550491567bSOlga Kornievskaia 	return 0;
9560491567bSOlga Kornievskaia }
9570491567bSOlga Kornievskaia 
decode_deallocate(struct xdr_stream * xdr,struct nfs42_falloc_res * res)958624bd5b7SAnna Schumaker static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
959624bd5b7SAnna Schumaker {
960624bd5b7SAnna Schumaker 	return decode_op_hdr(xdr, OP_DEALLOCATE);
961624bd5b7SAnna Schumaker }
962624bd5b7SAnna Schumaker 
963d3b00a80SAnna Schumaker struct read_plus_segment {
964d3b00a80SAnna Schumaker 	enum data_content4 type;
965c5675526SAnna Schumaker 	uint64_t offset;
966d3b00a80SAnna Schumaker 	union {
967d3b00a80SAnna Schumaker 		struct {
968d3b00a80SAnna Schumaker 			uint64_t length;
969d3b00a80SAnna Schumaker 		} hole;
970c5675526SAnna Schumaker 
971d3b00a80SAnna Schumaker 		struct {
972d3b00a80SAnna Schumaker 			uint32_t length;
973d3b00a80SAnna Schumaker 			unsigned int from;
974d3b00a80SAnna Schumaker 		} data;
975d3b00a80SAnna Schumaker 	};
976d3b00a80SAnna Schumaker };
977c5675526SAnna Schumaker 
read_plus_segment_length(struct read_plus_segment * seg)978d3b00a80SAnna Schumaker static inline uint64_t read_plus_segment_length(struct read_plus_segment *seg)
979c05eafadSAnna Schumaker {
980d3b00a80SAnna Schumaker 	return seg->type == NFS4_CONTENT_DATA ? seg->data.length : seg->hole.length;
981d3b00a80SAnna Schumaker }
982d3b00a80SAnna Schumaker 
decode_read_plus_segment(struct xdr_stream * xdr,struct read_plus_segment * seg)983d3b00a80SAnna Schumaker static int decode_read_plus_segment(struct xdr_stream *xdr,
984d3b00a80SAnna Schumaker 				    struct read_plus_segment *seg)
985d3b00a80SAnna Schumaker {
986c05eafadSAnna Schumaker 	__be32 *p;
987c05eafadSAnna Schumaker 
988d3b00a80SAnna Schumaker 	p = xdr_inline_decode(xdr, 4);
989503b934aSTrond Myklebust 	if (!p)
990d3b00a80SAnna Schumaker 		return -EIO;
991d3b00a80SAnna Schumaker 	seg->type = be32_to_cpup(p++);
992c05eafadSAnna Schumaker 
993d3b00a80SAnna Schumaker 	p = xdr_inline_decode(xdr, seg->type == NFS4_CONTENT_DATA ? 12 : 16);
994d3b00a80SAnna Schumaker 	if (!p)
995d3b00a80SAnna Schumaker 		return -EIO;
996d3b00a80SAnna Schumaker 	p = xdr_decode_hyper(p, &seg->offset);
997c05eafadSAnna Schumaker 
998d3b00a80SAnna Schumaker 	if (seg->type == NFS4_CONTENT_DATA) {
999d3b00a80SAnna Schumaker 		struct xdr_buf buf;
1000d3b00a80SAnna Schumaker 		uint32_t len = be32_to_cpup(p);
1001d3b00a80SAnna Schumaker 
1002d3b00a80SAnna Schumaker 		seg->data.length = len;
1003d3b00a80SAnna Schumaker 		seg->data.from = xdr_stream_pos(xdr);
1004d3b00a80SAnna Schumaker 
1005d3b00a80SAnna Schumaker 		if (!xdr_stream_subsegment(xdr, &buf, xdr_align_size(len)))
1006d3b00a80SAnna Schumaker 			return -EIO;
1007d3b00a80SAnna Schumaker 	} else if (seg->type == NFS4_CONTENT_HOLE) {
1008d3b00a80SAnna Schumaker 		xdr_decode_hyper(p, &seg->hole.length);
1009d3b00a80SAnna Schumaker 	} else
1010d3b00a80SAnna Schumaker 		return -EINVAL;
1011c05eafadSAnna Schumaker 	return 0;
1012c05eafadSAnna Schumaker }
1013c05eafadSAnna Schumaker 
process_read_plus_segment(struct xdr_stream * xdr,struct nfs_pgio_args * args,struct nfs_pgio_res * res,struct read_plus_segment * seg)1014d3b00a80SAnna Schumaker static int process_read_plus_segment(struct xdr_stream *xdr,
1015d3b00a80SAnna Schumaker 				     struct nfs_pgio_args *args,
1016d3b00a80SAnna Schumaker 				     struct nfs_pgio_res *res,
1017d3b00a80SAnna Schumaker 				     struct read_plus_segment *seg)
1018d3b00a80SAnna Schumaker {
1019d3b00a80SAnna Schumaker 	unsigned long offset = seg->offset;
1020d3b00a80SAnna Schumaker 	unsigned long length = read_plus_segment_length(seg);
1021d3b00a80SAnna Schumaker 	unsigned int bufpos;
1022d3b00a80SAnna Schumaker 
1023d3b00a80SAnna Schumaker 	if (offset + length < args->offset)
1024d3b00a80SAnna Schumaker 		return 0;
1025d3b00a80SAnna Schumaker 	else if (offset > args->offset + args->count) {
1026d3b00a80SAnna Schumaker 		res->eof = 0;
1027d3b00a80SAnna Schumaker 		return 0;
1028d3b00a80SAnna Schumaker 	} else if (offset < args->offset) {
1029d3b00a80SAnna Schumaker 		length -= (args->offset - offset);
1030d3b00a80SAnna Schumaker 		offset = args->offset;
1031d3b00a80SAnna Schumaker 	} else if (offset + length > args->offset + args->count) {
1032d3b00a80SAnna Schumaker 		length = (args->offset + args->count) - offset;
1033d3b00a80SAnna Schumaker 		res->eof = 0;
1034d3b00a80SAnna Schumaker 	}
1035d3b00a80SAnna Schumaker 
1036d3b00a80SAnna Schumaker 	bufpos = xdr->buf->head[0].iov_len + (offset - args->offset);
1037d3b00a80SAnna Schumaker 	if (seg->type == NFS4_CONTENT_HOLE)
1038d3b00a80SAnna Schumaker 		return xdr_stream_zero(xdr, bufpos, length);
1039d3b00a80SAnna Schumaker 	else
1040d3b00a80SAnna Schumaker 		return xdr_stream_move_subsegment(xdr, seg->data.from, bufpos, length);
1041d3b00a80SAnna Schumaker }
1042d3b00a80SAnna Schumaker 
decode_read_plus(struct xdr_stream * xdr,struct nfs_pgio_res * res)1043c5675526SAnna Schumaker static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
1044c5675526SAnna Schumaker {
104582f98c8bSTrond Myklebust 	struct nfs_pgio_header *hdr =
104682f98c8bSTrond Myklebust 		container_of(res, struct nfs_pgio_header, res);
104782f98c8bSTrond Myklebust 	struct nfs_pgio_args *args = &hdr->args;
1048d3b00a80SAnna Schumaker 	uint32_t segments;
1049d3b00a80SAnna Schumaker 	struct read_plus_segment *segs;
1050bff049a3SAnna Schumaker 	int status, i;
1051c5675526SAnna Schumaker 	__be32 *p;
1052c5675526SAnna Schumaker 
1053c5675526SAnna Schumaker 	status = decode_op_hdr(xdr, OP_READ_PLUS);
1054c5675526SAnna Schumaker 	if (status)
1055c5675526SAnna Schumaker 		return status;
1056c5675526SAnna Schumaker 
1057c5675526SAnna Schumaker 	p = xdr_inline_decode(xdr, 4 + 4);
1058c5675526SAnna Schumaker 	if (unlikely(!p))
1059c5675526SAnna Schumaker 		return -EIO;
1060c5675526SAnna Schumaker 
10611ee63101STrond Myklebust 	res->count = 0;
1062d3b00a80SAnna Schumaker 	res->eof = be32_to_cpup(p++);
1063c5675526SAnna Schumaker 	segments = be32_to_cpup(p++);
1064c5675526SAnna Schumaker 	if (segments == 0)
1065bb05a617SAnna Schumaker 		return 0;
1066d3b00a80SAnna Schumaker 
1067d3b00a80SAnna Schumaker 	segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL);
1068d3b00a80SAnna Schumaker 	if (!segs)
1069d3b00a80SAnna Schumaker 		return -ENOMEM;
1070d3b00a80SAnna Schumaker 
1071d3b00a80SAnna Schumaker 	for (i = 0; i < segments; i++) {
1072d3b00a80SAnna Schumaker 		status = decode_read_plus_segment(xdr, &segs[i]);
1073d3b00a80SAnna Schumaker 		if (status < 0)
1074d3b00a80SAnna Schumaker 			goto out;
1075bff049a3SAnna Schumaker 	}
1076c5675526SAnna Schumaker 
1077d3b00a80SAnna Schumaker 	xdr_set_pagelen(xdr, xdr_align_size(args->count));
1078d3b00a80SAnna Schumaker 	for (i = segments; i > 0; i--)
1079d3b00a80SAnna Schumaker 		res->count += process_read_plus_segment(xdr, args, res, &segs[i-1]);
1080d3b00a80SAnna Schumaker 	status = 0;
1081d3b00a80SAnna Schumaker 
1082c5675526SAnna Schumaker out:
1083d3b00a80SAnna Schumaker 	kfree(segs);
1084d3b00a80SAnna Schumaker 	return status;
1085c5675526SAnna Schumaker }
1086c5675526SAnna Schumaker 
decode_seek(struct xdr_stream * xdr,struct nfs42_seek_res * res)10871c6dcbe5SAnna Schumaker static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
10881c6dcbe5SAnna Schumaker {
10891c6dcbe5SAnna Schumaker 	int status;
10901c6dcbe5SAnna Schumaker 	__be32 *p;
10911c6dcbe5SAnna Schumaker 
10921c6dcbe5SAnna Schumaker 	status = decode_op_hdr(xdr, OP_SEEK);
10931c6dcbe5SAnna Schumaker 	if (status)
10941c6dcbe5SAnna Schumaker 		return status;
10951c6dcbe5SAnna Schumaker 
10961c6dcbe5SAnna Schumaker 	p = xdr_inline_decode(xdr, 4 + 8);
10971c6dcbe5SAnna Schumaker 	if (unlikely(!p))
1098eb72f484SChuck Lever 		return -EIO;
10991c6dcbe5SAnna Schumaker 
11001c6dcbe5SAnna Schumaker 	res->sr_eof = be32_to_cpup(p++);
11011c6dcbe5SAnna Schumaker 	p = xdr_decode_hyper(p, &res->sr_offset);
11021c6dcbe5SAnna Schumaker 	return 0;
11031c6dcbe5SAnna Schumaker }
11041c6dcbe5SAnna Schumaker 
decode_layoutstats(struct xdr_stream * xdr)110519cf6335SPeng Tao static int decode_layoutstats(struct xdr_stream *xdr)
1106be3a5d23STrond Myklebust {
1107da2e8127STrond Myklebust 	return decode_op_hdr(xdr, OP_LAYOUTSTATS);
1108be3a5d23STrond Myklebust }
1109be3a5d23STrond Myklebust 
decode_clone(struct xdr_stream * xdr)111036022770SPeng Tao static int decode_clone(struct xdr_stream *xdr)
111136022770SPeng Tao {
111236022770SPeng Tao 	return decode_op_hdr(xdr, OP_CLONE);
111336022770SPeng Tao }
111436022770SPeng Tao 
decode_layouterror(struct xdr_stream * xdr)11153eb86093STrond Myklebust static int decode_layouterror(struct xdr_stream *xdr)
11163eb86093STrond Myklebust {
11173eb86093STrond Myklebust 	return decode_op_hdr(xdr, OP_LAYOUTERROR);
11183eb86093STrond Myklebust }
11193eb86093STrond Myklebust 
decode_setxattr(struct xdr_stream * xdr,struct nfs4_change_info * cinfo)112004b4c9fbSAnna Schumaker static int decode_setxattr(struct xdr_stream *xdr,
112104b4c9fbSAnna Schumaker 			   struct nfs4_change_info *cinfo)
112204b4c9fbSAnna Schumaker {
112304b4c9fbSAnna Schumaker 	int status;
112404b4c9fbSAnna Schumaker 
112504b4c9fbSAnna Schumaker 	status = decode_op_hdr(xdr, OP_SETXATTR);
112604b4c9fbSAnna Schumaker 	if (status)
112704b4c9fbSAnna Schumaker 		goto out;
112804b4c9fbSAnna Schumaker 	status = decode_change_info(xdr, cinfo);
112904b4c9fbSAnna Schumaker out:
113004b4c9fbSAnna Schumaker 	return status;
113104b4c9fbSAnna Schumaker }
113204b4c9fbSAnna Schumaker 
decode_getxattr(struct xdr_stream * xdr,struct nfs42_getxattrres * res,struct rpc_rqst * req)113304b4c9fbSAnna Schumaker static int decode_getxattr(struct xdr_stream *xdr,
113404b4c9fbSAnna Schumaker 			   struct nfs42_getxattrres *res,
113504b4c9fbSAnna Schumaker 			   struct rpc_rqst *req)
113604b4c9fbSAnna Schumaker {
113704b4c9fbSAnna Schumaker 	int status;
113804b4c9fbSAnna Schumaker 	__be32 *p;
113904b4c9fbSAnna Schumaker 	u32 len, rdlen;
114004b4c9fbSAnna Schumaker 
114104b4c9fbSAnna Schumaker 	status = decode_op_hdr(xdr, OP_GETXATTR);
114204b4c9fbSAnna Schumaker 	if (status)
114304b4c9fbSAnna Schumaker 		return status;
114404b4c9fbSAnna Schumaker 
114504b4c9fbSAnna Schumaker 	p = xdr_inline_decode(xdr, 4);
114604b4c9fbSAnna Schumaker 	if (unlikely(!p))
114704b4c9fbSAnna Schumaker 		return -EIO;
114804b4c9fbSAnna Schumaker 
114904b4c9fbSAnna Schumaker 	len = be32_to_cpup(p);
115004b4c9fbSAnna Schumaker 
115104b4c9fbSAnna Schumaker 	/*
115204b4c9fbSAnna Schumaker 	 * Only check against the page length here. The actual
115304b4c9fbSAnna Schumaker 	 * requested length may be smaller, but that is only
115404b4c9fbSAnna Schumaker 	 * checked against after possibly caching a valid reply.
115504b4c9fbSAnna Schumaker 	 */
115604b4c9fbSAnna Schumaker 	if (len > req->rq_rcv_buf.page_len)
115704b4c9fbSAnna Schumaker 		return -ERANGE;
115804b4c9fbSAnna Schumaker 
115904b4c9fbSAnna Schumaker 	res->xattr_len = len;
116004b4c9fbSAnna Schumaker 
116104b4c9fbSAnna Schumaker 	if (len > 0) {
116204b4c9fbSAnna Schumaker 		rdlen = xdr_read_pages(xdr, len);
116304b4c9fbSAnna Schumaker 		if (rdlen < len)
116404b4c9fbSAnna Schumaker 			return -EIO;
116504b4c9fbSAnna Schumaker 	}
116604b4c9fbSAnna Schumaker 
116704b4c9fbSAnna Schumaker 	return 0;
116804b4c9fbSAnna Schumaker }
116904b4c9fbSAnna Schumaker 
decode_removexattr(struct xdr_stream * xdr,struct nfs4_change_info * cinfo)117004b4c9fbSAnna Schumaker static int decode_removexattr(struct xdr_stream *xdr,
117104b4c9fbSAnna Schumaker 			   struct nfs4_change_info *cinfo)
117204b4c9fbSAnna Schumaker {
117304b4c9fbSAnna Schumaker 	int status;
117404b4c9fbSAnna Schumaker 
117504b4c9fbSAnna Schumaker 	status = decode_op_hdr(xdr, OP_REMOVEXATTR);
117604b4c9fbSAnna Schumaker 	if (status)
117704b4c9fbSAnna Schumaker 		goto out;
117804b4c9fbSAnna Schumaker 
117904b4c9fbSAnna Schumaker 	status = decode_change_info(xdr, cinfo);
118004b4c9fbSAnna Schumaker out:
118104b4c9fbSAnna Schumaker 	return status;
118204b4c9fbSAnna Schumaker }
118304b4c9fbSAnna Schumaker 
decode_listxattrs(struct xdr_stream * xdr,struct nfs42_listxattrsres * res)118404b4c9fbSAnna Schumaker static int decode_listxattrs(struct xdr_stream *xdr,
118504b4c9fbSAnna Schumaker 			    struct nfs42_listxattrsres *res)
118604b4c9fbSAnna Schumaker {
118704b4c9fbSAnna Schumaker 	int status;
118804b4c9fbSAnna Schumaker 	__be32 *p;
118904b4c9fbSAnna Schumaker 	u32 count, len, ulen;
119004b4c9fbSAnna Schumaker 	size_t left, copied;
119104b4c9fbSAnna Schumaker 	char *buf;
119204b4c9fbSAnna Schumaker 
119304b4c9fbSAnna Schumaker 	status = decode_op_hdr(xdr, OP_LISTXATTRS);
119404b4c9fbSAnna Schumaker 	if (status) {
119504b4c9fbSAnna Schumaker 		/*
119604b4c9fbSAnna Schumaker 		 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
119704b4c9fbSAnna Schumaker 		 * should be translated to ERANGE.
119804b4c9fbSAnna Schumaker 		 */
119904b4c9fbSAnna Schumaker 		if (status == -ETOOSMALL)
120004b4c9fbSAnna Schumaker 			status = -ERANGE;
120104b4c9fbSAnna Schumaker 		/*
120204b4c9fbSAnna Schumaker 		 * Special case: for LISTXATTRS, NFS4ERR_NOXATTR
120304b4c9fbSAnna Schumaker 		 * should be translated to success with zero-length reply.
120404b4c9fbSAnna Schumaker 		 */
120504b4c9fbSAnna Schumaker 		if (status == -ENODATA) {
120604b4c9fbSAnna Schumaker 			res->eof = true;
120704b4c9fbSAnna Schumaker 			status = 0;
120804b4c9fbSAnna Schumaker 		}
120904b4c9fbSAnna Schumaker 		goto out;
121004b4c9fbSAnna Schumaker 	}
121104b4c9fbSAnna Schumaker 
121204b4c9fbSAnna Schumaker 	p = xdr_inline_decode(xdr, 8);
121304b4c9fbSAnna Schumaker 	if (unlikely(!p))
121404b4c9fbSAnna Schumaker 		return -EIO;
121504b4c9fbSAnna Schumaker 
121604b4c9fbSAnna Schumaker 	xdr_decode_hyper(p, &res->cookie);
121704b4c9fbSAnna Schumaker 
121804b4c9fbSAnna Schumaker 	p = xdr_inline_decode(xdr, 4);
121904b4c9fbSAnna Schumaker 	if (unlikely(!p))
122004b4c9fbSAnna Schumaker 		return -EIO;
122104b4c9fbSAnna Schumaker 
122204b4c9fbSAnna Schumaker 	left = res->xattr_len;
122304b4c9fbSAnna Schumaker 	buf = res->xattr_buf;
122404b4c9fbSAnna Schumaker 
122504b4c9fbSAnna Schumaker 	count = be32_to_cpup(p);
122604b4c9fbSAnna Schumaker 	copied = 0;
122704b4c9fbSAnna Schumaker 
122804b4c9fbSAnna Schumaker 	/*
122904b4c9fbSAnna Schumaker 	 * We have asked for enough room to encode the maximum number
123004b4c9fbSAnna Schumaker 	 * of possible attribute names, so everything should fit.
123104b4c9fbSAnna Schumaker 	 *
123204b4c9fbSAnna Schumaker 	 * But, don't rely on that assumption. Just decode entries
123304b4c9fbSAnna Schumaker 	 * until they don't fit anymore, just in case the server did
123404b4c9fbSAnna Schumaker 	 * something odd.
123504b4c9fbSAnna Schumaker 	 */
123604b4c9fbSAnna Schumaker 	while (count--) {
123704b4c9fbSAnna Schumaker 		p = xdr_inline_decode(xdr, 4);
123804b4c9fbSAnna Schumaker 		if (unlikely(!p))
123904b4c9fbSAnna Schumaker 			return -EIO;
124004b4c9fbSAnna Schumaker 
124104b4c9fbSAnna Schumaker 		len = be32_to_cpup(p);
124204b4c9fbSAnna Schumaker 		if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
124304b4c9fbSAnna Schumaker 			status = -ERANGE;
124404b4c9fbSAnna Schumaker 			goto out;
124504b4c9fbSAnna Schumaker 		}
124604b4c9fbSAnna Schumaker 
124704b4c9fbSAnna Schumaker 		p = xdr_inline_decode(xdr, len);
124804b4c9fbSAnna Schumaker 		if (unlikely(!p))
124904b4c9fbSAnna Schumaker 			return -EIO;
125004b4c9fbSAnna Schumaker 
125104b4c9fbSAnna Schumaker 		ulen = len + XATTR_USER_PREFIX_LEN + 1;
125204b4c9fbSAnna Schumaker 		if (buf) {
125304b4c9fbSAnna Schumaker 			if (ulen > left) {
125404b4c9fbSAnna Schumaker 				status = -ERANGE;
125504b4c9fbSAnna Schumaker 				goto out;
125604b4c9fbSAnna Schumaker 			}
125704b4c9fbSAnna Schumaker 
125804b4c9fbSAnna Schumaker 			memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
125904b4c9fbSAnna Schumaker 			memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
126004b4c9fbSAnna Schumaker 
126104b4c9fbSAnna Schumaker 			buf[ulen - 1] = 0;
126204b4c9fbSAnna Schumaker 			buf += ulen;
126304b4c9fbSAnna Schumaker 			left -= ulen;
126404b4c9fbSAnna Schumaker 		}
126504b4c9fbSAnna Schumaker 		copied += ulen;
126604b4c9fbSAnna Schumaker 	}
126704b4c9fbSAnna Schumaker 
126804b4c9fbSAnna Schumaker 	p = xdr_inline_decode(xdr, 4);
126904b4c9fbSAnna Schumaker 	if (unlikely(!p))
127004b4c9fbSAnna Schumaker 		return -EIO;
127104b4c9fbSAnna Schumaker 
127204b4c9fbSAnna Schumaker 	res->eof = be32_to_cpup(p);
127304b4c9fbSAnna Schumaker 	res->copied = copied;
127404b4c9fbSAnna Schumaker 
127504b4c9fbSAnna Schumaker out:
127604b4c9fbSAnna Schumaker 	if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
127704b4c9fbSAnna Schumaker 		status = -E2BIG;
127804b4c9fbSAnna Schumaker 
127904b4c9fbSAnna Schumaker 	return status;
128004b4c9fbSAnna Schumaker }
128104b4c9fbSAnna Schumaker 
12821c6dcbe5SAnna Schumaker /*
1283f4ac1674SAnna Schumaker  * Decode ALLOCATE request
1284f4ac1674SAnna Schumaker  */
nfs4_xdr_dec_allocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1285f4ac1674SAnna Schumaker static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
1286f4ac1674SAnna Schumaker 				 struct xdr_stream *xdr,
128718d9cff4SChristoph Hellwig 				 void *data)
1288f4ac1674SAnna Schumaker {
128918d9cff4SChristoph Hellwig 	struct nfs42_falloc_res *res = data;
1290f4ac1674SAnna Schumaker 	struct compound_hdr hdr;
1291f4ac1674SAnna Schumaker 	int status;
1292f4ac1674SAnna Schumaker 
1293f4ac1674SAnna Schumaker 	status = decode_compound_hdr(xdr, &hdr);
1294f4ac1674SAnna Schumaker 	if (status)
1295f4ac1674SAnna Schumaker 		goto out;
1296f4ac1674SAnna Schumaker 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1297f4ac1674SAnna Schumaker 	if (status)
1298f4ac1674SAnna Schumaker 		goto out;
1299f4ac1674SAnna Schumaker 	status = decode_putfh(xdr);
1300f4ac1674SAnna Schumaker 	if (status)
1301f4ac1674SAnna Schumaker 		goto out;
1302f4ac1674SAnna Schumaker 	status = decode_allocate(xdr, res);
13039a51940bSAnna Schumaker 	if (status)
13049a51940bSAnna Schumaker 		goto out;
13059a51940bSAnna Schumaker 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1306f4ac1674SAnna Schumaker out:
1307f4ac1674SAnna Schumaker 	return status;
1308f4ac1674SAnna Schumaker }
1309f4ac1674SAnna Schumaker 
1310f4ac1674SAnna Schumaker /*
13112e72448bSAnna Schumaker  * Decode COPY response
13122e72448bSAnna Schumaker  */
nfs4_xdr_dec_copy(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)13132e72448bSAnna Schumaker static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
13142e72448bSAnna Schumaker 			     struct xdr_stream *xdr,
131518d9cff4SChristoph Hellwig 			     void *data)
13162e72448bSAnna Schumaker {
131718d9cff4SChristoph Hellwig 	struct nfs42_copy_res *res = data;
13182e72448bSAnna Schumaker 	struct compound_hdr hdr;
13192e72448bSAnna Schumaker 	int status;
13202e72448bSAnna Schumaker 
13212e72448bSAnna Schumaker 	status = decode_compound_hdr(xdr, &hdr);
13222e72448bSAnna Schumaker 	if (status)
13232e72448bSAnna Schumaker 		goto out;
13242e72448bSAnna Schumaker 	status = decode_sequence(xdr, &res->seq_res, rqstp);
13252e72448bSAnna Schumaker 	if (status)
13262e72448bSAnna Schumaker 		goto out;
13272e72448bSAnna Schumaker 	status = decode_putfh(xdr);
13282e72448bSAnna Schumaker 	if (status)
13292e72448bSAnna Schumaker 		goto out;
13302e72448bSAnna Schumaker 	status = decode_savefh(xdr);
13312e72448bSAnna Schumaker 	if (status)
13322e72448bSAnna Schumaker 		goto out;
13332e72448bSAnna Schumaker 	status = decode_putfh(xdr);
13342e72448bSAnna Schumaker 	if (status)
13352e72448bSAnna Schumaker 		goto out;
13362e72448bSAnna Schumaker 	status = decode_copy(xdr, res);
1337e0926934SOlga Kornievskaia 	if (status)
1338e0926934SOlga Kornievskaia 		goto out;
133962164f31SOlga Kornievskaia 	if (res->commit_res.verf)
1340e0926934SOlga Kornievskaia 		status = decode_commit(xdr, &res->commit_res);
13412e72448bSAnna Schumaker out:
13422e72448bSAnna Schumaker 	return status;
13432e72448bSAnna Schumaker }
13442e72448bSAnna Schumaker 
13452e72448bSAnna Schumaker /*
1346cb95deeaSOlga Kornievskaia  * Decode OFFLOAD_CANCEL response
1347cb95deeaSOlga Kornievskaia  */
nfs4_xdr_dec_offload_cancel(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1348cb95deeaSOlga Kornievskaia static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
1349cb95deeaSOlga Kornievskaia 				       struct xdr_stream *xdr,
1350cb95deeaSOlga Kornievskaia 				       void *data)
1351cb95deeaSOlga Kornievskaia {
1352cb95deeaSOlga Kornievskaia 	struct nfs42_offload_status_res *res = data;
1353cb95deeaSOlga Kornievskaia 	struct compound_hdr hdr;
1354cb95deeaSOlga Kornievskaia 	int status;
1355cb95deeaSOlga Kornievskaia 
1356cb95deeaSOlga Kornievskaia 	status = decode_compound_hdr(xdr, &hdr);
1357cb95deeaSOlga Kornievskaia 	if (status)
1358cb95deeaSOlga Kornievskaia 		goto out;
1359cb95deeaSOlga Kornievskaia 	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
1360cb95deeaSOlga Kornievskaia 	if (status)
1361cb95deeaSOlga Kornievskaia 		goto out;
1362cb95deeaSOlga Kornievskaia 	status = decode_putfh(xdr);
1363cb95deeaSOlga Kornievskaia 	if (status)
1364cb95deeaSOlga Kornievskaia 		goto out;
1365cb95deeaSOlga Kornievskaia 	status = decode_offload_cancel(xdr, res);
1366cb95deeaSOlga Kornievskaia 
1367cb95deeaSOlga Kornievskaia out:
1368cb95deeaSOlga Kornievskaia 	return status;
1369cb95deeaSOlga Kornievskaia }
1370cb95deeaSOlga Kornievskaia 
1371cb95deeaSOlga Kornievskaia /*
13720491567bSOlga Kornievskaia  * Decode COPY_NOTIFY response
13730491567bSOlga Kornievskaia  */
nfs4_xdr_dec_copy_notify(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)13740491567bSOlga Kornievskaia static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
13750491567bSOlga Kornievskaia 				    struct xdr_stream *xdr,
13760491567bSOlga Kornievskaia 				    void *data)
13770491567bSOlga Kornievskaia {
13780491567bSOlga Kornievskaia 	struct nfs42_copy_notify_res *res = data;
13790491567bSOlga Kornievskaia 	struct compound_hdr hdr;
13800491567bSOlga Kornievskaia 	int status;
13810491567bSOlga Kornievskaia 
13820491567bSOlga Kornievskaia 	status = decode_compound_hdr(xdr, &hdr);
13830491567bSOlga Kornievskaia 	if (status)
13840491567bSOlga Kornievskaia 		goto out;
13850491567bSOlga Kornievskaia 	status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
13860491567bSOlga Kornievskaia 	if (status)
13870491567bSOlga Kornievskaia 		goto out;
13880491567bSOlga Kornievskaia 	status = decode_putfh(xdr);
13890491567bSOlga Kornievskaia 	if (status)
13900491567bSOlga Kornievskaia 		goto out;
13910491567bSOlga Kornievskaia 	status = decode_copy_notify(xdr, res);
13920491567bSOlga Kornievskaia 
13930491567bSOlga Kornievskaia out:
13940491567bSOlga Kornievskaia 	return status;
13950491567bSOlga Kornievskaia }
13960491567bSOlga Kornievskaia 
13970491567bSOlga Kornievskaia /*
1398624bd5b7SAnna Schumaker  * Decode DEALLOCATE request
1399624bd5b7SAnna Schumaker  */
nfs4_xdr_dec_deallocate(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1400624bd5b7SAnna Schumaker static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
1401624bd5b7SAnna Schumaker 				   struct xdr_stream *xdr,
140218d9cff4SChristoph Hellwig 				   void *data)
1403624bd5b7SAnna Schumaker {
140418d9cff4SChristoph Hellwig 	struct nfs42_falloc_res *res = data;
1405624bd5b7SAnna Schumaker 	struct compound_hdr hdr;
1406624bd5b7SAnna Schumaker 	int status;
1407624bd5b7SAnna Schumaker 
1408624bd5b7SAnna Schumaker 	status = decode_compound_hdr(xdr, &hdr);
1409624bd5b7SAnna Schumaker 	if (status)
1410624bd5b7SAnna Schumaker 		goto out;
1411624bd5b7SAnna Schumaker 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1412624bd5b7SAnna Schumaker 	if (status)
1413624bd5b7SAnna Schumaker 		goto out;
1414624bd5b7SAnna Schumaker 	status = decode_putfh(xdr);
1415624bd5b7SAnna Schumaker 	if (status)
1416624bd5b7SAnna Schumaker 		goto out;
1417624bd5b7SAnna Schumaker 	status = decode_deallocate(xdr, res);
14189a51940bSAnna Schumaker 	if (status)
14199a51940bSAnna Schumaker 		goto out;
14209a51940bSAnna Schumaker 	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
1421624bd5b7SAnna Schumaker out:
1422624bd5b7SAnna Schumaker 	return status;
1423624bd5b7SAnna Schumaker }
1424624bd5b7SAnna Schumaker 
1425624bd5b7SAnna Schumaker /*
1426c5675526SAnna Schumaker  * Decode READ_PLUS request
1427c5675526SAnna Schumaker  */
nfs4_xdr_dec_read_plus(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1428c5675526SAnna Schumaker static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
1429c5675526SAnna Schumaker 				  struct xdr_stream *xdr,
1430c5675526SAnna Schumaker 				  void *data)
1431c5675526SAnna Schumaker {
1432c5675526SAnna Schumaker 	struct nfs_pgio_res *res = data;
1433c5675526SAnna Schumaker 	struct compound_hdr hdr;
1434c5675526SAnna Schumaker 	int status;
1435c5675526SAnna Schumaker 
1436*303a7805SAnna Schumaker 	xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE);
1437fbd2a05fSAnna Schumaker 
1438c5675526SAnna Schumaker 	status = decode_compound_hdr(xdr, &hdr);
1439c5675526SAnna Schumaker 	if (status)
1440c5675526SAnna Schumaker 		goto out;
1441c5675526SAnna Schumaker 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1442c5675526SAnna Schumaker 	if (status)
1443c5675526SAnna Schumaker 		goto out;
1444c5675526SAnna Schumaker 	status = decode_putfh(xdr);
1445c5675526SAnna Schumaker 	if (status)
1446c5675526SAnna Schumaker 		goto out;
1447c5675526SAnna Schumaker 	status = decode_read_plus(xdr, res);
1448c5675526SAnna Schumaker 	if (!status)
1449c5675526SAnna Schumaker 		status = res->count;
1450c5675526SAnna Schumaker out:
1451c5675526SAnna Schumaker 	return status;
1452c5675526SAnna Schumaker }
1453c5675526SAnna Schumaker 
1454c5675526SAnna Schumaker /*
14551c6dcbe5SAnna Schumaker  * Decode SEEK request
14561c6dcbe5SAnna Schumaker  */
nfs4_xdr_dec_seek(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)14571c6dcbe5SAnna Schumaker static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
14581c6dcbe5SAnna Schumaker 			     struct xdr_stream *xdr,
145918d9cff4SChristoph Hellwig 			     void *data)
14601c6dcbe5SAnna Schumaker {
146118d9cff4SChristoph Hellwig 	struct nfs42_seek_res *res = data;
14621c6dcbe5SAnna Schumaker 	struct compound_hdr hdr;
14631c6dcbe5SAnna Schumaker 	int status;
14641c6dcbe5SAnna Schumaker 
14651c6dcbe5SAnna Schumaker 	status = decode_compound_hdr(xdr, &hdr);
14661c6dcbe5SAnna Schumaker 	if (status)
14671c6dcbe5SAnna Schumaker 		goto out;
14681c6dcbe5SAnna Schumaker 	status = decode_sequence(xdr, &res->seq_res, rqstp);
14691c6dcbe5SAnna Schumaker 	if (status)
14701c6dcbe5SAnna Schumaker 		goto out;
14711c6dcbe5SAnna Schumaker 	status = decode_putfh(xdr);
14721c6dcbe5SAnna Schumaker 	if (status)
14731c6dcbe5SAnna Schumaker 		goto out;
14741c6dcbe5SAnna Schumaker 	status = decode_seek(xdr, res);
14751c6dcbe5SAnna Schumaker out:
14761c6dcbe5SAnna Schumaker 	return status;
14771c6dcbe5SAnna Schumaker }
1478be3a5d23STrond Myklebust 
1479be3a5d23STrond Myklebust /*
1480be3a5d23STrond Myklebust  * Decode LAYOUTSTATS request
1481be3a5d23STrond Myklebust  */
nfs4_xdr_dec_layoutstats(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)1482be3a5d23STrond Myklebust static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
1483be3a5d23STrond Myklebust 				    struct xdr_stream *xdr,
148418d9cff4SChristoph Hellwig 				    void *data)
1485be3a5d23STrond Myklebust {
148618d9cff4SChristoph Hellwig 	struct nfs42_layoutstat_res *res = data;
1487be3a5d23STrond Myklebust 	struct compound_hdr hdr;
1488be3a5d23STrond Myklebust 	int status, i;
1489be3a5d23STrond Myklebust 
1490be3a5d23STrond Myklebust 	status = decode_compound_hdr(xdr, &hdr);
1491be3a5d23STrond Myklebust 	if (status)
1492be3a5d23STrond Myklebust 		goto out;
1493be3a5d23STrond Myklebust 	status = decode_sequence(xdr, &res->seq_res, rqstp);
1494be3a5d23STrond Myklebust 	if (status)
1495be3a5d23STrond Myklebust 		goto out;
1496be3a5d23STrond Myklebust 	status = decode_putfh(xdr);
1497be3a5d23STrond Myklebust 	if (status)
1498be3a5d23STrond Myklebust 		goto out;
1499be3a5d23STrond Myklebust 	WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
1500be3a5d23STrond Myklebust 	for (i = 0; i < res->num_dev; i++) {
150119cf6335SPeng Tao 		status = decode_layoutstats(xdr);
1502be3a5d23STrond Myklebust 		if (status)
1503be3a5d23STrond Myklebust 			goto out;
1504be3a5d23STrond Myklebust 	}
1505be3a5d23STrond Myklebust out:
1506be3a5d23STrond Myklebust 	res->rpc_status = status;
1507be3a5d23STrond Myklebust 	return status;
1508be3a5d23STrond Myklebust }
1509be3a5d23STrond Myklebust 
151036022770SPeng Tao /*
151136022770SPeng Tao  * Decode CLONE request
151236022770SPeng Tao  */
nfs4_xdr_dec_clone(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)151336022770SPeng Tao static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
151436022770SPeng Tao 			      struct xdr_stream *xdr,
151518d9cff4SChristoph Hellwig 			      void *data)
151636022770SPeng Tao {
151718d9cff4SChristoph Hellwig 	struct nfs42_clone_res *res = data;
151836022770SPeng Tao 	struct compound_hdr hdr;
151936022770SPeng Tao 	int status;
152036022770SPeng Tao 
152136022770SPeng Tao 	status = decode_compound_hdr(xdr, &hdr);
152236022770SPeng Tao 	if (status)
152336022770SPeng Tao 		goto out;
152436022770SPeng Tao 	status = decode_sequence(xdr, &res->seq_res, rqstp);
152536022770SPeng Tao 	if (status)
152636022770SPeng Tao 		goto out;
152736022770SPeng Tao 	status = decode_putfh(xdr);
152836022770SPeng Tao 	if (status)
152936022770SPeng Tao 		goto out;
153036022770SPeng Tao 	status = decode_savefh(xdr);
153136022770SPeng Tao 	if (status)
153236022770SPeng Tao 		goto out;
153336022770SPeng Tao 	status = decode_putfh(xdr);
153436022770SPeng Tao 	if (status)
153536022770SPeng Tao 		goto out;
153636022770SPeng Tao 	status = decode_clone(xdr);
153736022770SPeng Tao 	if (status)
153836022770SPeng Tao 		goto out;
1539d3c45824STrond Myklebust 	decode_getfattr(xdr, res->dst_fattr, res->server);
154036022770SPeng Tao out:
154136022770SPeng Tao 	res->rpc_status = status;
154236022770SPeng Tao 	return status;
154336022770SPeng Tao }
154436022770SPeng Tao 
15453eb86093STrond Myklebust /*
15463eb86093STrond Myklebust  * Decode LAYOUTERROR request
15473eb86093STrond Myklebust  */
nfs4_xdr_dec_layouterror(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)15483eb86093STrond Myklebust static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
15493eb86093STrond Myklebust 				    struct xdr_stream *xdr,
15503eb86093STrond Myklebust 				    void *data)
15513eb86093STrond Myklebust {
15523eb86093STrond Myklebust 	struct nfs42_layouterror_res *res = data;
15533eb86093STrond Myklebust 	struct compound_hdr hdr;
15543eb86093STrond Myklebust 	int status, i;
15553eb86093STrond Myklebust 
15563eb86093STrond Myklebust 	status = decode_compound_hdr(xdr, &hdr);
15573eb86093STrond Myklebust 	if (status)
15583eb86093STrond Myklebust 		goto out;
15593eb86093STrond Myklebust 	status = decode_sequence(xdr, &res->seq_res, rqstp);
15603eb86093STrond Myklebust 	if (status)
15613eb86093STrond Myklebust 		goto out;
15623eb86093STrond Myklebust 	status = decode_putfh(xdr);
15633eb86093STrond Myklebust 
15643eb86093STrond Myklebust 	for (i = 0; i < res->num_errors && status == 0; i++)
15653eb86093STrond Myklebust 		status = decode_layouterror(xdr);
15663eb86093STrond Myklebust out:
15673eb86093STrond Myklebust 	res->rpc_status = status;
15683eb86093STrond Myklebust 	return status;
15693eb86093STrond Myklebust }
15703eb86093STrond Myklebust 
1571d5940973SAnna Schumaker /*
1572d5940973SAnna Schumaker  * Decode SETXATTR request
1573d5940973SAnna Schumaker  */
nfs4_xdr_dec_setxattr(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)15743e1f0212SFrank van der Linden static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
15753e1f0212SFrank van der Linden 				 void *data)
15763e1f0212SFrank van der Linden {
15773e1f0212SFrank van der Linden 	struct nfs42_setxattrres *res = data;
15783e1f0212SFrank van der Linden 	struct compound_hdr hdr;
15793e1f0212SFrank van der Linden 	int status;
15803e1f0212SFrank van der Linden 
15813e1f0212SFrank van der Linden 	status = decode_compound_hdr(xdr, &hdr);
15823e1f0212SFrank van der Linden 	if (status)
15833e1f0212SFrank van der Linden 		goto out;
15843e1f0212SFrank van der Linden 	status = decode_sequence(xdr, &res->seq_res, req);
15853e1f0212SFrank van der Linden 	if (status)
15863e1f0212SFrank van der Linden 		goto out;
15873e1f0212SFrank van der Linden 	status = decode_putfh(xdr);
15883e1f0212SFrank van der Linden 	if (status)
15893e1f0212SFrank van der Linden 		goto out;
15903e1f0212SFrank van der Linden 	status = decode_setxattr(xdr, &res->cinfo);
159186e2e1f6SAnna Schumaker 	if (status)
159286e2e1f6SAnna Schumaker 		goto out;
159386e2e1f6SAnna Schumaker 	status = decode_getfattr(xdr, res->fattr, res->server);
15943e1f0212SFrank van der Linden out:
15953e1f0212SFrank van der Linden 	return status;
15963e1f0212SFrank van der Linden }
15973e1f0212SFrank van der Linden 
1598d5940973SAnna Schumaker /*
1599d5940973SAnna Schumaker  * Decode GETXATTR request
1600d5940973SAnna Schumaker  */
nfs4_xdr_dec_getxattr(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)16013e1f0212SFrank van der Linden static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
16023e1f0212SFrank van der Linden 				 struct xdr_stream *xdr, void *data)
16033e1f0212SFrank van der Linden {
16043e1f0212SFrank van der Linden 	struct nfs42_getxattrres *res = data;
16053e1f0212SFrank van der Linden 	struct compound_hdr hdr;
16063e1f0212SFrank van der Linden 	int status;
16073e1f0212SFrank van der Linden 
16083e1f0212SFrank van der Linden 	status = decode_compound_hdr(xdr, &hdr);
16093e1f0212SFrank van der Linden 	if (status)
16103e1f0212SFrank van der Linden 		goto out;
16113e1f0212SFrank van der Linden 	status = decode_sequence(xdr, &res->seq_res, rqstp);
16123e1f0212SFrank van der Linden 	if (status)
16133e1f0212SFrank van der Linden 		goto out;
16143e1f0212SFrank van der Linden 	status = decode_putfh(xdr);
16153e1f0212SFrank van der Linden 	if (status)
16163e1f0212SFrank van der Linden 		goto out;
16173e1f0212SFrank van der Linden 	status = decode_getxattr(xdr, res, rqstp);
16183e1f0212SFrank van der Linden out:
16193e1f0212SFrank van der Linden 	return status;
16203e1f0212SFrank van der Linden }
16213e1f0212SFrank van der Linden 
1622d5940973SAnna Schumaker /*
1623d5940973SAnna Schumaker  * Decode LISTXATTR request
1624d5940973SAnna Schumaker  */
nfs4_xdr_dec_listxattrs(struct rpc_rqst * rqstp,struct xdr_stream * xdr,void * data)16253e1f0212SFrank van der Linden static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
16263e1f0212SFrank van der Linden 				   struct xdr_stream *xdr, void *data)
16273e1f0212SFrank van der Linden {
16283e1f0212SFrank van der Linden 	struct nfs42_listxattrsres *res = data;
16293e1f0212SFrank van der Linden 	struct compound_hdr hdr;
16303e1f0212SFrank van der Linden 	int status;
16313e1f0212SFrank van der Linden 
16320ae4c3e8SChuck Lever 	xdr_set_scratch_page(xdr, res->scratch);
16333e1f0212SFrank van der Linden 
16343e1f0212SFrank van der Linden 	status = decode_compound_hdr(xdr, &hdr);
16353e1f0212SFrank van der Linden 	if (status)
16363e1f0212SFrank van der Linden 		goto out;
16373e1f0212SFrank van der Linden 	status = decode_sequence(xdr, &res->seq_res, rqstp);
16383e1f0212SFrank van der Linden 	if (status)
16393e1f0212SFrank van der Linden 		goto out;
16403e1f0212SFrank van der Linden 	status = decode_putfh(xdr);
16413e1f0212SFrank van der Linden 	if (status)
16423e1f0212SFrank van der Linden 		goto out;
16433e1f0212SFrank van der Linden 	status = decode_listxattrs(xdr, res);
16443e1f0212SFrank van der Linden out:
16453e1f0212SFrank van der Linden 	return status;
16463e1f0212SFrank van der Linden }
16473e1f0212SFrank van der Linden 
1648d5940973SAnna Schumaker /*
1649d5940973SAnna Schumaker  * Decode REMOVEXATTR request
1650d5940973SAnna Schumaker  */
nfs4_xdr_dec_removexattr(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)16513e1f0212SFrank van der Linden static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
16523e1f0212SFrank van der Linden 				    struct xdr_stream *xdr, void *data)
16533e1f0212SFrank van der Linden {
16543e1f0212SFrank van der Linden 	struct nfs42_removexattrres *res = data;
16553e1f0212SFrank van der Linden 	struct compound_hdr hdr;
16563e1f0212SFrank van der Linden 	int status;
16573e1f0212SFrank van der Linden 
16583e1f0212SFrank van der Linden 	status = decode_compound_hdr(xdr, &hdr);
16593e1f0212SFrank van der Linden 	if (status)
16603e1f0212SFrank van der Linden 		goto out;
16613e1f0212SFrank van der Linden 	status = decode_sequence(xdr, &res->seq_res, req);
16623e1f0212SFrank van der Linden 	if (status)
16633e1f0212SFrank van der Linden 		goto out;
16643e1f0212SFrank van der Linden 	status = decode_putfh(xdr);
16653e1f0212SFrank van der Linden 	if (status)
16663e1f0212SFrank van der Linden 		goto out;
16673e1f0212SFrank van der Linden 
16683e1f0212SFrank van der Linden 	status = decode_removexattr(xdr, &res->cinfo);
16693e1f0212SFrank van der Linden out:
16703e1f0212SFrank van der Linden 	return status;
16713e1f0212SFrank van der Linden }
16721c6dcbe5SAnna Schumaker #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
1673