18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  fs/nfs/nfs4xdr.c
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  Client-side XDR for NFSv4.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci *  Copyright (c) 2002 The Regents of the University of Michigan.
78c2ecf20Sopenharmony_ci *  All rights reserved.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci *  Kendrick Smith <kmsmith@umich.edu>
108c2ecf20Sopenharmony_ci *  Andy Adamson   <andros@umich.edu>
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci *  Redistribution and use in source and binary forms, with or without
138c2ecf20Sopenharmony_ci *  modification, are permitted provided that the following conditions
148c2ecf20Sopenharmony_ci *  are met:
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *  1. Redistributions of source code must retain the above copyright
178c2ecf20Sopenharmony_ci *     notice, this list of conditions and the following disclaimer.
188c2ecf20Sopenharmony_ci *  2. Redistributions in binary form must reproduce the above copyright
198c2ecf20Sopenharmony_ci *     notice, this list of conditions and the following disclaimer in the
208c2ecf20Sopenharmony_ci *     documentation and/or other materials provided with the distribution.
218c2ecf20Sopenharmony_ci *  3. Neither the name of the University nor the names of its
228c2ecf20Sopenharmony_ci *     contributors may be used to endorse or promote products derived
238c2ecf20Sopenharmony_ci *     from this software without specific prior written permission.
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
268c2ecf20Sopenharmony_ci *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
278c2ecf20Sopenharmony_ci *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
288c2ecf20Sopenharmony_ci *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
298c2ecf20Sopenharmony_ci *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
308c2ecf20Sopenharmony_ci *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
318c2ecf20Sopenharmony_ci *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
328c2ecf20Sopenharmony_ci *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
338c2ecf20Sopenharmony_ci *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
348c2ecf20Sopenharmony_ci *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
358c2ecf20Sopenharmony_ci *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#include <linux/param.h>
398c2ecf20Sopenharmony_ci#include <linux/time.h>
408c2ecf20Sopenharmony_ci#include <linux/mm.h>
418c2ecf20Sopenharmony_ci#include <linux/errno.h>
428c2ecf20Sopenharmony_ci#include <linux/string.h>
438c2ecf20Sopenharmony_ci#include <linux/in.h>
448c2ecf20Sopenharmony_ci#include <linux/pagemap.h>
458c2ecf20Sopenharmony_ci#include <linux/proc_fs.h>
468c2ecf20Sopenharmony_ci#include <linux/kdev_t.h>
478c2ecf20Sopenharmony_ci#include <linux/module.h>
488c2ecf20Sopenharmony_ci#include <linux/utsname.h>
498c2ecf20Sopenharmony_ci#include <linux/sunrpc/clnt.h>
508c2ecf20Sopenharmony_ci#include <linux/sunrpc/msg_prot.h>
518c2ecf20Sopenharmony_ci#include <linux/sunrpc/gss_api.h>
528c2ecf20Sopenharmony_ci#include <linux/nfs.h>
538c2ecf20Sopenharmony_ci#include <linux/nfs4.h>
548c2ecf20Sopenharmony_ci#include <linux/nfs_fs.h>
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci#include "nfs4_fs.h"
578c2ecf20Sopenharmony_ci#include "nfs4trace.h"
588c2ecf20Sopenharmony_ci#include "internal.h"
598c2ecf20Sopenharmony_ci#include "nfs4idmap.h"
608c2ecf20Sopenharmony_ci#include "nfs4session.h"
618c2ecf20Sopenharmony_ci#include "pnfs.h"
628c2ecf20Sopenharmony_ci#include "netns.h"
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#define NFSDBG_FACILITY		NFSDBG_XDR
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/* Mapping from NFS error code to "errno" error code. */
678c2ecf20Sopenharmony_ci#define errno_NFSERR_IO		EIO
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistruct compound_hdr;
708c2ecf20Sopenharmony_cistatic int nfs4_stat_to_errno(int);
718c2ecf20Sopenharmony_cistatic void encode_layoutget(struct xdr_stream *xdr,
728c2ecf20Sopenharmony_ci			     const struct nfs4_layoutget_args *args,
738c2ecf20Sopenharmony_ci			     struct compound_hdr *hdr);
748c2ecf20Sopenharmony_cistatic int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
758c2ecf20Sopenharmony_ci			     struct nfs4_layoutget_res *res);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci/* NFSv4 COMPOUND tags are only wanted for debugging purposes */
788c2ecf20Sopenharmony_ci#ifdef DEBUG
798c2ecf20Sopenharmony_ci#define NFS4_MAXTAGLEN		20
808c2ecf20Sopenharmony_ci#else
818c2ecf20Sopenharmony_ci#define NFS4_MAXTAGLEN		0
828c2ecf20Sopenharmony_ci#endif
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci/* lock,open owner id:
858c2ecf20Sopenharmony_ci * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT  >> 2)
868c2ecf20Sopenharmony_ci */
878c2ecf20Sopenharmony_ci#define open_owner_id_maxsz	(1 + 2 + 1 + 1 + 2)
888c2ecf20Sopenharmony_ci#define lock_owner_id_maxsz	(1 + 1 + 4)
898c2ecf20Sopenharmony_ci#define decode_lockowner_maxsz	(1 + XDR_QUADLEN(IDMAP_NAMESZ))
908c2ecf20Sopenharmony_ci#define compound_encode_hdr_maxsz	(3 + (NFS4_MAXTAGLEN >> 2))
918c2ecf20Sopenharmony_ci#define compound_decode_hdr_maxsz	(3 + (NFS4_MAXTAGLEN >> 2))
928c2ecf20Sopenharmony_ci#define op_encode_hdr_maxsz	(1)
938c2ecf20Sopenharmony_ci#define op_decode_hdr_maxsz	(2)
948c2ecf20Sopenharmony_ci#define encode_stateid_maxsz	(XDR_QUADLEN(NFS4_STATEID_SIZE))
958c2ecf20Sopenharmony_ci#define decode_stateid_maxsz	(XDR_QUADLEN(NFS4_STATEID_SIZE))
968c2ecf20Sopenharmony_ci#define encode_verifier_maxsz	(XDR_QUADLEN(NFS4_VERIFIER_SIZE))
978c2ecf20Sopenharmony_ci#define decode_verifier_maxsz	(XDR_QUADLEN(NFS4_VERIFIER_SIZE))
988c2ecf20Sopenharmony_ci#define encode_putfh_maxsz	(op_encode_hdr_maxsz + 1 + \
998c2ecf20Sopenharmony_ci				(NFS4_FHSIZE >> 2))
1008c2ecf20Sopenharmony_ci#define decode_putfh_maxsz	(op_decode_hdr_maxsz)
1018c2ecf20Sopenharmony_ci#define encode_putrootfh_maxsz	(op_encode_hdr_maxsz)
1028c2ecf20Sopenharmony_ci#define decode_putrootfh_maxsz	(op_decode_hdr_maxsz)
1038c2ecf20Sopenharmony_ci#define encode_getfh_maxsz      (op_encode_hdr_maxsz)
1048c2ecf20Sopenharmony_ci#define decode_getfh_maxsz      (op_decode_hdr_maxsz + 1 + \
1058c2ecf20Sopenharmony_ci				((3+NFS4_FHSIZE) >> 2))
1068c2ecf20Sopenharmony_ci#define nfs4_fattr_bitmap_maxsz 4
1078c2ecf20Sopenharmony_ci#define encode_getattr_maxsz    (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
1088c2ecf20Sopenharmony_ci#define nfstime4_maxsz		(3)
1098c2ecf20Sopenharmony_ci#define nfs4_name_maxsz		(1 + ((3 + NFS4_MAXNAMLEN) >> 2))
1108c2ecf20Sopenharmony_ci#define nfs4_path_maxsz		(1 + ((3 + NFS4_MAXPATHLEN) >> 2))
1118c2ecf20Sopenharmony_ci#define nfs4_owner_maxsz	(1 + XDR_QUADLEN(IDMAP_NAMESZ))
1128c2ecf20Sopenharmony_ci#define nfs4_group_maxsz	(1 + XDR_QUADLEN(IDMAP_NAMESZ))
1138c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_SECURITY_LABEL
1148c2ecf20Sopenharmony_ci/* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */
1158c2ecf20Sopenharmony_ci#define	nfs4_label_maxsz	(4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN))
1168c2ecf20Sopenharmony_ci#else
1178c2ecf20Sopenharmony_ci#define	nfs4_label_maxsz	0
1188c2ecf20Sopenharmony_ci#endif
1198c2ecf20Sopenharmony_ci/* We support only one layout type per file system */
1208c2ecf20Sopenharmony_ci#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8)
1218c2ecf20Sopenharmony_ci/* This is based on getfattr, which uses the most attributes: */
1228c2ecf20Sopenharmony_ci#define nfs4_fattr_value_maxsz	(1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
1238c2ecf20Sopenharmony_ci				3*nfstime4_maxsz + \
1248c2ecf20Sopenharmony_ci				nfs4_owner_maxsz + \
1258c2ecf20Sopenharmony_ci				nfs4_group_maxsz + nfs4_label_maxsz + \
1268c2ecf20Sopenharmony_ci				 decode_mdsthreshold_maxsz))
1278c2ecf20Sopenharmony_ci#define nfs4_fattr_maxsz	(nfs4_fattr_bitmap_maxsz + \
1288c2ecf20Sopenharmony_ci				nfs4_fattr_value_maxsz)
1298c2ecf20Sopenharmony_ci#define decode_getattr_maxsz    (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
1308c2ecf20Sopenharmony_ci#define encode_attrs_maxsz	(nfs4_fattr_bitmap_maxsz + \
1318c2ecf20Sopenharmony_ci				 1 + 2 + 1 + \
1328c2ecf20Sopenharmony_ci				nfs4_owner_maxsz + \
1338c2ecf20Sopenharmony_ci				nfs4_group_maxsz + \
1348c2ecf20Sopenharmony_ci				nfs4_label_maxsz + \
1358c2ecf20Sopenharmony_ci				1 + nfstime4_maxsz + \
1368c2ecf20Sopenharmony_ci				1 + nfstime4_maxsz)
1378c2ecf20Sopenharmony_ci#define encode_savefh_maxsz     (op_encode_hdr_maxsz)
1388c2ecf20Sopenharmony_ci#define decode_savefh_maxsz     (op_decode_hdr_maxsz)
1398c2ecf20Sopenharmony_ci#define encode_restorefh_maxsz  (op_encode_hdr_maxsz)
1408c2ecf20Sopenharmony_ci#define decode_restorefh_maxsz  (op_decode_hdr_maxsz)
1418c2ecf20Sopenharmony_ci#define encode_fsinfo_maxsz	(encode_getattr_maxsz)
1428c2ecf20Sopenharmony_ci/* The 5 accounts for the PNFS attributes, and assumes that at most three
1438c2ecf20Sopenharmony_ci * layout types will be returned.
1448c2ecf20Sopenharmony_ci */
1458c2ecf20Sopenharmony_ci#define decode_fsinfo_maxsz	(op_decode_hdr_maxsz + \
1468c2ecf20Sopenharmony_ci				 nfs4_fattr_bitmap_maxsz + 4 + 8 + 5)
1478c2ecf20Sopenharmony_ci#define encode_renew_maxsz	(op_encode_hdr_maxsz + 3)
1488c2ecf20Sopenharmony_ci#define decode_renew_maxsz	(op_decode_hdr_maxsz)
1498c2ecf20Sopenharmony_ci#define encode_setclientid_maxsz \
1508c2ecf20Sopenharmony_ci				(op_encode_hdr_maxsz + \
1518c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
1528c2ecf20Sopenharmony_ci				/* client name */ \
1538c2ecf20Sopenharmony_ci				1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
1548c2ecf20Sopenharmony_ci				1 /* sc_prog */ + \
1558c2ecf20Sopenharmony_ci				1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
1568c2ecf20Sopenharmony_ci				1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \
1578c2ecf20Sopenharmony_ci				1) /* sc_cb_ident */
1588c2ecf20Sopenharmony_ci#define decode_setclientid_maxsz \
1598c2ecf20Sopenharmony_ci				(op_decode_hdr_maxsz + \
1608c2ecf20Sopenharmony_ci				2 /* clientid */ + \
1618c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
1628c2ecf20Sopenharmony_ci				1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
1638c2ecf20Sopenharmony_ci				1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
1648c2ecf20Sopenharmony_ci#define encode_setclientid_confirm_maxsz \
1658c2ecf20Sopenharmony_ci				(op_encode_hdr_maxsz + \
1668c2ecf20Sopenharmony_ci				3 + (NFS4_VERIFIER_SIZE >> 2))
1678c2ecf20Sopenharmony_ci#define decode_setclientid_confirm_maxsz \
1688c2ecf20Sopenharmony_ci				(op_decode_hdr_maxsz)
1698c2ecf20Sopenharmony_ci#define encode_lookup_maxsz	(op_encode_hdr_maxsz + nfs4_name_maxsz)
1708c2ecf20Sopenharmony_ci#define decode_lookup_maxsz	(op_decode_hdr_maxsz)
1718c2ecf20Sopenharmony_ci#define encode_lookupp_maxsz	(op_encode_hdr_maxsz)
1728c2ecf20Sopenharmony_ci#define decode_lookupp_maxsz	(op_decode_hdr_maxsz)
1738c2ecf20Sopenharmony_ci#define encode_share_access_maxsz \
1748c2ecf20Sopenharmony_ci				(2)
1758c2ecf20Sopenharmony_ci#define encode_createmode_maxsz	(1 + encode_attrs_maxsz + encode_verifier_maxsz)
1768c2ecf20Sopenharmony_ci#define encode_opentype_maxsz	(1 + encode_createmode_maxsz)
1778c2ecf20Sopenharmony_ci#define encode_claim_null_maxsz	(1 + nfs4_name_maxsz)
1788c2ecf20Sopenharmony_ci#define encode_open_maxsz	(op_encode_hdr_maxsz + \
1798c2ecf20Sopenharmony_ci				2 + encode_share_access_maxsz + 2 + \
1808c2ecf20Sopenharmony_ci				open_owner_id_maxsz + \
1818c2ecf20Sopenharmony_ci				encode_opentype_maxsz + \
1828c2ecf20Sopenharmony_ci				encode_claim_null_maxsz)
1838c2ecf20Sopenharmony_ci#define decode_space_limit_maxsz	(3)
1848c2ecf20Sopenharmony_ci#define decode_ace_maxsz	(3 + nfs4_owner_maxsz)
1858c2ecf20Sopenharmony_ci#define decode_delegation_maxsz	(1 + decode_stateid_maxsz + 1 + \
1868c2ecf20Sopenharmony_ci				decode_space_limit_maxsz + \
1878c2ecf20Sopenharmony_ci				decode_ace_maxsz)
1888c2ecf20Sopenharmony_ci#define decode_change_info_maxsz	(5)
1898c2ecf20Sopenharmony_ci#define decode_open_maxsz	(op_decode_hdr_maxsz + \
1908c2ecf20Sopenharmony_ci				decode_stateid_maxsz + \
1918c2ecf20Sopenharmony_ci				decode_change_info_maxsz + 1 + \
1928c2ecf20Sopenharmony_ci				nfs4_fattr_bitmap_maxsz + \
1938c2ecf20Sopenharmony_ci				decode_delegation_maxsz)
1948c2ecf20Sopenharmony_ci#define encode_open_confirm_maxsz \
1958c2ecf20Sopenharmony_ci				(op_encode_hdr_maxsz + \
1968c2ecf20Sopenharmony_ci				 encode_stateid_maxsz + 1)
1978c2ecf20Sopenharmony_ci#define decode_open_confirm_maxsz \
1988c2ecf20Sopenharmony_ci				(op_decode_hdr_maxsz + \
1998c2ecf20Sopenharmony_ci				 decode_stateid_maxsz)
2008c2ecf20Sopenharmony_ci#define encode_open_downgrade_maxsz \
2018c2ecf20Sopenharmony_ci				(op_encode_hdr_maxsz + \
2028c2ecf20Sopenharmony_ci				 encode_stateid_maxsz + 1 + \
2038c2ecf20Sopenharmony_ci				 encode_share_access_maxsz)
2048c2ecf20Sopenharmony_ci#define decode_open_downgrade_maxsz \
2058c2ecf20Sopenharmony_ci				(op_decode_hdr_maxsz + \
2068c2ecf20Sopenharmony_ci				 decode_stateid_maxsz)
2078c2ecf20Sopenharmony_ci#define encode_close_maxsz	(op_encode_hdr_maxsz + \
2088c2ecf20Sopenharmony_ci				 1 + encode_stateid_maxsz)
2098c2ecf20Sopenharmony_ci#define decode_close_maxsz	(op_decode_hdr_maxsz + \
2108c2ecf20Sopenharmony_ci				 decode_stateid_maxsz)
2118c2ecf20Sopenharmony_ci#define encode_setattr_maxsz	(op_encode_hdr_maxsz + \
2128c2ecf20Sopenharmony_ci				 encode_stateid_maxsz + \
2138c2ecf20Sopenharmony_ci				 encode_attrs_maxsz)
2148c2ecf20Sopenharmony_ci#define decode_setattr_maxsz	(op_decode_hdr_maxsz + \
2158c2ecf20Sopenharmony_ci				 nfs4_fattr_bitmap_maxsz)
2168c2ecf20Sopenharmony_ci#define encode_read_maxsz	(op_encode_hdr_maxsz + \
2178c2ecf20Sopenharmony_ci				 encode_stateid_maxsz + 3)
2188c2ecf20Sopenharmony_ci#define decode_read_maxsz	(op_decode_hdr_maxsz + 2 + 1)
2198c2ecf20Sopenharmony_ci#define encode_readdir_maxsz	(op_encode_hdr_maxsz + \
2208c2ecf20Sopenharmony_ci				 2 + encode_verifier_maxsz + 5 + \
2218c2ecf20Sopenharmony_ci				nfs4_label_maxsz)
2228c2ecf20Sopenharmony_ci#define decode_readdir_maxsz	(op_decode_hdr_maxsz + \
2238c2ecf20Sopenharmony_ci				 decode_verifier_maxsz + 1)
2248c2ecf20Sopenharmony_ci#define encode_readlink_maxsz	(op_encode_hdr_maxsz)
2258c2ecf20Sopenharmony_ci#define decode_readlink_maxsz	(op_decode_hdr_maxsz + 1 + 1)
2268c2ecf20Sopenharmony_ci#define encode_write_maxsz	(op_encode_hdr_maxsz + \
2278c2ecf20Sopenharmony_ci				 encode_stateid_maxsz + 4)
2288c2ecf20Sopenharmony_ci#define decode_write_maxsz	(op_decode_hdr_maxsz + \
2298c2ecf20Sopenharmony_ci				 2 + decode_verifier_maxsz)
2308c2ecf20Sopenharmony_ci#define encode_commit_maxsz	(op_encode_hdr_maxsz + 3)
2318c2ecf20Sopenharmony_ci#define decode_commit_maxsz	(op_decode_hdr_maxsz + \
2328c2ecf20Sopenharmony_ci				 decode_verifier_maxsz)
2338c2ecf20Sopenharmony_ci#define encode_remove_maxsz	(op_encode_hdr_maxsz + \
2348c2ecf20Sopenharmony_ci				nfs4_name_maxsz)
2358c2ecf20Sopenharmony_ci#define decode_remove_maxsz	(op_decode_hdr_maxsz + \
2368c2ecf20Sopenharmony_ci				 decode_change_info_maxsz)
2378c2ecf20Sopenharmony_ci#define encode_rename_maxsz	(op_encode_hdr_maxsz + \
2388c2ecf20Sopenharmony_ci				2 * nfs4_name_maxsz)
2398c2ecf20Sopenharmony_ci#define decode_rename_maxsz	(op_decode_hdr_maxsz + \
2408c2ecf20Sopenharmony_ci				 decode_change_info_maxsz + \
2418c2ecf20Sopenharmony_ci				 decode_change_info_maxsz)
2428c2ecf20Sopenharmony_ci#define encode_link_maxsz	(op_encode_hdr_maxsz + \
2438c2ecf20Sopenharmony_ci				nfs4_name_maxsz)
2448c2ecf20Sopenharmony_ci#define decode_link_maxsz	(op_decode_hdr_maxsz + decode_change_info_maxsz)
2458c2ecf20Sopenharmony_ci#define encode_lockowner_maxsz	(7)
2468c2ecf20Sopenharmony_ci#define encode_lock_maxsz	(op_encode_hdr_maxsz + \
2478c2ecf20Sopenharmony_ci				 7 + \
2488c2ecf20Sopenharmony_ci				 1 + encode_stateid_maxsz + 1 + \
2498c2ecf20Sopenharmony_ci				 encode_lockowner_maxsz)
2508c2ecf20Sopenharmony_ci#define decode_lock_denied_maxsz \
2518c2ecf20Sopenharmony_ci				(8 + decode_lockowner_maxsz)
2528c2ecf20Sopenharmony_ci#define decode_lock_maxsz	(op_decode_hdr_maxsz + \
2538c2ecf20Sopenharmony_ci				 decode_lock_denied_maxsz)
2548c2ecf20Sopenharmony_ci#define encode_lockt_maxsz	(op_encode_hdr_maxsz + 5 + \
2558c2ecf20Sopenharmony_ci				encode_lockowner_maxsz)
2568c2ecf20Sopenharmony_ci#define decode_lockt_maxsz	(op_decode_hdr_maxsz + \
2578c2ecf20Sopenharmony_ci				 decode_lock_denied_maxsz)
2588c2ecf20Sopenharmony_ci#define encode_locku_maxsz	(op_encode_hdr_maxsz + 3 + \
2598c2ecf20Sopenharmony_ci				 encode_stateid_maxsz + \
2608c2ecf20Sopenharmony_ci				 4)
2618c2ecf20Sopenharmony_ci#define decode_locku_maxsz	(op_decode_hdr_maxsz + \
2628c2ecf20Sopenharmony_ci				 decode_stateid_maxsz)
2638c2ecf20Sopenharmony_ci#define encode_release_lockowner_maxsz \
2648c2ecf20Sopenharmony_ci				(op_encode_hdr_maxsz + \
2658c2ecf20Sopenharmony_ci				 encode_lockowner_maxsz)
2668c2ecf20Sopenharmony_ci#define decode_release_lockowner_maxsz \
2678c2ecf20Sopenharmony_ci				(op_decode_hdr_maxsz)
2688c2ecf20Sopenharmony_ci#define encode_access_maxsz	(op_encode_hdr_maxsz + 1)
2698c2ecf20Sopenharmony_ci#define decode_access_maxsz	(op_decode_hdr_maxsz + 2)
2708c2ecf20Sopenharmony_ci#define encode_symlink_maxsz	(op_encode_hdr_maxsz + \
2718c2ecf20Sopenharmony_ci				1 + nfs4_name_maxsz + \
2728c2ecf20Sopenharmony_ci				1 + \
2738c2ecf20Sopenharmony_ci				nfs4_fattr_maxsz)
2748c2ecf20Sopenharmony_ci#define decode_symlink_maxsz	(op_decode_hdr_maxsz + 8)
2758c2ecf20Sopenharmony_ci#define encode_create_maxsz	(op_encode_hdr_maxsz + \
2768c2ecf20Sopenharmony_ci				1 + 2 + nfs4_name_maxsz + \
2778c2ecf20Sopenharmony_ci				encode_attrs_maxsz)
2788c2ecf20Sopenharmony_ci#define decode_create_maxsz	(op_decode_hdr_maxsz + \
2798c2ecf20Sopenharmony_ci				decode_change_info_maxsz + \
2808c2ecf20Sopenharmony_ci				nfs4_fattr_bitmap_maxsz)
2818c2ecf20Sopenharmony_ci#define encode_statfs_maxsz	(encode_getattr_maxsz)
2828c2ecf20Sopenharmony_ci#define decode_statfs_maxsz	(decode_getattr_maxsz)
2838c2ecf20Sopenharmony_ci#define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)
2848c2ecf20Sopenharmony_ci#define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
2858c2ecf20Sopenharmony_ci#define encode_getacl_maxsz	(encode_getattr_maxsz)
2868c2ecf20Sopenharmony_ci#define decode_getacl_maxsz	(op_decode_hdr_maxsz + \
2878c2ecf20Sopenharmony_ci				 nfs4_fattr_bitmap_maxsz + 1 + 1)
2888c2ecf20Sopenharmony_ci#define encode_setacl_maxsz	(op_encode_hdr_maxsz + \
2898c2ecf20Sopenharmony_ci				 encode_stateid_maxsz + 3)
2908c2ecf20Sopenharmony_ci#define decode_setacl_maxsz	(decode_setattr_maxsz)
2918c2ecf20Sopenharmony_ci#define encode_fs_locations_maxsz \
2928c2ecf20Sopenharmony_ci				(encode_getattr_maxsz)
2938c2ecf20Sopenharmony_ci#define decode_fs_locations_maxsz \
2948c2ecf20Sopenharmony_ci				(1)
2958c2ecf20Sopenharmony_ci#define encode_secinfo_maxsz	(op_encode_hdr_maxsz + nfs4_name_maxsz)
2968c2ecf20Sopenharmony_ci#define decode_secinfo_maxsz	(op_decode_hdr_maxsz + 1 + ((NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)) / 4))
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
2998c2ecf20Sopenharmony_ci#define NFS4_MAX_MACHINE_NAME_LEN (64)
3008c2ecf20Sopenharmony_ci#define IMPL_NAME_LIMIT (sizeof(utsname()->sysname) + sizeof(utsname()->release) + \
3018c2ecf20Sopenharmony_ci			 sizeof(utsname()->version) + sizeof(utsname()->machine) + 8)
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci#define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \
3048c2ecf20Sopenharmony_ci				encode_verifier_maxsz + \
3058c2ecf20Sopenharmony_ci				1 /* co_ownerid.len */ + \
3068c2ecf20Sopenharmony_ci				/* eia_clientowner */ \
3078c2ecf20Sopenharmony_ci				1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
3088c2ecf20Sopenharmony_ci				1 /* flags */ + \
3098c2ecf20Sopenharmony_ci				1 /* spa_how */ + \
3108c2ecf20Sopenharmony_ci				/* max is SP4_MACH_CRED (for now) */ + \
3118c2ecf20Sopenharmony_ci				1 + NFS4_OP_MAP_NUM_WORDS + \
3128c2ecf20Sopenharmony_ci				1 + NFS4_OP_MAP_NUM_WORDS + \
3138c2ecf20Sopenharmony_ci				1 /* implementation id array of size 1 */ + \
3148c2ecf20Sopenharmony_ci				1 /* nii_domain */ + \
3158c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
3168c2ecf20Sopenharmony_ci				1 /* nii_name */ + \
3178c2ecf20Sopenharmony_ci				XDR_QUADLEN(IMPL_NAME_LIMIT) + \
3188c2ecf20Sopenharmony_ci				3 /* nii_date */)
3198c2ecf20Sopenharmony_ci#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \
3208c2ecf20Sopenharmony_ci				2 /* eir_clientid */ + \
3218c2ecf20Sopenharmony_ci				1 /* eir_sequenceid */ + \
3228c2ecf20Sopenharmony_ci				1 /* eir_flags */ + \
3238c2ecf20Sopenharmony_ci				1 /* spr_how */ + \
3248c2ecf20Sopenharmony_ci				  /* max is SP4_MACH_CRED (for now) */ + \
3258c2ecf20Sopenharmony_ci				1 + NFS4_OP_MAP_NUM_WORDS + \
3268c2ecf20Sopenharmony_ci				1 + NFS4_OP_MAP_NUM_WORDS + \
3278c2ecf20Sopenharmony_ci				2 /* eir_server_owner.so_minor_id */ + \
3288c2ecf20Sopenharmony_ci				/* eir_server_owner.so_major_id<> */ \
3298c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
3308c2ecf20Sopenharmony_ci				/* eir_server_scope<> */ \
3318c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
3328c2ecf20Sopenharmony_ci				1 /* eir_server_impl_id array length */ + \
3338c2ecf20Sopenharmony_ci				1 /* nii_domain */ + \
3348c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
3358c2ecf20Sopenharmony_ci				1 /* nii_name */ + \
3368c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
3378c2ecf20Sopenharmony_ci				3 /* nii_date */)
3388c2ecf20Sopenharmony_ci#define encode_channel_attrs_maxsz  (6 + 1 /* ca_rdma_ird.len (0) */)
3398c2ecf20Sopenharmony_ci#define decode_channel_attrs_maxsz  (6 + \
3408c2ecf20Sopenharmony_ci				     1 /* ca_rdma_ird.len */ + \
3418c2ecf20Sopenharmony_ci				     1 /* ca_rdma_ird */)
3428c2ecf20Sopenharmony_ci#define encode_create_session_maxsz  (op_encode_hdr_maxsz + \
3438c2ecf20Sopenharmony_ci				     2 /* csa_clientid */ + \
3448c2ecf20Sopenharmony_ci				     1 /* csa_sequence */ + \
3458c2ecf20Sopenharmony_ci				     1 /* csa_flags */ + \
3468c2ecf20Sopenharmony_ci				     encode_channel_attrs_maxsz + \
3478c2ecf20Sopenharmony_ci				     encode_channel_attrs_maxsz + \
3488c2ecf20Sopenharmony_ci				     1 /* csa_cb_program */ + \
3498c2ecf20Sopenharmony_ci				     1 /* csa_sec_parms.len (1) */ + \
3508c2ecf20Sopenharmony_ci				     1 /* cb_secflavor (AUTH_SYS) */ + \
3518c2ecf20Sopenharmony_ci				     1 /* stamp */ + \
3528c2ecf20Sopenharmony_ci				     1 /* machinename.len */ + \
3538c2ecf20Sopenharmony_ci				     XDR_QUADLEN(NFS4_MAX_MACHINE_NAME_LEN) + \
3548c2ecf20Sopenharmony_ci				     1 /* uid */ + \
3558c2ecf20Sopenharmony_ci				     1 /* gid */ + \
3568c2ecf20Sopenharmony_ci				     1 /* gids.len (0) */)
3578c2ecf20Sopenharmony_ci#define decode_create_session_maxsz  (op_decode_hdr_maxsz +	\
3588c2ecf20Sopenharmony_ci				     XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
3598c2ecf20Sopenharmony_ci				     1 /* csr_sequence */ + \
3608c2ecf20Sopenharmony_ci				     1 /* csr_flags */ + \
3618c2ecf20Sopenharmony_ci				     decode_channel_attrs_maxsz + \
3628c2ecf20Sopenharmony_ci				     decode_channel_attrs_maxsz)
3638c2ecf20Sopenharmony_ci#define encode_bind_conn_to_session_maxsz  (op_encode_hdr_maxsz + \
3648c2ecf20Sopenharmony_ci				     /* bctsa_sessid */ \
3658c2ecf20Sopenharmony_ci				     XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
3668c2ecf20Sopenharmony_ci				     1 /* bctsa_dir */ + \
3678c2ecf20Sopenharmony_ci				     1 /* bctsa_use_conn_in_rdma_mode */)
3688c2ecf20Sopenharmony_ci#define decode_bind_conn_to_session_maxsz  (op_decode_hdr_maxsz +	\
3698c2ecf20Sopenharmony_ci				     /* bctsr_sessid */ \
3708c2ecf20Sopenharmony_ci				     XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
3718c2ecf20Sopenharmony_ci				     1 /* bctsr_dir */ + \
3728c2ecf20Sopenharmony_ci				     1 /* bctsr_use_conn_in_rdma_mode */)
3738c2ecf20Sopenharmony_ci#define encode_destroy_session_maxsz    (op_encode_hdr_maxsz + 4)
3748c2ecf20Sopenharmony_ci#define decode_destroy_session_maxsz    (op_decode_hdr_maxsz)
3758c2ecf20Sopenharmony_ci#define encode_destroy_clientid_maxsz   (op_encode_hdr_maxsz + 2)
3768c2ecf20Sopenharmony_ci#define decode_destroy_clientid_maxsz   (op_decode_hdr_maxsz)
3778c2ecf20Sopenharmony_ci#define encode_sequence_maxsz	(op_encode_hdr_maxsz + \
3788c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
3798c2ecf20Sopenharmony_ci#define decode_sequence_maxsz	(op_decode_hdr_maxsz + \
3808c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
3818c2ecf20Sopenharmony_ci#define encode_reclaim_complete_maxsz	(op_encode_hdr_maxsz + 4)
3828c2ecf20Sopenharmony_ci#define decode_reclaim_complete_maxsz	(op_decode_hdr_maxsz + 4)
3838c2ecf20Sopenharmony_ci#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \
3848c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
3858c2ecf20Sopenharmony_ci				1 /* layout type */ + \
3868c2ecf20Sopenharmony_ci				1 /* maxcount */ + \
3878c2ecf20Sopenharmony_ci				1 /* bitmap size */ + \
3888c2ecf20Sopenharmony_ci				1 /* notification bitmap length */ + \
3898c2ecf20Sopenharmony_ci				1 /* notification bitmap, word 0 */)
3908c2ecf20Sopenharmony_ci#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \
3918c2ecf20Sopenharmony_ci				1 /* layout type */ + \
3928c2ecf20Sopenharmony_ci				1 /* opaque devaddr4 length */ + \
3938c2ecf20Sopenharmony_ci				  /* devaddr4 payload is read into page */ \
3948c2ecf20Sopenharmony_ci				1 /* notification bitmap length */ + \
3958c2ecf20Sopenharmony_ci				1 /* notification bitmap, word 0 */ + \
3968c2ecf20Sopenharmony_ci				1 /* possible XDR padding */)
3978c2ecf20Sopenharmony_ci#define encode_layoutget_maxsz	(op_encode_hdr_maxsz + 10 + \
3988c2ecf20Sopenharmony_ci				encode_stateid_maxsz)
3998c2ecf20Sopenharmony_ci#define decode_layoutget_maxsz	(op_decode_hdr_maxsz + 8 + \
4008c2ecf20Sopenharmony_ci				decode_stateid_maxsz + \
4018c2ecf20Sopenharmony_ci				XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE) + 1)
4028c2ecf20Sopenharmony_ci#define encode_layoutcommit_maxsz (op_encode_hdr_maxsz +          \
4038c2ecf20Sopenharmony_ci				2 /* offset */ + \
4048c2ecf20Sopenharmony_ci				2 /* length */ + \
4058c2ecf20Sopenharmony_ci				1 /* reclaim */ + \
4068c2ecf20Sopenharmony_ci				encode_stateid_maxsz + \
4078c2ecf20Sopenharmony_ci				1 /* new offset (true) */ + \
4088c2ecf20Sopenharmony_ci				2 /* last byte written */ + \
4098c2ecf20Sopenharmony_ci				1 /* nt_timechanged (false) */ + \
4108c2ecf20Sopenharmony_ci				1 /* layoutupdate4 layout type */ + \
4118c2ecf20Sopenharmony_ci				1 /* layoutupdate4 opaqueue len */)
4128c2ecf20Sopenharmony_ci				  /* the actual content of layoutupdate4 should
4138c2ecf20Sopenharmony_ci				     be allocated by drivers and spliced in
4148c2ecf20Sopenharmony_ci				     using xdr_write_pages */
4158c2ecf20Sopenharmony_ci#define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3)
4168c2ecf20Sopenharmony_ci#define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \
4178c2ecf20Sopenharmony_ci				encode_stateid_maxsz + \
4188c2ecf20Sopenharmony_ci				1 + \
4198c2ecf20Sopenharmony_ci				XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
4208c2ecf20Sopenharmony_ci#define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \
4218c2ecf20Sopenharmony_ci				1 + decode_stateid_maxsz)
4228c2ecf20Sopenharmony_ci#define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 1)
4238c2ecf20Sopenharmony_ci#define decode_secinfo_no_name_maxsz decode_secinfo_maxsz
4248c2ecf20Sopenharmony_ci#define encode_test_stateid_maxsz	(op_encode_hdr_maxsz + 2 + \
4258c2ecf20Sopenharmony_ci					 XDR_QUADLEN(NFS4_STATEID_SIZE))
4268c2ecf20Sopenharmony_ci#define decode_test_stateid_maxsz	(op_decode_hdr_maxsz + 2 + 1)
4278c2ecf20Sopenharmony_ci#define encode_free_stateid_maxsz	(op_encode_hdr_maxsz + 1 + \
4288c2ecf20Sopenharmony_ci					 XDR_QUADLEN(NFS4_STATEID_SIZE))
4298c2ecf20Sopenharmony_ci#define decode_free_stateid_maxsz	(op_decode_hdr_maxsz)
4308c2ecf20Sopenharmony_ci#else /* CONFIG_NFS_V4_1 */
4318c2ecf20Sopenharmony_ci#define encode_sequence_maxsz	0
4328c2ecf20Sopenharmony_ci#define decode_sequence_maxsz	0
4338c2ecf20Sopenharmony_ci#define encode_layoutreturn_maxsz 0
4348c2ecf20Sopenharmony_ci#define decode_layoutreturn_maxsz 0
4358c2ecf20Sopenharmony_ci#define encode_layoutget_maxsz	0
4368c2ecf20Sopenharmony_ci#define decode_layoutget_maxsz	0
4378c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci#define NFS4_enc_compound_sz	(1024)  /* XXX: large enough? */
4408c2ecf20Sopenharmony_ci#define NFS4_dec_compound_sz	(1024)  /* XXX: large enough? */
4418c2ecf20Sopenharmony_ci#define NFS4_enc_read_sz	(compound_encode_hdr_maxsz + \
4428c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
4438c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
4448c2ecf20Sopenharmony_ci				encode_read_maxsz)
4458c2ecf20Sopenharmony_ci#define NFS4_dec_read_sz	(compound_decode_hdr_maxsz + \
4468c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
4478c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
4488c2ecf20Sopenharmony_ci				decode_read_maxsz)
4498c2ecf20Sopenharmony_ci#define NFS4_enc_readlink_sz	(compound_encode_hdr_maxsz + \
4508c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
4518c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
4528c2ecf20Sopenharmony_ci				encode_readlink_maxsz)
4538c2ecf20Sopenharmony_ci#define NFS4_dec_readlink_sz	(compound_decode_hdr_maxsz + \
4548c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
4558c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
4568c2ecf20Sopenharmony_ci				decode_readlink_maxsz)
4578c2ecf20Sopenharmony_ci#define NFS4_enc_readdir_sz	(compound_encode_hdr_maxsz + \
4588c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
4598c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
4608c2ecf20Sopenharmony_ci				encode_readdir_maxsz)
4618c2ecf20Sopenharmony_ci#define NFS4_dec_readdir_sz	(compound_decode_hdr_maxsz + \
4628c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
4638c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
4648c2ecf20Sopenharmony_ci				decode_readdir_maxsz)
4658c2ecf20Sopenharmony_ci#define NFS4_enc_write_sz	(compound_encode_hdr_maxsz + \
4668c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
4678c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
4688c2ecf20Sopenharmony_ci				encode_write_maxsz + \
4698c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
4708c2ecf20Sopenharmony_ci#define NFS4_dec_write_sz	(compound_decode_hdr_maxsz + \
4718c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
4728c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
4738c2ecf20Sopenharmony_ci				decode_write_maxsz + \
4748c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
4758c2ecf20Sopenharmony_ci#define NFS4_enc_commit_sz	(compound_encode_hdr_maxsz + \
4768c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
4778c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
4788c2ecf20Sopenharmony_ci				encode_commit_maxsz)
4798c2ecf20Sopenharmony_ci#define NFS4_dec_commit_sz	(compound_decode_hdr_maxsz + \
4808c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
4818c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
4828c2ecf20Sopenharmony_ci				decode_commit_maxsz)
4838c2ecf20Sopenharmony_ci#define NFS4_enc_open_sz        (compound_encode_hdr_maxsz + \
4848c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
4858c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
4868c2ecf20Sopenharmony_ci				encode_open_maxsz + \
4878c2ecf20Sopenharmony_ci				encode_access_maxsz + \
4888c2ecf20Sopenharmony_ci				encode_getfh_maxsz + \
4898c2ecf20Sopenharmony_ci				encode_getattr_maxsz + \
4908c2ecf20Sopenharmony_ci				encode_layoutget_maxsz)
4918c2ecf20Sopenharmony_ci#define NFS4_dec_open_sz        (compound_decode_hdr_maxsz + \
4928c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
4938c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
4948c2ecf20Sopenharmony_ci				decode_open_maxsz + \
4958c2ecf20Sopenharmony_ci				decode_access_maxsz + \
4968c2ecf20Sopenharmony_ci				decode_getfh_maxsz + \
4978c2ecf20Sopenharmony_ci				decode_getattr_maxsz + \
4988c2ecf20Sopenharmony_ci				decode_layoutget_maxsz)
4998c2ecf20Sopenharmony_ci#define NFS4_enc_open_confirm_sz \
5008c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
5018c2ecf20Sopenharmony_ci				 encode_putfh_maxsz + \
5028c2ecf20Sopenharmony_ci				 encode_open_confirm_maxsz)
5038c2ecf20Sopenharmony_ci#define NFS4_dec_open_confirm_sz \
5048c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
5058c2ecf20Sopenharmony_ci				 decode_putfh_maxsz + \
5068c2ecf20Sopenharmony_ci				 decode_open_confirm_maxsz)
5078c2ecf20Sopenharmony_ci#define NFS4_enc_open_noattr_sz	(compound_encode_hdr_maxsz + \
5088c2ecf20Sopenharmony_ci					encode_sequence_maxsz + \
5098c2ecf20Sopenharmony_ci					encode_putfh_maxsz + \
5108c2ecf20Sopenharmony_ci					encode_open_maxsz + \
5118c2ecf20Sopenharmony_ci					encode_access_maxsz + \
5128c2ecf20Sopenharmony_ci					encode_getattr_maxsz + \
5138c2ecf20Sopenharmony_ci					encode_layoutget_maxsz)
5148c2ecf20Sopenharmony_ci#define NFS4_dec_open_noattr_sz	(compound_decode_hdr_maxsz + \
5158c2ecf20Sopenharmony_ci					decode_sequence_maxsz + \
5168c2ecf20Sopenharmony_ci					decode_putfh_maxsz + \
5178c2ecf20Sopenharmony_ci					decode_open_maxsz + \
5188c2ecf20Sopenharmony_ci					decode_access_maxsz + \
5198c2ecf20Sopenharmony_ci					decode_getattr_maxsz + \
5208c2ecf20Sopenharmony_ci					decode_layoutget_maxsz)
5218c2ecf20Sopenharmony_ci#define NFS4_enc_open_downgrade_sz \
5228c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
5238c2ecf20Sopenharmony_ci				 encode_sequence_maxsz + \
5248c2ecf20Sopenharmony_ci				 encode_putfh_maxsz + \
5258c2ecf20Sopenharmony_ci				 encode_layoutreturn_maxsz + \
5268c2ecf20Sopenharmony_ci				 encode_open_downgrade_maxsz)
5278c2ecf20Sopenharmony_ci#define NFS4_dec_open_downgrade_sz \
5288c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
5298c2ecf20Sopenharmony_ci				 decode_sequence_maxsz + \
5308c2ecf20Sopenharmony_ci				 decode_putfh_maxsz + \
5318c2ecf20Sopenharmony_ci				 decode_layoutreturn_maxsz + \
5328c2ecf20Sopenharmony_ci				 decode_open_downgrade_maxsz)
5338c2ecf20Sopenharmony_ci#define NFS4_enc_close_sz	(compound_encode_hdr_maxsz + \
5348c2ecf20Sopenharmony_ci				 encode_sequence_maxsz + \
5358c2ecf20Sopenharmony_ci				 encode_putfh_maxsz + \
5368c2ecf20Sopenharmony_ci				 encode_layoutreturn_maxsz + \
5378c2ecf20Sopenharmony_ci				 encode_close_maxsz + \
5388c2ecf20Sopenharmony_ci				 encode_getattr_maxsz)
5398c2ecf20Sopenharmony_ci#define NFS4_dec_close_sz	(compound_decode_hdr_maxsz + \
5408c2ecf20Sopenharmony_ci				 decode_sequence_maxsz + \
5418c2ecf20Sopenharmony_ci				 decode_putfh_maxsz + \
5428c2ecf20Sopenharmony_ci				 decode_layoutreturn_maxsz + \
5438c2ecf20Sopenharmony_ci				 decode_close_maxsz + \
5448c2ecf20Sopenharmony_ci				 decode_getattr_maxsz)
5458c2ecf20Sopenharmony_ci#define NFS4_enc_setattr_sz	(compound_encode_hdr_maxsz + \
5468c2ecf20Sopenharmony_ci				 encode_sequence_maxsz + \
5478c2ecf20Sopenharmony_ci				 encode_putfh_maxsz + \
5488c2ecf20Sopenharmony_ci				 encode_setattr_maxsz + \
5498c2ecf20Sopenharmony_ci				 encode_getattr_maxsz)
5508c2ecf20Sopenharmony_ci#define NFS4_dec_setattr_sz	(compound_decode_hdr_maxsz + \
5518c2ecf20Sopenharmony_ci				 decode_sequence_maxsz + \
5528c2ecf20Sopenharmony_ci				 decode_putfh_maxsz + \
5538c2ecf20Sopenharmony_ci				 decode_setattr_maxsz + \
5548c2ecf20Sopenharmony_ci				 decode_getattr_maxsz)
5558c2ecf20Sopenharmony_ci#define NFS4_enc_fsinfo_sz	(compound_encode_hdr_maxsz + \
5568c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
5578c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
5588c2ecf20Sopenharmony_ci				encode_fsinfo_maxsz)
5598c2ecf20Sopenharmony_ci#define NFS4_dec_fsinfo_sz	(compound_decode_hdr_maxsz + \
5608c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
5618c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
5628c2ecf20Sopenharmony_ci				decode_fsinfo_maxsz)
5638c2ecf20Sopenharmony_ci#define NFS4_enc_renew_sz	(compound_encode_hdr_maxsz + \
5648c2ecf20Sopenharmony_ci				encode_renew_maxsz)
5658c2ecf20Sopenharmony_ci#define NFS4_dec_renew_sz	(compound_decode_hdr_maxsz + \
5668c2ecf20Sopenharmony_ci				decode_renew_maxsz)
5678c2ecf20Sopenharmony_ci#define NFS4_enc_setclientid_sz	(compound_encode_hdr_maxsz + \
5688c2ecf20Sopenharmony_ci				encode_setclientid_maxsz)
5698c2ecf20Sopenharmony_ci#define NFS4_dec_setclientid_sz	(compound_decode_hdr_maxsz + \
5708c2ecf20Sopenharmony_ci				decode_setclientid_maxsz)
5718c2ecf20Sopenharmony_ci#define NFS4_enc_setclientid_confirm_sz \
5728c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
5738c2ecf20Sopenharmony_ci				encode_setclientid_confirm_maxsz)
5748c2ecf20Sopenharmony_ci#define NFS4_dec_setclientid_confirm_sz \
5758c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
5768c2ecf20Sopenharmony_ci				decode_setclientid_confirm_maxsz)
5778c2ecf20Sopenharmony_ci#define NFS4_enc_lock_sz        (compound_encode_hdr_maxsz + \
5788c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
5798c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
5808c2ecf20Sopenharmony_ci				encode_lock_maxsz)
5818c2ecf20Sopenharmony_ci#define NFS4_dec_lock_sz        (compound_decode_hdr_maxsz + \
5828c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
5838c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
5848c2ecf20Sopenharmony_ci				decode_lock_maxsz)
5858c2ecf20Sopenharmony_ci#define NFS4_enc_lockt_sz       (compound_encode_hdr_maxsz + \
5868c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
5878c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
5888c2ecf20Sopenharmony_ci				encode_lockt_maxsz)
5898c2ecf20Sopenharmony_ci#define NFS4_dec_lockt_sz       (compound_decode_hdr_maxsz + \
5908c2ecf20Sopenharmony_ci				 decode_sequence_maxsz + \
5918c2ecf20Sopenharmony_ci				 decode_putfh_maxsz + \
5928c2ecf20Sopenharmony_ci				 decode_lockt_maxsz)
5938c2ecf20Sopenharmony_ci#define NFS4_enc_locku_sz       (compound_encode_hdr_maxsz + \
5948c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
5958c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
5968c2ecf20Sopenharmony_ci				encode_locku_maxsz)
5978c2ecf20Sopenharmony_ci#define NFS4_dec_locku_sz       (compound_decode_hdr_maxsz + \
5988c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
5998c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6008c2ecf20Sopenharmony_ci				decode_locku_maxsz)
6018c2ecf20Sopenharmony_ci#define NFS4_enc_release_lockowner_sz \
6028c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
6038c2ecf20Sopenharmony_ci				 encode_lockowner_maxsz)
6048c2ecf20Sopenharmony_ci#define NFS4_dec_release_lockowner_sz \
6058c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
6068c2ecf20Sopenharmony_ci				 decode_lockowner_maxsz)
6078c2ecf20Sopenharmony_ci#define NFS4_enc_access_sz	(compound_encode_hdr_maxsz + \
6088c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6098c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6108c2ecf20Sopenharmony_ci				encode_access_maxsz + \
6118c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
6128c2ecf20Sopenharmony_ci#define NFS4_dec_access_sz	(compound_decode_hdr_maxsz + \
6138c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6148c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6158c2ecf20Sopenharmony_ci				decode_access_maxsz + \
6168c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
6178c2ecf20Sopenharmony_ci#define NFS4_enc_getattr_sz	(compound_encode_hdr_maxsz + \
6188c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6198c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6208c2ecf20Sopenharmony_ci				encode_getattr_maxsz + \
6218c2ecf20Sopenharmony_ci				encode_renew_maxsz)
6228c2ecf20Sopenharmony_ci#define NFS4_dec_getattr_sz	(compound_decode_hdr_maxsz + \
6238c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6248c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6258c2ecf20Sopenharmony_ci				decode_getattr_maxsz + \
6268c2ecf20Sopenharmony_ci				decode_renew_maxsz)
6278c2ecf20Sopenharmony_ci#define NFS4_enc_lookup_sz	(compound_encode_hdr_maxsz + \
6288c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6298c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6308c2ecf20Sopenharmony_ci				encode_lookup_maxsz + \
6318c2ecf20Sopenharmony_ci				encode_getattr_maxsz + \
6328c2ecf20Sopenharmony_ci				encode_getfh_maxsz)
6338c2ecf20Sopenharmony_ci#define NFS4_dec_lookup_sz	(compound_decode_hdr_maxsz + \
6348c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6358c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6368c2ecf20Sopenharmony_ci				decode_lookup_maxsz + \
6378c2ecf20Sopenharmony_ci				decode_getattr_maxsz + \
6388c2ecf20Sopenharmony_ci				decode_getfh_maxsz)
6398c2ecf20Sopenharmony_ci#define NFS4_enc_lookupp_sz	(compound_encode_hdr_maxsz + \
6408c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6418c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6428c2ecf20Sopenharmony_ci				encode_lookupp_maxsz + \
6438c2ecf20Sopenharmony_ci				encode_getattr_maxsz + \
6448c2ecf20Sopenharmony_ci				encode_getfh_maxsz)
6458c2ecf20Sopenharmony_ci#define NFS4_dec_lookupp_sz	(compound_decode_hdr_maxsz + \
6468c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6478c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6488c2ecf20Sopenharmony_ci				decode_lookupp_maxsz + \
6498c2ecf20Sopenharmony_ci				decode_getattr_maxsz + \
6508c2ecf20Sopenharmony_ci				decode_getfh_maxsz)
6518c2ecf20Sopenharmony_ci#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
6528c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6538c2ecf20Sopenharmony_ci				encode_putrootfh_maxsz + \
6548c2ecf20Sopenharmony_ci				encode_getattr_maxsz + \
6558c2ecf20Sopenharmony_ci				encode_getfh_maxsz)
6568c2ecf20Sopenharmony_ci#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \
6578c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6588c2ecf20Sopenharmony_ci				decode_putrootfh_maxsz + \
6598c2ecf20Sopenharmony_ci				decode_getattr_maxsz + \
6608c2ecf20Sopenharmony_ci				decode_getfh_maxsz)
6618c2ecf20Sopenharmony_ci#define NFS4_enc_remove_sz	(compound_encode_hdr_maxsz + \
6628c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6638c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6648c2ecf20Sopenharmony_ci				encode_remove_maxsz)
6658c2ecf20Sopenharmony_ci#define NFS4_dec_remove_sz	(compound_decode_hdr_maxsz + \
6668c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6678c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6688c2ecf20Sopenharmony_ci				decode_remove_maxsz)
6698c2ecf20Sopenharmony_ci#define NFS4_enc_rename_sz	(compound_encode_hdr_maxsz + \
6708c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6718c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6728c2ecf20Sopenharmony_ci				encode_savefh_maxsz + \
6738c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6748c2ecf20Sopenharmony_ci				encode_rename_maxsz)
6758c2ecf20Sopenharmony_ci#define NFS4_dec_rename_sz	(compound_decode_hdr_maxsz + \
6768c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6778c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6788c2ecf20Sopenharmony_ci				decode_savefh_maxsz + \
6798c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6808c2ecf20Sopenharmony_ci				decode_rename_maxsz)
6818c2ecf20Sopenharmony_ci#define NFS4_enc_link_sz	(compound_encode_hdr_maxsz + \
6828c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6838c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6848c2ecf20Sopenharmony_ci				encode_savefh_maxsz + \
6858c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
6868c2ecf20Sopenharmony_ci				encode_link_maxsz + \
6878c2ecf20Sopenharmony_ci				encode_restorefh_maxsz + \
6888c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
6898c2ecf20Sopenharmony_ci#define NFS4_dec_link_sz	(compound_decode_hdr_maxsz + \
6908c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
6918c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6928c2ecf20Sopenharmony_ci				decode_savefh_maxsz + \
6938c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
6948c2ecf20Sopenharmony_ci				decode_link_maxsz + \
6958c2ecf20Sopenharmony_ci				decode_restorefh_maxsz + \
6968c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
6978c2ecf20Sopenharmony_ci#define NFS4_enc_symlink_sz	(compound_encode_hdr_maxsz + \
6988c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
6998c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7008c2ecf20Sopenharmony_ci				encode_symlink_maxsz + \
7018c2ecf20Sopenharmony_ci				encode_getattr_maxsz + \
7028c2ecf20Sopenharmony_ci				encode_getfh_maxsz)
7038c2ecf20Sopenharmony_ci#define NFS4_dec_symlink_sz	(compound_decode_hdr_maxsz + \
7048c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7058c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7068c2ecf20Sopenharmony_ci				decode_symlink_maxsz + \
7078c2ecf20Sopenharmony_ci				decode_getattr_maxsz + \
7088c2ecf20Sopenharmony_ci				decode_getfh_maxsz)
7098c2ecf20Sopenharmony_ci#define NFS4_enc_create_sz	(compound_encode_hdr_maxsz + \
7108c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7118c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7128c2ecf20Sopenharmony_ci				encode_create_maxsz + \
7138c2ecf20Sopenharmony_ci				encode_getfh_maxsz + \
7148c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
7158c2ecf20Sopenharmony_ci#define NFS4_dec_create_sz	(compound_decode_hdr_maxsz + \
7168c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7178c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7188c2ecf20Sopenharmony_ci				decode_create_maxsz + \
7198c2ecf20Sopenharmony_ci				decode_getfh_maxsz + \
7208c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
7218c2ecf20Sopenharmony_ci#define NFS4_enc_pathconf_sz	(compound_encode_hdr_maxsz + \
7228c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7238c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7248c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
7258c2ecf20Sopenharmony_ci#define NFS4_dec_pathconf_sz	(compound_decode_hdr_maxsz + \
7268c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7278c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7288c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
7298c2ecf20Sopenharmony_ci#define NFS4_enc_statfs_sz	(compound_encode_hdr_maxsz + \
7308c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7318c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7328c2ecf20Sopenharmony_ci				encode_statfs_maxsz)
7338c2ecf20Sopenharmony_ci#define NFS4_dec_statfs_sz	(compound_decode_hdr_maxsz + \
7348c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7358c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7368c2ecf20Sopenharmony_ci				decode_statfs_maxsz)
7378c2ecf20Sopenharmony_ci#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
7388c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7398c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7408c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
7418c2ecf20Sopenharmony_ci#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
7428c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7438c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7448c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
7458c2ecf20Sopenharmony_ci#define NFS4_enc_delegreturn_sz	(compound_encode_hdr_maxsz + \
7468c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7478c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7488c2ecf20Sopenharmony_ci				encode_layoutreturn_maxsz + \
7498c2ecf20Sopenharmony_ci				encode_delegreturn_maxsz + \
7508c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
7518c2ecf20Sopenharmony_ci#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
7528c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7538c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7548c2ecf20Sopenharmony_ci				decode_layoutreturn_maxsz + \
7558c2ecf20Sopenharmony_ci				decode_delegreturn_maxsz + \
7568c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
7578c2ecf20Sopenharmony_ci#define NFS4_enc_getacl_sz	(compound_encode_hdr_maxsz + \
7588c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7598c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7608c2ecf20Sopenharmony_ci				encode_getacl_maxsz)
7618c2ecf20Sopenharmony_ci#define NFS4_dec_getacl_sz	(compound_decode_hdr_maxsz + \
7628c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7638c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7648c2ecf20Sopenharmony_ci				decode_getacl_maxsz)
7658c2ecf20Sopenharmony_ci#define NFS4_enc_setacl_sz	(compound_encode_hdr_maxsz + \
7668c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7678c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7688c2ecf20Sopenharmony_ci				encode_setacl_maxsz)
7698c2ecf20Sopenharmony_ci#define NFS4_dec_setacl_sz	(compound_decode_hdr_maxsz + \
7708c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7718c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7728c2ecf20Sopenharmony_ci				decode_setacl_maxsz)
7738c2ecf20Sopenharmony_ci#define NFS4_enc_fs_locations_sz \
7748c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
7758c2ecf20Sopenharmony_ci				 encode_sequence_maxsz + \
7768c2ecf20Sopenharmony_ci				 encode_putfh_maxsz + \
7778c2ecf20Sopenharmony_ci				 encode_lookup_maxsz + \
7788c2ecf20Sopenharmony_ci				 encode_fs_locations_maxsz + \
7798c2ecf20Sopenharmony_ci				 encode_renew_maxsz)
7808c2ecf20Sopenharmony_ci#define NFS4_dec_fs_locations_sz \
7818c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
7828c2ecf20Sopenharmony_ci				 decode_sequence_maxsz + \
7838c2ecf20Sopenharmony_ci				 decode_putfh_maxsz + \
7848c2ecf20Sopenharmony_ci				 decode_lookup_maxsz + \
7858c2ecf20Sopenharmony_ci				 decode_fs_locations_maxsz + \
7868c2ecf20Sopenharmony_ci				 decode_renew_maxsz)
7878c2ecf20Sopenharmony_ci#define NFS4_enc_secinfo_sz 	(compound_encode_hdr_maxsz + \
7888c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
7898c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
7908c2ecf20Sopenharmony_ci				encode_secinfo_maxsz)
7918c2ecf20Sopenharmony_ci#define NFS4_dec_secinfo_sz	(compound_decode_hdr_maxsz + \
7928c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
7938c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
7948c2ecf20Sopenharmony_ci				decode_secinfo_maxsz)
7958c2ecf20Sopenharmony_ci#define NFS4_enc_fsid_present_sz \
7968c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
7978c2ecf20Sopenharmony_ci				 encode_sequence_maxsz + \
7988c2ecf20Sopenharmony_ci				 encode_putfh_maxsz + \
7998c2ecf20Sopenharmony_ci				 encode_getfh_maxsz + \
8008c2ecf20Sopenharmony_ci				 encode_renew_maxsz)
8018c2ecf20Sopenharmony_ci#define NFS4_dec_fsid_present_sz \
8028c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
8038c2ecf20Sopenharmony_ci				 decode_sequence_maxsz + \
8048c2ecf20Sopenharmony_ci				 decode_putfh_maxsz + \
8058c2ecf20Sopenharmony_ci				 decode_getfh_maxsz + \
8068c2ecf20Sopenharmony_ci				 decode_renew_maxsz)
8078c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
8088c2ecf20Sopenharmony_ci#define NFS4_enc_bind_conn_to_session_sz \
8098c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
8108c2ecf20Sopenharmony_ci				 encode_bind_conn_to_session_maxsz)
8118c2ecf20Sopenharmony_ci#define NFS4_dec_bind_conn_to_session_sz \
8128c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
8138c2ecf20Sopenharmony_ci				 decode_bind_conn_to_session_maxsz)
8148c2ecf20Sopenharmony_ci#define NFS4_enc_exchange_id_sz \
8158c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
8168c2ecf20Sopenharmony_ci				 encode_exchange_id_maxsz)
8178c2ecf20Sopenharmony_ci#define NFS4_dec_exchange_id_sz \
8188c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
8198c2ecf20Sopenharmony_ci				 decode_exchange_id_maxsz)
8208c2ecf20Sopenharmony_ci#define NFS4_enc_create_session_sz \
8218c2ecf20Sopenharmony_ci				(compound_encode_hdr_maxsz + \
8228c2ecf20Sopenharmony_ci				 encode_create_session_maxsz)
8238c2ecf20Sopenharmony_ci#define NFS4_dec_create_session_sz \
8248c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
8258c2ecf20Sopenharmony_ci				 decode_create_session_maxsz)
8268c2ecf20Sopenharmony_ci#define NFS4_enc_destroy_session_sz	(compound_encode_hdr_maxsz + \
8278c2ecf20Sopenharmony_ci					 encode_destroy_session_maxsz)
8288c2ecf20Sopenharmony_ci#define NFS4_dec_destroy_session_sz	(compound_decode_hdr_maxsz + \
8298c2ecf20Sopenharmony_ci					 decode_destroy_session_maxsz)
8308c2ecf20Sopenharmony_ci#define NFS4_enc_destroy_clientid_sz	(compound_encode_hdr_maxsz + \
8318c2ecf20Sopenharmony_ci					 encode_destroy_clientid_maxsz)
8328c2ecf20Sopenharmony_ci#define NFS4_dec_destroy_clientid_sz	(compound_decode_hdr_maxsz + \
8338c2ecf20Sopenharmony_ci					 decode_destroy_clientid_maxsz)
8348c2ecf20Sopenharmony_ci#define NFS4_enc_sequence_sz \
8358c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
8368c2ecf20Sopenharmony_ci				 encode_sequence_maxsz)
8378c2ecf20Sopenharmony_ci#define NFS4_dec_sequence_sz \
8388c2ecf20Sopenharmony_ci				(compound_decode_hdr_maxsz + \
8398c2ecf20Sopenharmony_ci				 decode_sequence_maxsz)
8408c2ecf20Sopenharmony_ci#endif
8418c2ecf20Sopenharmony_ci#define NFS4_enc_get_lease_time_sz	(compound_encode_hdr_maxsz + \
8428c2ecf20Sopenharmony_ci					 encode_sequence_maxsz + \
8438c2ecf20Sopenharmony_ci					 encode_putrootfh_maxsz + \
8448c2ecf20Sopenharmony_ci					 encode_fsinfo_maxsz)
8458c2ecf20Sopenharmony_ci#define NFS4_dec_get_lease_time_sz	(compound_decode_hdr_maxsz + \
8468c2ecf20Sopenharmony_ci					 decode_sequence_maxsz + \
8478c2ecf20Sopenharmony_ci					 decode_putrootfh_maxsz + \
8488c2ecf20Sopenharmony_ci					 decode_fsinfo_maxsz)
8498c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
8508c2ecf20Sopenharmony_ci#define NFS4_enc_reclaim_complete_sz	(compound_encode_hdr_maxsz + \
8518c2ecf20Sopenharmony_ci					 encode_sequence_maxsz + \
8528c2ecf20Sopenharmony_ci					 encode_reclaim_complete_maxsz)
8538c2ecf20Sopenharmony_ci#define NFS4_dec_reclaim_complete_sz	(compound_decode_hdr_maxsz + \
8548c2ecf20Sopenharmony_ci					 decode_sequence_maxsz + \
8558c2ecf20Sopenharmony_ci					 decode_reclaim_complete_maxsz)
8568c2ecf20Sopenharmony_ci#define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz +    \
8578c2ecf20Sopenharmony_ci				encode_sequence_maxsz +\
8588c2ecf20Sopenharmony_ci				encode_getdeviceinfo_maxsz)
8598c2ecf20Sopenharmony_ci#define NFS4_dec_getdeviceinfo_sz (compound_decode_hdr_maxsz +    \
8608c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
8618c2ecf20Sopenharmony_ci				decode_getdeviceinfo_maxsz)
8628c2ecf20Sopenharmony_ci#define NFS4_enc_layoutget_sz	(compound_encode_hdr_maxsz + \
8638c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
8648c2ecf20Sopenharmony_ci				encode_putfh_maxsz +        \
8658c2ecf20Sopenharmony_ci				encode_layoutget_maxsz)
8668c2ecf20Sopenharmony_ci#define NFS4_dec_layoutget_sz	(compound_decode_hdr_maxsz + \
8678c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
8688c2ecf20Sopenharmony_ci				decode_putfh_maxsz +        \
8698c2ecf20Sopenharmony_ci				decode_layoutget_maxsz)
8708c2ecf20Sopenharmony_ci#define NFS4_enc_layoutcommit_sz (compound_encode_hdr_maxsz + \
8718c2ecf20Sopenharmony_ci				encode_sequence_maxsz +\
8728c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
8738c2ecf20Sopenharmony_ci				encode_layoutcommit_maxsz + \
8748c2ecf20Sopenharmony_ci				encode_getattr_maxsz)
8758c2ecf20Sopenharmony_ci#define NFS4_dec_layoutcommit_sz (compound_decode_hdr_maxsz + \
8768c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
8778c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
8788c2ecf20Sopenharmony_ci				decode_layoutcommit_maxsz + \
8798c2ecf20Sopenharmony_ci				decode_getattr_maxsz)
8808c2ecf20Sopenharmony_ci#define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \
8818c2ecf20Sopenharmony_ci				encode_sequence_maxsz + \
8828c2ecf20Sopenharmony_ci				encode_putfh_maxsz + \
8838c2ecf20Sopenharmony_ci				encode_layoutreturn_maxsz)
8848c2ecf20Sopenharmony_ci#define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \
8858c2ecf20Sopenharmony_ci				decode_sequence_maxsz + \
8868c2ecf20Sopenharmony_ci				decode_putfh_maxsz + \
8878c2ecf20Sopenharmony_ci				decode_layoutreturn_maxsz)
8888c2ecf20Sopenharmony_ci#define NFS4_enc_secinfo_no_name_sz	(compound_encode_hdr_maxsz + \
8898c2ecf20Sopenharmony_ci					encode_sequence_maxsz + \
8908c2ecf20Sopenharmony_ci					encode_putrootfh_maxsz +\
8918c2ecf20Sopenharmony_ci					encode_secinfo_no_name_maxsz)
8928c2ecf20Sopenharmony_ci#define NFS4_dec_secinfo_no_name_sz	(compound_decode_hdr_maxsz + \
8938c2ecf20Sopenharmony_ci					decode_sequence_maxsz + \
8948c2ecf20Sopenharmony_ci					decode_putrootfh_maxsz + \
8958c2ecf20Sopenharmony_ci					decode_secinfo_no_name_maxsz)
8968c2ecf20Sopenharmony_ci#define NFS4_enc_test_stateid_sz	(compound_encode_hdr_maxsz + \
8978c2ecf20Sopenharmony_ci					 encode_sequence_maxsz + \
8988c2ecf20Sopenharmony_ci					 encode_test_stateid_maxsz)
8998c2ecf20Sopenharmony_ci#define NFS4_dec_test_stateid_sz	(compound_decode_hdr_maxsz + \
9008c2ecf20Sopenharmony_ci					 decode_sequence_maxsz + \
9018c2ecf20Sopenharmony_ci					 decode_test_stateid_maxsz)
9028c2ecf20Sopenharmony_ci#define NFS4_enc_free_stateid_sz	(compound_encode_hdr_maxsz + \
9038c2ecf20Sopenharmony_ci					 encode_sequence_maxsz + \
9048c2ecf20Sopenharmony_ci					 encode_free_stateid_maxsz)
9058c2ecf20Sopenharmony_ci#define NFS4_dec_free_stateid_sz	(compound_decode_hdr_maxsz + \
9068c2ecf20Sopenharmony_ci					 decode_sequence_maxsz + \
9078c2ecf20Sopenharmony_ci					 decode_free_stateid_maxsz)
9088c2ecf20Sopenharmony_ci
9098c2ecf20Sopenharmony_ciconst u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
9108c2ecf20Sopenharmony_ci				      compound_encode_hdr_maxsz +
9118c2ecf20Sopenharmony_ci				      encode_sequence_maxsz +
9128c2ecf20Sopenharmony_ci				      encode_putfh_maxsz +
9138c2ecf20Sopenharmony_ci				      encode_getattr_maxsz) *
9148c2ecf20Sopenharmony_ci				     XDR_UNIT);
9158c2ecf20Sopenharmony_ci
9168c2ecf20Sopenharmony_ciconst u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
9178c2ecf20Sopenharmony_ci				     compound_decode_hdr_maxsz +
9188c2ecf20Sopenharmony_ci				     decode_sequence_maxsz +
9198c2ecf20Sopenharmony_ci				     decode_putfh_maxsz) *
9208c2ecf20Sopenharmony_ci				    XDR_UNIT);
9218c2ecf20Sopenharmony_ci
9228c2ecf20Sopenharmony_ciconst u32 nfs41_maxgetdevinfo_overhead = ((RPC_MAX_REPHEADER_WITH_AUTH +
9238c2ecf20Sopenharmony_ci					   compound_decode_hdr_maxsz +
9248c2ecf20Sopenharmony_ci					   decode_sequence_maxsz) *
9258c2ecf20Sopenharmony_ci					  XDR_UNIT);
9268c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(nfs41_maxgetdevinfo_overhead);
9278c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_cistatic const umode_t nfs_type2fmt[] = {
9308c2ecf20Sopenharmony_ci	[NF4BAD] = 0,
9318c2ecf20Sopenharmony_ci	[NF4REG] = S_IFREG,
9328c2ecf20Sopenharmony_ci	[NF4DIR] = S_IFDIR,
9338c2ecf20Sopenharmony_ci	[NF4BLK] = S_IFBLK,
9348c2ecf20Sopenharmony_ci	[NF4CHR] = S_IFCHR,
9358c2ecf20Sopenharmony_ci	[NF4LNK] = S_IFLNK,
9368c2ecf20Sopenharmony_ci	[NF4SOCK] = S_IFSOCK,
9378c2ecf20Sopenharmony_ci	[NF4FIFO] = S_IFIFO,
9388c2ecf20Sopenharmony_ci	[NF4ATTRDIR] = 0,
9398c2ecf20Sopenharmony_ci	[NF4NAMEDATTR] = 0,
9408c2ecf20Sopenharmony_ci};
9418c2ecf20Sopenharmony_ci
9428c2ecf20Sopenharmony_cistruct compound_hdr {
9438c2ecf20Sopenharmony_ci	int32_t		status;
9448c2ecf20Sopenharmony_ci	uint32_t	nops;
9458c2ecf20Sopenharmony_ci	__be32 *	nops_p;
9468c2ecf20Sopenharmony_ci	uint32_t	taglen;
9478c2ecf20Sopenharmony_ci	char *		tag;
9488c2ecf20Sopenharmony_ci	uint32_t	replen;		/* expected reply words */
9498c2ecf20Sopenharmony_ci	u32		minorversion;
9508c2ecf20Sopenharmony_ci};
9518c2ecf20Sopenharmony_ci
9528c2ecf20Sopenharmony_cistatic __be32 *reserve_space(struct xdr_stream *xdr, size_t nbytes)
9538c2ecf20Sopenharmony_ci{
9548c2ecf20Sopenharmony_ci	__be32 *p = xdr_reserve_space(xdr, nbytes);
9558c2ecf20Sopenharmony_ci	BUG_ON(!p);
9568c2ecf20Sopenharmony_ci	return p;
9578c2ecf20Sopenharmony_ci}
9588c2ecf20Sopenharmony_ci
9598c2ecf20Sopenharmony_cistatic void encode_opaque_fixed(struct xdr_stream *xdr, const void *buf, size_t len)
9608c2ecf20Sopenharmony_ci{
9618c2ecf20Sopenharmony_ci	WARN_ON_ONCE(xdr_stream_encode_opaque_fixed(xdr, buf, len) < 0);
9628c2ecf20Sopenharmony_ci}
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_cistatic void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
9658c2ecf20Sopenharmony_ci{
9668c2ecf20Sopenharmony_ci	WARN_ON_ONCE(xdr_stream_encode_opaque(xdr, str, len) < 0);
9678c2ecf20Sopenharmony_ci}
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_cistatic void encode_uint32(struct xdr_stream *xdr, u32 n)
9708c2ecf20Sopenharmony_ci{
9718c2ecf20Sopenharmony_ci	WARN_ON_ONCE(xdr_stream_encode_u32(xdr, n) < 0);
9728c2ecf20Sopenharmony_ci}
9738c2ecf20Sopenharmony_ci
9748c2ecf20Sopenharmony_cistatic void encode_uint64(struct xdr_stream *xdr, u64 n)
9758c2ecf20Sopenharmony_ci{
9768c2ecf20Sopenharmony_ci	WARN_ON_ONCE(xdr_stream_encode_u64(xdr, n) < 0);
9778c2ecf20Sopenharmony_ci}
9788c2ecf20Sopenharmony_ci
9798c2ecf20Sopenharmony_cistatic ssize_t xdr_encode_bitmap4(struct xdr_stream *xdr,
9808c2ecf20Sopenharmony_ci		const __u32 *bitmap, size_t len)
9818c2ecf20Sopenharmony_ci{
9828c2ecf20Sopenharmony_ci	ssize_t ret;
9838c2ecf20Sopenharmony_ci
9848c2ecf20Sopenharmony_ci	/* Trim empty words */
9858c2ecf20Sopenharmony_ci	while (len > 0 && bitmap[len-1] == 0)
9868c2ecf20Sopenharmony_ci		len--;
9878c2ecf20Sopenharmony_ci	ret = xdr_stream_encode_uint32_array(xdr, bitmap, len);
9888c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(ret < 0))
9898c2ecf20Sopenharmony_ci		return ret;
9908c2ecf20Sopenharmony_ci	return len;
9918c2ecf20Sopenharmony_ci}
9928c2ecf20Sopenharmony_ci
9938c2ecf20Sopenharmony_cistatic size_t mask_bitmap4(const __u32 *bitmap, const __u32 *mask,
9948c2ecf20Sopenharmony_ci		__u32 *res, size_t len)
9958c2ecf20Sopenharmony_ci{
9968c2ecf20Sopenharmony_ci	size_t i;
9978c2ecf20Sopenharmony_ci	__u32 tmp;
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_ci	while (len > 0 && (bitmap[len-1] == 0 || mask[len-1] == 0))
10008c2ecf20Sopenharmony_ci		len--;
10018c2ecf20Sopenharmony_ci	for (i = len; i-- > 0;) {
10028c2ecf20Sopenharmony_ci		tmp = bitmap[i] & mask[i];
10038c2ecf20Sopenharmony_ci		res[i] = tmp;
10048c2ecf20Sopenharmony_ci	}
10058c2ecf20Sopenharmony_ci	return len;
10068c2ecf20Sopenharmony_ci}
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_cistatic void encode_nfs4_seqid(struct xdr_stream *xdr,
10098c2ecf20Sopenharmony_ci		const struct nfs_seqid *seqid)
10108c2ecf20Sopenharmony_ci{
10118c2ecf20Sopenharmony_ci	if (seqid != NULL)
10128c2ecf20Sopenharmony_ci		encode_uint32(xdr, seqid->sequence->counter);
10138c2ecf20Sopenharmony_ci	else
10148c2ecf20Sopenharmony_ci		encode_uint32(xdr, 0);
10158c2ecf20Sopenharmony_ci}
10168c2ecf20Sopenharmony_ci
10178c2ecf20Sopenharmony_cistatic void encode_compound_hdr(struct xdr_stream *xdr,
10188c2ecf20Sopenharmony_ci				struct rpc_rqst *req,
10198c2ecf20Sopenharmony_ci				struct compound_hdr *hdr)
10208c2ecf20Sopenharmony_ci{
10218c2ecf20Sopenharmony_ci	__be32 *p;
10228c2ecf20Sopenharmony_ci
10238c2ecf20Sopenharmony_ci	/* initialize running count of expected bytes in reply.
10248c2ecf20Sopenharmony_ci	 * NOTE: the replied tag SHOULD be the same is the one sent,
10258c2ecf20Sopenharmony_ci	 * but this is not required as a MUST for the server to do so. */
10268c2ecf20Sopenharmony_ci	hdr->replen = 3 + hdr->taglen;
10278c2ecf20Sopenharmony_ci
10288c2ecf20Sopenharmony_ci	WARN_ON_ONCE(hdr->taglen > NFS4_MAXTAGLEN);
10298c2ecf20Sopenharmony_ci	encode_string(xdr, hdr->taglen, hdr->tag);
10308c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 8);
10318c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(hdr->minorversion);
10328c2ecf20Sopenharmony_ci	hdr->nops_p = p;
10338c2ecf20Sopenharmony_ci	*p = cpu_to_be32(hdr->nops);
10348c2ecf20Sopenharmony_ci}
10358c2ecf20Sopenharmony_ci
10368c2ecf20Sopenharmony_cistatic void encode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 op,
10378c2ecf20Sopenharmony_ci		uint32_t replen,
10388c2ecf20Sopenharmony_ci		struct compound_hdr *hdr)
10398c2ecf20Sopenharmony_ci{
10408c2ecf20Sopenharmony_ci	encode_uint32(xdr, op);
10418c2ecf20Sopenharmony_ci	hdr->nops++;
10428c2ecf20Sopenharmony_ci	hdr->replen += replen;
10438c2ecf20Sopenharmony_ci}
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_cistatic void encode_nops(struct compound_hdr *hdr)
10468c2ecf20Sopenharmony_ci{
10478c2ecf20Sopenharmony_ci	WARN_ON_ONCE(hdr->nops > NFS4_MAX_OPS);
10488c2ecf20Sopenharmony_ci	*hdr->nops_p = htonl(hdr->nops);
10498c2ecf20Sopenharmony_ci}
10508c2ecf20Sopenharmony_ci
10518c2ecf20Sopenharmony_cistatic void encode_nfs4_stateid(struct xdr_stream *xdr, const nfs4_stateid *stateid)
10528c2ecf20Sopenharmony_ci{
10538c2ecf20Sopenharmony_ci	encode_opaque_fixed(xdr, stateid, NFS4_STATEID_SIZE);
10548c2ecf20Sopenharmony_ci}
10558c2ecf20Sopenharmony_ci
10568c2ecf20Sopenharmony_cistatic void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf)
10578c2ecf20Sopenharmony_ci{
10588c2ecf20Sopenharmony_ci	encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE);
10598c2ecf20Sopenharmony_ci}
10608c2ecf20Sopenharmony_ci
10618c2ecf20Sopenharmony_cistatic __be32 *
10628c2ecf20Sopenharmony_cixdr_encode_nfstime4(__be32 *p, const struct timespec64 *t)
10638c2ecf20Sopenharmony_ci{
10648c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, t->tv_sec);
10658c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(t->tv_nsec);
10668c2ecf20Sopenharmony_ci	return p;
10678c2ecf20Sopenharmony_ci}
10688c2ecf20Sopenharmony_ci
10698c2ecf20Sopenharmony_cistatic void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap,
10708c2ecf20Sopenharmony_ci				const struct nfs4_label *label,
10718c2ecf20Sopenharmony_ci				const umode_t *umask,
10728c2ecf20Sopenharmony_ci				const struct nfs_server *server,
10738c2ecf20Sopenharmony_ci				const uint32_t attrmask[])
10748c2ecf20Sopenharmony_ci{
10758c2ecf20Sopenharmony_ci	char owner_name[IDMAP_NAMESZ];
10768c2ecf20Sopenharmony_ci	char owner_group[IDMAP_NAMESZ];
10778c2ecf20Sopenharmony_ci	int owner_namelen = 0;
10788c2ecf20Sopenharmony_ci	int owner_grouplen = 0;
10798c2ecf20Sopenharmony_ci	__be32 *p;
10808c2ecf20Sopenharmony_ci	uint32_t len = 0;
10818c2ecf20Sopenharmony_ci	uint32_t bmval[3] = { 0 };
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	/*
10848c2ecf20Sopenharmony_ci	 * We reserve enough space to write the entire attribute buffer at once.
10858c2ecf20Sopenharmony_ci	 */
10868c2ecf20Sopenharmony_ci	if ((iap->ia_valid & ATTR_SIZE) && (attrmask[0] & FATTR4_WORD0_SIZE)) {
10878c2ecf20Sopenharmony_ci		bmval[0] |= FATTR4_WORD0_SIZE;
10888c2ecf20Sopenharmony_ci		len += 8;
10898c2ecf20Sopenharmony_ci	}
10908c2ecf20Sopenharmony_ci	if (iap->ia_valid & ATTR_MODE) {
10918c2ecf20Sopenharmony_ci		if (umask && (attrmask[2] & FATTR4_WORD2_MODE_UMASK)) {
10928c2ecf20Sopenharmony_ci			bmval[2] |= FATTR4_WORD2_MODE_UMASK;
10938c2ecf20Sopenharmony_ci			len += 8;
10948c2ecf20Sopenharmony_ci		} else if (attrmask[1] & FATTR4_WORD1_MODE) {
10958c2ecf20Sopenharmony_ci			bmval[1] |= FATTR4_WORD1_MODE;
10968c2ecf20Sopenharmony_ci			len += 4;
10978c2ecf20Sopenharmony_ci		}
10988c2ecf20Sopenharmony_ci	}
10998c2ecf20Sopenharmony_ci	if ((iap->ia_valid & ATTR_UID) && (attrmask[1] & FATTR4_WORD1_OWNER)) {
11008c2ecf20Sopenharmony_ci		owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ);
11018c2ecf20Sopenharmony_ci		if (owner_namelen < 0) {
11028c2ecf20Sopenharmony_ci			dprintk("nfs: couldn't resolve uid %d to string\n",
11038c2ecf20Sopenharmony_ci					from_kuid(&init_user_ns, iap->ia_uid));
11048c2ecf20Sopenharmony_ci			/* XXX */
11058c2ecf20Sopenharmony_ci			strcpy(owner_name, "nobody");
11068c2ecf20Sopenharmony_ci			owner_namelen = sizeof("nobody") - 1;
11078c2ecf20Sopenharmony_ci			/* goto out; */
11088c2ecf20Sopenharmony_ci		}
11098c2ecf20Sopenharmony_ci		bmval[1] |= FATTR4_WORD1_OWNER;
11108c2ecf20Sopenharmony_ci		len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
11118c2ecf20Sopenharmony_ci	}
11128c2ecf20Sopenharmony_ci	if ((iap->ia_valid & ATTR_GID) &&
11138c2ecf20Sopenharmony_ci	   (attrmask[1] & FATTR4_WORD1_OWNER_GROUP)) {
11148c2ecf20Sopenharmony_ci		owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ);
11158c2ecf20Sopenharmony_ci		if (owner_grouplen < 0) {
11168c2ecf20Sopenharmony_ci			dprintk("nfs: couldn't resolve gid %d to string\n",
11178c2ecf20Sopenharmony_ci					from_kgid(&init_user_ns, iap->ia_gid));
11188c2ecf20Sopenharmony_ci			strcpy(owner_group, "nobody");
11198c2ecf20Sopenharmony_ci			owner_grouplen = sizeof("nobody") - 1;
11208c2ecf20Sopenharmony_ci			/* goto out; */
11218c2ecf20Sopenharmony_ci		}
11228c2ecf20Sopenharmony_ci		bmval[1] |= FATTR4_WORD1_OWNER_GROUP;
11238c2ecf20Sopenharmony_ci		len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);
11248c2ecf20Sopenharmony_ci	}
11258c2ecf20Sopenharmony_ci	if (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
11268c2ecf20Sopenharmony_ci		if (iap->ia_valid & ATTR_ATIME_SET) {
11278c2ecf20Sopenharmony_ci			bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
11288c2ecf20Sopenharmony_ci			len += 4 + (nfstime4_maxsz << 2);
11298c2ecf20Sopenharmony_ci		} else if (iap->ia_valid & ATTR_ATIME) {
11308c2ecf20Sopenharmony_ci			bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
11318c2ecf20Sopenharmony_ci			len += 4;
11328c2ecf20Sopenharmony_ci		}
11338c2ecf20Sopenharmony_ci	}
11348c2ecf20Sopenharmony_ci	if (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
11358c2ecf20Sopenharmony_ci		if (iap->ia_valid & ATTR_MTIME_SET) {
11368c2ecf20Sopenharmony_ci			bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
11378c2ecf20Sopenharmony_ci			len += 4 + (nfstime4_maxsz << 2);
11388c2ecf20Sopenharmony_ci		} else if (iap->ia_valid & ATTR_MTIME) {
11398c2ecf20Sopenharmony_ci			bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
11408c2ecf20Sopenharmony_ci			len += 4;
11418c2ecf20Sopenharmony_ci		}
11428c2ecf20Sopenharmony_ci	}
11438c2ecf20Sopenharmony_ci
11448c2ecf20Sopenharmony_ci	if (label && (attrmask[2] & FATTR4_WORD2_SECURITY_LABEL)) {
11458c2ecf20Sopenharmony_ci		len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2);
11468c2ecf20Sopenharmony_ci		bmval[2] |= FATTR4_WORD2_SECURITY_LABEL;
11478c2ecf20Sopenharmony_ci	}
11488c2ecf20Sopenharmony_ci
11498c2ecf20Sopenharmony_ci	xdr_encode_bitmap4(xdr, bmval, ARRAY_SIZE(bmval));
11508c2ecf20Sopenharmony_ci	xdr_stream_encode_opaque_inline(xdr, (void **)&p, len);
11518c2ecf20Sopenharmony_ci
11528c2ecf20Sopenharmony_ci	if (bmval[0] & FATTR4_WORD0_SIZE)
11538c2ecf20Sopenharmony_ci		p = xdr_encode_hyper(p, iap->ia_size);
11548c2ecf20Sopenharmony_ci	if (bmval[1] & FATTR4_WORD1_MODE)
11558c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO);
11568c2ecf20Sopenharmony_ci	if (bmval[1] & FATTR4_WORD1_OWNER)
11578c2ecf20Sopenharmony_ci		p = xdr_encode_opaque(p, owner_name, owner_namelen);
11588c2ecf20Sopenharmony_ci	if (bmval[1] & FATTR4_WORD1_OWNER_GROUP)
11598c2ecf20Sopenharmony_ci		p = xdr_encode_opaque(p, owner_group, owner_grouplen);
11608c2ecf20Sopenharmony_ci	if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
11618c2ecf20Sopenharmony_ci		if (iap->ia_valid & ATTR_ATIME_SET) {
11628c2ecf20Sopenharmony_ci			*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
11638c2ecf20Sopenharmony_ci			p = xdr_encode_nfstime4(p, &iap->ia_atime);
11648c2ecf20Sopenharmony_ci		} else
11658c2ecf20Sopenharmony_ci			*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
11668c2ecf20Sopenharmony_ci	}
11678c2ecf20Sopenharmony_ci	if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
11688c2ecf20Sopenharmony_ci		if (iap->ia_valid & ATTR_MTIME_SET) {
11698c2ecf20Sopenharmony_ci			*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
11708c2ecf20Sopenharmony_ci			p = xdr_encode_nfstime4(p, &iap->ia_mtime);
11718c2ecf20Sopenharmony_ci		} else
11728c2ecf20Sopenharmony_ci			*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
11738c2ecf20Sopenharmony_ci	}
11748c2ecf20Sopenharmony_ci	if (label && (bmval[2] & FATTR4_WORD2_SECURITY_LABEL)) {
11758c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(label->lfs);
11768c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(label->pi);
11778c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(label->len);
11788c2ecf20Sopenharmony_ci		p = xdr_encode_opaque_fixed(p, label->label, label->len);
11798c2ecf20Sopenharmony_ci	}
11808c2ecf20Sopenharmony_ci	if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
11818c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO);
11828c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(*umask);
11838c2ecf20Sopenharmony_ci	}
11848c2ecf20Sopenharmony_ci
11858c2ecf20Sopenharmony_ci/* out: */
11868c2ecf20Sopenharmony_ci}
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_cistatic void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hdr *hdr)
11898c2ecf20Sopenharmony_ci{
11908c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_ACCESS, decode_access_maxsz, hdr);
11918c2ecf20Sopenharmony_ci	encode_uint32(xdr, access);
11928c2ecf20Sopenharmony_ci}
11938c2ecf20Sopenharmony_ci
11948c2ecf20Sopenharmony_cistatic void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
11958c2ecf20Sopenharmony_ci{
11968c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_CLOSE, decode_close_maxsz, hdr);
11978c2ecf20Sopenharmony_ci	encode_nfs4_seqid(xdr, arg->seqid);
11988c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &arg->stateid);
11998c2ecf20Sopenharmony_ci}
12008c2ecf20Sopenharmony_ci
12018c2ecf20Sopenharmony_cistatic void encode_commit(struct xdr_stream *xdr, const struct nfs_commitargs *args, struct compound_hdr *hdr)
12028c2ecf20Sopenharmony_ci{
12038c2ecf20Sopenharmony_ci	__be32 *p;
12048c2ecf20Sopenharmony_ci
12058c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
12068c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 12);
12078c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->offset);
12088c2ecf20Sopenharmony_ci	*p = cpu_to_be32(args->count);
12098c2ecf20Sopenharmony_ci}
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_cistatic void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr)
12128c2ecf20Sopenharmony_ci{
12138c2ecf20Sopenharmony_ci	__be32 *p;
12148c2ecf20Sopenharmony_ci
12158c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_CREATE, decode_create_maxsz, hdr);
12168c2ecf20Sopenharmony_ci	encode_uint32(xdr, create->ftype);
12178c2ecf20Sopenharmony_ci
12188c2ecf20Sopenharmony_ci	switch (create->ftype) {
12198c2ecf20Sopenharmony_ci	case NF4LNK:
12208c2ecf20Sopenharmony_ci		p = reserve_space(xdr, 4);
12218c2ecf20Sopenharmony_ci		*p = cpu_to_be32(create->u.symlink.len);
12228c2ecf20Sopenharmony_ci		xdr_write_pages(xdr, create->u.symlink.pages, 0,
12238c2ecf20Sopenharmony_ci				create->u.symlink.len);
12248c2ecf20Sopenharmony_ci		xdr->buf->flags |= XDRBUF_WRITE;
12258c2ecf20Sopenharmony_ci		break;
12268c2ecf20Sopenharmony_ci
12278c2ecf20Sopenharmony_ci	case NF4BLK: case NF4CHR:
12288c2ecf20Sopenharmony_ci		p = reserve_space(xdr, 8);
12298c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(create->u.device.specdata1);
12308c2ecf20Sopenharmony_ci		*p = cpu_to_be32(create->u.device.specdata2);
12318c2ecf20Sopenharmony_ci		break;
12328c2ecf20Sopenharmony_ci
12338c2ecf20Sopenharmony_ci	default:
12348c2ecf20Sopenharmony_ci		break;
12358c2ecf20Sopenharmony_ci	}
12368c2ecf20Sopenharmony_ci
12378c2ecf20Sopenharmony_ci	encode_string(xdr, create->name->len, create->name->name);
12388c2ecf20Sopenharmony_ci	encode_attrs(xdr, create->attrs, create->label, &create->umask,
12398c2ecf20Sopenharmony_ci			create->server, create->server->attr_bitmask);
12408c2ecf20Sopenharmony_ci}
12418c2ecf20Sopenharmony_ci
12428c2ecf20Sopenharmony_cistatic void encode_getattr(struct xdr_stream *xdr,
12438c2ecf20Sopenharmony_ci		const __u32 *bitmap, const __u32 *mask, size_t len,
12448c2ecf20Sopenharmony_ci		struct compound_hdr *hdr)
12458c2ecf20Sopenharmony_ci{
12468c2ecf20Sopenharmony_ci	__u32 masked_bitmap[nfs4_fattr_bitmap_maxsz];
12478c2ecf20Sopenharmony_ci
12488c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_GETATTR, decode_getattr_maxsz, hdr);
12498c2ecf20Sopenharmony_ci	if (mask) {
12508c2ecf20Sopenharmony_ci		if (WARN_ON_ONCE(len > ARRAY_SIZE(masked_bitmap)))
12518c2ecf20Sopenharmony_ci			len = ARRAY_SIZE(masked_bitmap);
12528c2ecf20Sopenharmony_ci		len = mask_bitmap4(bitmap, mask, masked_bitmap, len);
12538c2ecf20Sopenharmony_ci		bitmap = masked_bitmap;
12548c2ecf20Sopenharmony_ci	}
12558c2ecf20Sopenharmony_ci	xdr_encode_bitmap4(xdr, bitmap, len);
12568c2ecf20Sopenharmony_ci}
12578c2ecf20Sopenharmony_ci
12588c2ecf20Sopenharmony_cistatic void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
12598c2ecf20Sopenharmony_ci{
12608c2ecf20Sopenharmony_ci	encode_getattr(xdr, nfs4_fattr_bitmap, bitmask,
12618c2ecf20Sopenharmony_ci			ARRAY_SIZE(nfs4_fattr_bitmap), hdr);
12628c2ecf20Sopenharmony_ci}
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_cistatic void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,
12658c2ecf20Sopenharmony_ci				 const u32 *open_bitmap,
12668c2ecf20Sopenharmony_ci				 struct compound_hdr *hdr)
12678c2ecf20Sopenharmony_ci{
12688c2ecf20Sopenharmony_ci	encode_getattr(xdr, open_bitmap, bitmask, 3, hdr);
12698c2ecf20Sopenharmony_ci}
12708c2ecf20Sopenharmony_ci
12718c2ecf20Sopenharmony_cistatic void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
12728c2ecf20Sopenharmony_ci{
12738c2ecf20Sopenharmony_ci	encode_getattr(xdr, nfs4_fsinfo_bitmap, bitmask,
12748c2ecf20Sopenharmony_ci			ARRAY_SIZE(nfs4_fsinfo_bitmap), hdr);
12758c2ecf20Sopenharmony_ci}
12768c2ecf20Sopenharmony_ci
12778c2ecf20Sopenharmony_cistatic void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
12788c2ecf20Sopenharmony_ci{
12798c2ecf20Sopenharmony_ci	encode_getattr(xdr, nfs4_fs_locations_bitmap, bitmask,
12808c2ecf20Sopenharmony_ci			ARRAY_SIZE(nfs4_fs_locations_bitmap), hdr);
12818c2ecf20Sopenharmony_ci}
12828c2ecf20Sopenharmony_ci
12838c2ecf20Sopenharmony_cistatic void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
12848c2ecf20Sopenharmony_ci{
12858c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_GETFH, decode_getfh_maxsz, hdr);
12868c2ecf20Sopenharmony_ci}
12878c2ecf20Sopenharmony_ci
12888c2ecf20Sopenharmony_cistatic void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
12898c2ecf20Sopenharmony_ci{
12908c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LINK, decode_link_maxsz, hdr);
12918c2ecf20Sopenharmony_ci	encode_string(xdr, name->len, name->name);
12928c2ecf20Sopenharmony_ci}
12938c2ecf20Sopenharmony_ci
12948c2ecf20Sopenharmony_cistatic inline int nfs4_lock_type(struct file_lock *fl, int block)
12958c2ecf20Sopenharmony_ci{
12968c2ecf20Sopenharmony_ci	if (fl->fl_type == F_RDLCK)
12978c2ecf20Sopenharmony_ci		return block ? NFS4_READW_LT : NFS4_READ_LT;
12988c2ecf20Sopenharmony_ci	return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
12998c2ecf20Sopenharmony_ci}
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_cistatic inline uint64_t nfs4_lock_length(struct file_lock *fl)
13028c2ecf20Sopenharmony_ci{
13038c2ecf20Sopenharmony_ci	if (fl->fl_end == OFFSET_MAX)
13048c2ecf20Sopenharmony_ci		return ~(uint64_t)0;
13058c2ecf20Sopenharmony_ci	return fl->fl_end - fl->fl_start + 1;
13068c2ecf20Sopenharmony_ci}
13078c2ecf20Sopenharmony_ci
13088c2ecf20Sopenharmony_cistatic void encode_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner)
13098c2ecf20Sopenharmony_ci{
13108c2ecf20Sopenharmony_ci	__be32 *p;
13118c2ecf20Sopenharmony_ci
13128c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 32);
13138c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, lowner->clientid);
13148c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(20);
13158c2ecf20Sopenharmony_ci	p = xdr_encode_opaque_fixed(p, "lock id:", 8);
13168c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(lowner->s_dev);
13178c2ecf20Sopenharmony_ci	xdr_encode_hyper(p, lowner->id);
13188c2ecf20Sopenharmony_ci}
13198c2ecf20Sopenharmony_ci
13208c2ecf20Sopenharmony_ci/*
13218c2ecf20Sopenharmony_ci * opcode,type,reclaim,offset,length,new_lock_owner = 32
13228c2ecf20Sopenharmony_ci * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
13238c2ecf20Sopenharmony_ci */
13248c2ecf20Sopenharmony_cistatic void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args, struct compound_hdr *hdr)
13258c2ecf20Sopenharmony_ci{
13268c2ecf20Sopenharmony_ci	__be32 *p;
13278c2ecf20Sopenharmony_ci
13288c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LOCK, decode_lock_maxsz, hdr);
13298c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 28);
13308c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(nfs4_lock_type(args->fl, args->block));
13318c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->reclaim);
13328c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->fl->fl_start);
13338c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
13348c2ecf20Sopenharmony_ci	*p = cpu_to_be32(args->new_lock_owner);
13358c2ecf20Sopenharmony_ci	if (args->new_lock_owner){
13368c2ecf20Sopenharmony_ci		encode_nfs4_seqid(xdr, args->open_seqid);
13378c2ecf20Sopenharmony_ci		encode_nfs4_stateid(xdr, &args->open_stateid);
13388c2ecf20Sopenharmony_ci		encode_nfs4_seqid(xdr, args->lock_seqid);
13398c2ecf20Sopenharmony_ci		encode_lockowner(xdr, &args->lock_owner);
13408c2ecf20Sopenharmony_ci	}
13418c2ecf20Sopenharmony_ci	else {
13428c2ecf20Sopenharmony_ci		encode_nfs4_stateid(xdr, &args->lock_stateid);
13438c2ecf20Sopenharmony_ci		encode_nfs4_seqid(xdr, args->lock_seqid);
13448c2ecf20Sopenharmony_ci	}
13458c2ecf20Sopenharmony_ci}
13468c2ecf20Sopenharmony_ci
13478c2ecf20Sopenharmony_cistatic void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr)
13488c2ecf20Sopenharmony_ci{
13498c2ecf20Sopenharmony_ci	__be32 *p;
13508c2ecf20Sopenharmony_ci
13518c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LOCKT, decode_lockt_maxsz, hdr);
13528c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 20);
13538c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0));
13548c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->fl->fl_start);
13558c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
13568c2ecf20Sopenharmony_ci	encode_lockowner(xdr, &args->lock_owner);
13578c2ecf20Sopenharmony_ci}
13588c2ecf20Sopenharmony_ci
13598c2ecf20Sopenharmony_cistatic void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr)
13608c2ecf20Sopenharmony_ci{
13618c2ecf20Sopenharmony_ci	__be32 *p;
13628c2ecf20Sopenharmony_ci
13638c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LOCKU, decode_locku_maxsz, hdr);
13648c2ecf20Sopenharmony_ci	encode_uint32(xdr, nfs4_lock_type(args->fl, 0));
13658c2ecf20Sopenharmony_ci	encode_nfs4_seqid(xdr, args->seqid);
13668c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &args->stateid);
13678c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 16);
13688c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->fl->fl_start);
13698c2ecf20Sopenharmony_ci	xdr_encode_hyper(p, nfs4_lock_length(args->fl));
13708c2ecf20Sopenharmony_ci}
13718c2ecf20Sopenharmony_ci
13728c2ecf20Sopenharmony_cistatic void encode_release_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner, struct compound_hdr *hdr)
13738c2ecf20Sopenharmony_ci{
13748c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_RELEASE_LOCKOWNER, decode_release_lockowner_maxsz, hdr);
13758c2ecf20Sopenharmony_ci	encode_lockowner(xdr, lowner);
13768c2ecf20Sopenharmony_ci}
13778c2ecf20Sopenharmony_ci
13788c2ecf20Sopenharmony_cistatic void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
13798c2ecf20Sopenharmony_ci{
13808c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LOOKUP, decode_lookup_maxsz, hdr);
13818c2ecf20Sopenharmony_ci	encode_string(xdr, name->len, name->name);
13828c2ecf20Sopenharmony_ci}
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_cistatic void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr)
13858c2ecf20Sopenharmony_ci{
13868c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr);
13878c2ecf20Sopenharmony_ci}
13888c2ecf20Sopenharmony_ci
13898c2ecf20Sopenharmony_cistatic void encode_share_access(struct xdr_stream *xdr, u32 share_access)
13908c2ecf20Sopenharmony_ci{
13918c2ecf20Sopenharmony_ci	__be32 *p;
13928c2ecf20Sopenharmony_ci
13938c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 8);
13948c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(share_access);
13958c2ecf20Sopenharmony_ci	*p = cpu_to_be32(0);		/* for linux, share_deny = 0 always */
13968c2ecf20Sopenharmony_ci}
13978c2ecf20Sopenharmony_ci
13988c2ecf20Sopenharmony_cistatic inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)
13998c2ecf20Sopenharmony_ci{
14008c2ecf20Sopenharmony_ci	__be32 *p;
14018c2ecf20Sopenharmony_ci /*
14028c2ecf20Sopenharmony_ci * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
14038c2ecf20Sopenharmony_ci * owner 4 = 32
14048c2ecf20Sopenharmony_ci */
14058c2ecf20Sopenharmony_ci	encode_nfs4_seqid(xdr, arg->seqid);
14068c2ecf20Sopenharmony_ci	encode_share_access(xdr, arg->share_access);
14078c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 36);
14088c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, arg->clientid);
14098c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(24);
14108c2ecf20Sopenharmony_ci	p = xdr_encode_opaque_fixed(p, "open id:", 8);
14118c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(arg->server->s_dev);
14128c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(arg->id.uniquifier);
14138c2ecf20Sopenharmony_ci	xdr_encode_hyper(p, arg->id.create_time);
14148c2ecf20Sopenharmony_ci}
14158c2ecf20Sopenharmony_ci
14168c2ecf20Sopenharmony_cistatic inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
14178c2ecf20Sopenharmony_ci{
14188c2ecf20Sopenharmony_ci	__be32 *p;
14198c2ecf20Sopenharmony_ci
14208c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
14218c2ecf20Sopenharmony_ci	switch(arg->createmode) {
14228c2ecf20Sopenharmony_ci	case NFS4_CREATE_UNCHECKED:
14238c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
14248c2ecf20Sopenharmony_ci		encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask,
14258c2ecf20Sopenharmony_ci				arg->server, arg->server->attr_bitmask);
14268c2ecf20Sopenharmony_ci		break;
14278c2ecf20Sopenharmony_ci	case NFS4_CREATE_GUARDED:
14288c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_CREATE_GUARDED);
14298c2ecf20Sopenharmony_ci		encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask,
14308c2ecf20Sopenharmony_ci				arg->server, arg->server->attr_bitmask);
14318c2ecf20Sopenharmony_ci		break;
14328c2ecf20Sopenharmony_ci	case NFS4_CREATE_EXCLUSIVE:
14338c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
14348c2ecf20Sopenharmony_ci		encode_nfs4_verifier(xdr, &arg->u.verifier);
14358c2ecf20Sopenharmony_ci		break;
14368c2ecf20Sopenharmony_ci	case NFS4_CREATE_EXCLUSIVE4_1:
14378c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
14388c2ecf20Sopenharmony_ci		encode_nfs4_verifier(xdr, &arg->u.verifier);
14398c2ecf20Sopenharmony_ci		encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask,
14408c2ecf20Sopenharmony_ci				arg->server, arg->server->exclcreat_bitmask);
14418c2ecf20Sopenharmony_ci	}
14428c2ecf20Sopenharmony_ci}
14438c2ecf20Sopenharmony_ci
14448c2ecf20Sopenharmony_cistatic void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg)
14458c2ecf20Sopenharmony_ci{
14468c2ecf20Sopenharmony_ci	__be32 *p;
14478c2ecf20Sopenharmony_ci
14488c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
14498c2ecf20Sopenharmony_ci	switch (arg->open_flags & O_CREAT) {
14508c2ecf20Sopenharmony_ci	case 0:
14518c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_OPEN_NOCREATE);
14528c2ecf20Sopenharmony_ci		break;
14538c2ecf20Sopenharmony_ci	default:
14548c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_OPEN_CREATE);
14558c2ecf20Sopenharmony_ci		encode_createmode(xdr, arg);
14568c2ecf20Sopenharmony_ci	}
14578c2ecf20Sopenharmony_ci}
14588c2ecf20Sopenharmony_ci
14598c2ecf20Sopenharmony_cistatic inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delegation_type)
14608c2ecf20Sopenharmony_ci{
14618c2ecf20Sopenharmony_ci	__be32 *p;
14628c2ecf20Sopenharmony_ci
14638c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
14648c2ecf20Sopenharmony_ci	switch (delegation_type) {
14658c2ecf20Sopenharmony_ci	case 0:
14668c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_NONE);
14678c2ecf20Sopenharmony_ci		break;
14688c2ecf20Sopenharmony_ci	case FMODE_READ:
14698c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_READ);
14708c2ecf20Sopenharmony_ci		break;
14718c2ecf20Sopenharmony_ci	case FMODE_WRITE|FMODE_READ:
14728c2ecf20Sopenharmony_ci		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_WRITE);
14738c2ecf20Sopenharmony_ci		break;
14748c2ecf20Sopenharmony_ci	default:
14758c2ecf20Sopenharmony_ci		BUG();
14768c2ecf20Sopenharmony_ci	}
14778c2ecf20Sopenharmony_ci}
14788c2ecf20Sopenharmony_ci
14798c2ecf20Sopenharmony_cistatic inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name)
14808c2ecf20Sopenharmony_ci{
14818c2ecf20Sopenharmony_ci	__be32 *p;
14828c2ecf20Sopenharmony_ci
14838c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
14848c2ecf20Sopenharmony_ci	*p = cpu_to_be32(NFS4_OPEN_CLAIM_NULL);
14858c2ecf20Sopenharmony_ci	encode_string(xdr, name->len, name->name);
14868c2ecf20Sopenharmony_ci}
14878c2ecf20Sopenharmony_ci
14888c2ecf20Sopenharmony_cistatic inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type)
14898c2ecf20Sopenharmony_ci{
14908c2ecf20Sopenharmony_ci	__be32 *p;
14918c2ecf20Sopenharmony_ci
14928c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
14938c2ecf20Sopenharmony_ci	*p = cpu_to_be32(NFS4_OPEN_CLAIM_PREVIOUS);
14948c2ecf20Sopenharmony_ci	encode_delegation_type(xdr, type);
14958c2ecf20Sopenharmony_ci}
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_cistatic inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid)
14988c2ecf20Sopenharmony_ci{
14998c2ecf20Sopenharmony_ci	__be32 *p;
15008c2ecf20Sopenharmony_ci
15018c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
15028c2ecf20Sopenharmony_ci	*p = cpu_to_be32(NFS4_OPEN_CLAIM_DELEGATE_CUR);
15038c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, stateid);
15048c2ecf20Sopenharmony_ci	encode_string(xdr, name->len, name->name);
15058c2ecf20Sopenharmony_ci}
15068c2ecf20Sopenharmony_ci
15078c2ecf20Sopenharmony_cistatic inline void encode_claim_fh(struct xdr_stream *xdr)
15088c2ecf20Sopenharmony_ci{
15098c2ecf20Sopenharmony_ci	__be32 *p;
15108c2ecf20Sopenharmony_ci
15118c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
15128c2ecf20Sopenharmony_ci	*p = cpu_to_be32(NFS4_OPEN_CLAIM_FH);
15138c2ecf20Sopenharmony_ci}
15148c2ecf20Sopenharmony_ci
15158c2ecf20Sopenharmony_cistatic inline void encode_claim_delegate_cur_fh(struct xdr_stream *xdr, const nfs4_stateid *stateid)
15168c2ecf20Sopenharmony_ci{
15178c2ecf20Sopenharmony_ci	__be32 *p;
15188c2ecf20Sopenharmony_ci
15198c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
15208c2ecf20Sopenharmony_ci	*p = cpu_to_be32(NFS4_OPEN_CLAIM_DELEG_CUR_FH);
15218c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, stateid);
15228c2ecf20Sopenharmony_ci}
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_cistatic void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr)
15258c2ecf20Sopenharmony_ci{
15268c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_OPEN, decode_open_maxsz, hdr);
15278c2ecf20Sopenharmony_ci	encode_openhdr(xdr, arg);
15288c2ecf20Sopenharmony_ci	encode_opentype(xdr, arg);
15298c2ecf20Sopenharmony_ci	switch (arg->claim) {
15308c2ecf20Sopenharmony_ci	case NFS4_OPEN_CLAIM_NULL:
15318c2ecf20Sopenharmony_ci		encode_claim_null(xdr, arg->name);
15328c2ecf20Sopenharmony_ci		break;
15338c2ecf20Sopenharmony_ci	case NFS4_OPEN_CLAIM_PREVIOUS:
15348c2ecf20Sopenharmony_ci		encode_claim_previous(xdr, arg->u.delegation_type);
15358c2ecf20Sopenharmony_ci		break;
15368c2ecf20Sopenharmony_ci	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
15378c2ecf20Sopenharmony_ci		encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
15388c2ecf20Sopenharmony_ci		break;
15398c2ecf20Sopenharmony_ci	case NFS4_OPEN_CLAIM_FH:
15408c2ecf20Sopenharmony_ci		encode_claim_fh(xdr);
15418c2ecf20Sopenharmony_ci		break;
15428c2ecf20Sopenharmony_ci	case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
15438c2ecf20Sopenharmony_ci		encode_claim_delegate_cur_fh(xdr, &arg->u.delegation);
15448c2ecf20Sopenharmony_ci		break;
15458c2ecf20Sopenharmony_ci	default:
15468c2ecf20Sopenharmony_ci		BUG();
15478c2ecf20Sopenharmony_ci	}
15488c2ecf20Sopenharmony_ci}
15498c2ecf20Sopenharmony_ci
15508c2ecf20Sopenharmony_cistatic void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr)
15518c2ecf20Sopenharmony_ci{
15528c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_OPEN_CONFIRM, decode_open_confirm_maxsz, hdr);
15538c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, arg->stateid);
15548c2ecf20Sopenharmony_ci	encode_nfs4_seqid(xdr, arg->seqid);
15558c2ecf20Sopenharmony_ci}
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_cistatic void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
15588c2ecf20Sopenharmony_ci{
15598c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_OPEN_DOWNGRADE, decode_open_downgrade_maxsz, hdr);
15608c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &arg->stateid);
15618c2ecf20Sopenharmony_ci	encode_nfs4_seqid(xdr, arg->seqid);
15628c2ecf20Sopenharmony_ci	encode_share_access(xdr, arg->share_access);
15638c2ecf20Sopenharmony_ci}
15648c2ecf20Sopenharmony_ci
15658c2ecf20Sopenharmony_cistatic void
15668c2ecf20Sopenharmony_ciencode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hdr *hdr)
15678c2ecf20Sopenharmony_ci{
15688c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_PUTFH, decode_putfh_maxsz, hdr);
15698c2ecf20Sopenharmony_ci	encode_string(xdr, fh->size, fh->data);
15708c2ecf20Sopenharmony_ci}
15718c2ecf20Sopenharmony_ci
15728c2ecf20Sopenharmony_cistatic void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
15738c2ecf20Sopenharmony_ci{
15748c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_PUTROOTFH, decode_putrootfh_maxsz, hdr);
15758c2ecf20Sopenharmony_ci}
15768c2ecf20Sopenharmony_ci
15778c2ecf20Sopenharmony_cistatic void encode_read(struct xdr_stream *xdr, const struct nfs_pgio_args *args,
15788c2ecf20Sopenharmony_ci			struct compound_hdr *hdr)
15798c2ecf20Sopenharmony_ci{
15808c2ecf20Sopenharmony_ci	__be32 *p;
15818c2ecf20Sopenharmony_ci
15828c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_READ, decode_read_maxsz, hdr);
15838c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &args->stateid);
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 12);
15868c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->offset);
15878c2ecf20Sopenharmony_ci	*p = cpu_to_be32(args->count);
15888c2ecf20Sopenharmony_ci}
15898c2ecf20Sopenharmony_ci
15908c2ecf20Sopenharmony_cistatic void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
15918c2ecf20Sopenharmony_ci{
15928c2ecf20Sopenharmony_ci	uint32_t attrs[3] = {
15938c2ecf20Sopenharmony_ci		FATTR4_WORD0_RDATTR_ERROR,
15948c2ecf20Sopenharmony_ci		FATTR4_WORD1_MOUNTED_ON_FILEID,
15958c2ecf20Sopenharmony_ci	};
15968c2ecf20Sopenharmony_ci	uint32_t dircount = readdir->count >> 1;
15978c2ecf20Sopenharmony_ci	__be32 *p, verf[2];
15988c2ecf20Sopenharmony_ci	uint32_t attrlen = 0;
15998c2ecf20Sopenharmony_ci	unsigned int i;
16008c2ecf20Sopenharmony_ci
16018c2ecf20Sopenharmony_ci	if (readdir->plus) {
16028c2ecf20Sopenharmony_ci		attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
16038c2ecf20Sopenharmony_ci			FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID;
16048c2ecf20Sopenharmony_ci		attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER|
16058c2ecf20Sopenharmony_ci			FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
16068c2ecf20Sopenharmony_ci			FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
16078c2ecf20Sopenharmony_ci			FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
16088c2ecf20Sopenharmony_ci		attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
16098c2ecf20Sopenharmony_ci		dircount >>= 1;
16108c2ecf20Sopenharmony_ci	}
16118c2ecf20Sopenharmony_ci	/* Use mounted_on_fileid only if the server supports it */
16128c2ecf20Sopenharmony_ci	if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID))
16138c2ecf20Sopenharmony_ci		attrs[0] |= FATTR4_WORD0_FILEID;
16148c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(attrs); i++) {
16158c2ecf20Sopenharmony_ci		attrs[i] &= readdir->bitmask[i];
16168c2ecf20Sopenharmony_ci		if (attrs[i] != 0)
16178c2ecf20Sopenharmony_ci			attrlen = i+1;
16188c2ecf20Sopenharmony_ci	}
16198c2ecf20Sopenharmony_ci
16208c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr);
16218c2ecf20Sopenharmony_ci	encode_uint64(xdr, readdir->cookie);
16228c2ecf20Sopenharmony_ci	encode_nfs4_verifier(xdr, &readdir->verifier);
16238c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 12 + (attrlen << 2));
16248c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(dircount);
16258c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(readdir->count);
16268c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(attrlen);
16278c2ecf20Sopenharmony_ci	for (i = 0; i < attrlen; i++)
16288c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(attrs[i]);
16298c2ecf20Sopenharmony_ci	memcpy(verf, readdir->verifier.data, sizeof(verf));
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_ci	dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n",
16328c2ecf20Sopenharmony_ci			__func__,
16338c2ecf20Sopenharmony_ci			(unsigned long long)readdir->cookie,
16348c2ecf20Sopenharmony_ci			verf[0], verf[1],
16358c2ecf20Sopenharmony_ci			attrs[0] & readdir->bitmask[0],
16368c2ecf20Sopenharmony_ci			attrs[1] & readdir->bitmask[1],
16378c2ecf20Sopenharmony_ci			attrs[2] & readdir->bitmask[2]);
16388c2ecf20Sopenharmony_ci}
16398c2ecf20Sopenharmony_ci
16408c2ecf20Sopenharmony_cistatic void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr)
16418c2ecf20Sopenharmony_ci{
16428c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_READLINK, decode_readlink_maxsz, hdr);
16438c2ecf20Sopenharmony_ci}
16448c2ecf20Sopenharmony_ci
16458c2ecf20Sopenharmony_cistatic void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
16468c2ecf20Sopenharmony_ci{
16478c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_REMOVE, decode_remove_maxsz, hdr);
16488c2ecf20Sopenharmony_ci	encode_string(xdr, name->len, name->name);
16498c2ecf20Sopenharmony_ci}
16508c2ecf20Sopenharmony_ci
16518c2ecf20Sopenharmony_cistatic void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr)
16528c2ecf20Sopenharmony_ci{
16538c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_RENAME, decode_rename_maxsz, hdr);
16548c2ecf20Sopenharmony_ci	encode_string(xdr, oldname->len, oldname->name);
16558c2ecf20Sopenharmony_ci	encode_string(xdr, newname->len, newname->name);
16568c2ecf20Sopenharmony_ci}
16578c2ecf20Sopenharmony_ci
16588c2ecf20Sopenharmony_cistatic void encode_renew(struct xdr_stream *xdr, clientid4 clid,
16598c2ecf20Sopenharmony_ci			 struct compound_hdr *hdr)
16608c2ecf20Sopenharmony_ci{
16618c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_RENEW, decode_renew_maxsz, hdr);
16628c2ecf20Sopenharmony_ci	encode_uint64(xdr, clid);
16638c2ecf20Sopenharmony_ci}
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_cistatic void
16668c2ecf20Sopenharmony_ciencode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
16678c2ecf20Sopenharmony_ci{
16688c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_RESTOREFH, decode_restorefh_maxsz, hdr);
16698c2ecf20Sopenharmony_ci}
16708c2ecf20Sopenharmony_ci
16718c2ecf20Sopenharmony_cistatic void
16728c2ecf20Sopenharmony_ciencode_setacl(struct xdr_stream *xdr, const struct nfs_setaclargs *arg,
16738c2ecf20Sopenharmony_ci		struct compound_hdr *hdr)
16748c2ecf20Sopenharmony_ci{
16758c2ecf20Sopenharmony_ci	__be32 *p;
16768c2ecf20Sopenharmony_ci
16778c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SETATTR, decode_setacl_maxsz, hdr);
16788c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &zero_stateid);
16798c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 2*4);
16808c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(1);
16818c2ecf20Sopenharmony_ci	*p = cpu_to_be32(FATTR4_WORD0_ACL);
16828c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
16838c2ecf20Sopenharmony_ci	*p = cpu_to_be32(arg->acl_len);
16848c2ecf20Sopenharmony_ci	xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len);
16858c2ecf20Sopenharmony_ci}
16868c2ecf20Sopenharmony_ci
16878c2ecf20Sopenharmony_cistatic void
16888c2ecf20Sopenharmony_ciencode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
16898c2ecf20Sopenharmony_ci{
16908c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SAVEFH, decode_savefh_maxsz, hdr);
16918c2ecf20Sopenharmony_ci}
16928c2ecf20Sopenharmony_ci
16938c2ecf20Sopenharmony_cistatic void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr)
16948c2ecf20Sopenharmony_ci{
16958c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr);
16968c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &arg->stateid);
16978c2ecf20Sopenharmony_ci	encode_attrs(xdr, arg->iap, arg->label, NULL, server,
16988c2ecf20Sopenharmony_ci			server->attr_bitmask);
16998c2ecf20Sopenharmony_ci}
17008c2ecf20Sopenharmony_ci
17018c2ecf20Sopenharmony_cistatic void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
17028c2ecf20Sopenharmony_ci{
17038c2ecf20Sopenharmony_ci	__be32 *p;
17048c2ecf20Sopenharmony_ci
17058c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SETCLIENTID, decode_setclientid_maxsz, hdr);
17068c2ecf20Sopenharmony_ci	encode_nfs4_verifier(xdr, setclientid->sc_verifier);
17078c2ecf20Sopenharmony_ci
17088c2ecf20Sopenharmony_ci	encode_string(xdr, strlen(setclientid->sc_clnt->cl_owner_id),
17098c2ecf20Sopenharmony_ci			setclientid->sc_clnt->cl_owner_id);
17108c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
17118c2ecf20Sopenharmony_ci	*p = cpu_to_be32(setclientid->sc_prog);
17128c2ecf20Sopenharmony_ci	encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid);
17138c2ecf20Sopenharmony_ci	encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
17148c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4);
17158c2ecf20Sopenharmony_ci	*p = cpu_to_be32(setclientid->sc_clnt->cl_cb_ident);
17168c2ecf20Sopenharmony_ci}
17178c2ecf20Sopenharmony_ci
17188c2ecf20Sopenharmony_cistatic void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr)
17198c2ecf20Sopenharmony_ci{
17208c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SETCLIENTID_CONFIRM,
17218c2ecf20Sopenharmony_ci			decode_setclientid_confirm_maxsz, hdr);
17228c2ecf20Sopenharmony_ci	encode_uint64(xdr, arg->clientid);
17238c2ecf20Sopenharmony_ci	encode_nfs4_verifier(xdr, &arg->confirm);
17248c2ecf20Sopenharmony_ci}
17258c2ecf20Sopenharmony_ci
17268c2ecf20Sopenharmony_cistatic void encode_write(struct xdr_stream *xdr, const struct nfs_pgio_args *args,
17278c2ecf20Sopenharmony_ci			 struct compound_hdr *hdr)
17288c2ecf20Sopenharmony_ci{
17298c2ecf20Sopenharmony_ci	__be32 *p;
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_WRITE, decode_write_maxsz, hdr);
17328c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &args->stateid);
17338c2ecf20Sopenharmony_ci
17348c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 16);
17358c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->offset);
17368c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->stable);
17378c2ecf20Sopenharmony_ci	*p = cpu_to_be32(args->count);
17388c2ecf20Sopenharmony_ci
17398c2ecf20Sopenharmony_ci	xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
17408c2ecf20Sopenharmony_ci}
17418c2ecf20Sopenharmony_ci
17428c2ecf20Sopenharmony_cistatic void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr)
17438c2ecf20Sopenharmony_ci{
17448c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_DELEGRETURN, decode_delegreturn_maxsz, hdr);
17458c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, stateid);
17468c2ecf20Sopenharmony_ci}
17478c2ecf20Sopenharmony_ci
17488c2ecf20Sopenharmony_cistatic void encode_secinfo(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
17498c2ecf20Sopenharmony_ci{
17508c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SECINFO, decode_secinfo_maxsz, hdr);
17518c2ecf20Sopenharmony_ci	encode_string(xdr, name->len, name->name);
17528c2ecf20Sopenharmony_ci}
17538c2ecf20Sopenharmony_ci
17548c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
17558c2ecf20Sopenharmony_ci/* NFSv4.1 operations */
17568c2ecf20Sopenharmony_cistatic void encode_bind_conn_to_session(struct xdr_stream *xdr,
17578c2ecf20Sopenharmony_ci				   const struct nfs41_bind_conn_to_session_args *args,
17588c2ecf20Sopenharmony_ci				   struct compound_hdr *hdr)
17598c2ecf20Sopenharmony_ci{
17608c2ecf20Sopenharmony_ci	__be32 *p;
17618c2ecf20Sopenharmony_ci
17628c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION,
17638c2ecf20Sopenharmony_ci		decode_bind_conn_to_session_maxsz, hdr);
17648c2ecf20Sopenharmony_ci	encode_opaque_fixed(xdr, args->sessionid.data, NFS4_MAX_SESSIONID_LEN);
17658c2ecf20Sopenharmony_ci	p = xdr_reserve_space(xdr, 8);
17668c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->dir);
17678c2ecf20Sopenharmony_ci	*p = (args->use_conn_in_rdma_mode) ? cpu_to_be32(1) : cpu_to_be32(0);
17688c2ecf20Sopenharmony_ci}
17698c2ecf20Sopenharmony_ci
17708c2ecf20Sopenharmony_cistatic void encode_op_map(struct xdr_stream *xdr, const struct nfs4_op_map *op_map)
17718c2ecf20Sopenharmony_ci{
17728c2ecf20Sopenharmony_ci	unsigned int i;
17738c2ecf20Sopenharmony_ci	encode_uint32(xdr, NFS4_OP_MAP_NUM_WORDS);
17748c2ecf20Sopenharmony_ci	for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++)
17758c2ecf20Sopenharmony_ci		encode_uint32(xdr, op_map->u.words[i]);
17768c2ecf20Sopenharmony_ci}
17778c2ecf20Sopenharmony_ci
17788c2ecf20Sopenharmony_cistatic void encode_exchange_id(struct xdr_stream *xdr,
17798c2ecf20Sopenharmony_ci			       const struct nfs41_exchange_id_args *args,
17808c2ecf20Sopenharmony_ci			       struct compound_hdr *hdr)
17818c2ecf20Sopenharmony_ci{
17828c2ecf20Sopenharmony_ci	__be32 *p;
17838c2ecf20Sopenharmony_ci	char impl_name[IMPL_NAME_LIMIT];
17848c2ecf20Sopenharmony_ci	int len = 0;
17858c2ecf20Sopenharmony_ci
17868c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr);
17878c2ecf20Sopenharmony_ci	encode_nfs4_verifier(xdr, &args->verifier);
17888c2ecf20Sopenharmony_ci
17898c2ecf20Sopenharmony_ci	encode_string(xdr, strlen(args->client->cl_owner_id),
17908c2ecf20Sopenharmony_ci			args->client->cl_owner_id);
17918c2ecf20Sopenharmony_ci
17928c2ecf20Sopenharmony_ci	encode_uint32(xdr, args->flags);
17938c2ecf20Sopenharmony_ci	encode_uint32(xdr, args->state_protect.how);
17948c2ecf20Sopenharmony_ci
17958c2ecf20Sopenharmony_ci	switch (args->state_protect.how) {
17968c2ecf20Sopenharmony_ci	case SP4_NONE:
17978c2ecf20Sopenharmony_ci		break;
17988c2ecf20Sopenharmony_ci	case SP4_MACH_CRED:
17998c2ecf20Sopenharmony_ci		encode_op_map(xdr, &args->state_protect.enforce);
18008c2ecf20Sopenharmony_ci		encode_op_map(xdr, &args->state_protect.allow);
18018c2ecf20Sopenharmony_ci		break;
18028c2ecf20Sopenharmony_ci	default:
18038c2ecf20Sopenharmony_ci		WARN_ON_ONCE(1);
18048c2ecf20Sopenharmony_ci		break;
18058c2ecf20Sopenharmony_ci	}
18068c2ecf20Sopenharmony_ci
18078c2ecf20Sopenharmony_ci	if (send_implementation_id &&
18088c2ecf20Sopenharmony_ci	    sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
18098c2ecf20Sopenharmony_ci	    sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN)
18108c2ecf20Sopenharmony_ci		<= sizeof(impl_name) + 1)
18118c2ecf20Sopenharmony_ci		len = snprintf(impl_name, sizeof(impl_name), "%s %s %s %s",
18128c2ecf20Sopenharmony_ci			       utsname()->sysname, utsname()->release,
18138c2ecf20Sopenharmony_ci			       utsname()->version, utsname()->machine);
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_ci	if (len > 0) {
18168c2ecf20Sopenharmony_ci		encode_uint32(xdr, 1);	/* implementation id array length=1 */
18178c2ecf20Sopenharmony_ci
18188c2ecf20Sopenharmony_ci		encode_string(xdr,
18198c2ecf20Sopenharmony_ci			sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1,
18208c2ecf20Sopenharmony_ci			CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN);
18218c2ecf20Sopenharmony_ci		encode_string(xdr, len, impl_name);
18228c2ecf20Sopenharmony_ci		/* just send zeros for nii_date - the date is in nii_name */
18238c2ecf20Sopenharmony_ci		p = reserve_space(xdr, 12);
18248c2ecf20Sopenharmony_ci		p = xdr_encode_hyper(p, 0);
18258c2ecf20Sopenharmony_ci		*p = cpu_to_be32(0);
18268c2ecf20Sopenharmony_ci	} else
18278c2ecf20Sopenharmony_ci		encode_uint32(xdr, 0);	/* implementation id array length=0 */
18288c2ecf20Sopenharmony_ci}
18298c2ecf20Sopenharmony_ci
18308c2ecf20Sopenharmony_cistatic void encode_create_session(struct xdr_stream *xdr,
18318c2ecf20Sopenharmony_ci				  const struct nfs41_create_session_args *args,
18328c2ecf20Sopenharmony_ci				  struct compound_hdr *hdr)
18338c2ecf20Sopenharmony_ci{
18348c2ecf20Sopenharmony_ci	__be32 *p;
18358c2ecf20Sopenharmony_ci	struct nfs_client *clp = args->client;
18368c2ecf20Sopenharmony_ci	struct rpc_clnt *clnt = clp->cl_rpcclient;
18378c2ecf20Sopenharmony_ci	struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
18388c2ecf20Sopenharmony_ci	u32 max_resp_sz_cached;
18398c2ecf20Sopenharmony_ci
18408c2ecf20Sopenharmony_ci	/*
18418c2ecf20Sopenharmony_ci	 * Assumes OPEN is the biggest non-idempotent compound.
18428c2ecf20Sopenharmony_ci	 * 2 is the verifier.
18438c2ecf20Sopenharmony_ci	 */
18448c2ecf20Sopenharmony_ci	max_resp_sz_cached = (NFS4_dec_open_sz + RPC_REPHDRSIZE + 2)
18458c2ecf20Sopenharmony_ci				* XDR_UNIT + RPC_MAX_AUTH_SIZE;
18468c2ecf20Sopenharmony_ci
18478c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_CREATE_SESSION, decode_create_session_maxsz, hdr);
18488c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 16 + 2*28 + 20 + clnt->cl_nodelen + 12);
18498c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->clientid);
18508c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->seqid);			/*Sequence id */
18518c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->flags);			/*flags */
18528c2ecf20Sopenharmony_ci
18538c2ecf20Sopenharmony_ci	/* Fore Channel */
18548c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);				/* header padding size */
18558c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz);	/* max req size */
18568c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->fc_attrs.max_resp_sz);	/* max resp size */
18578c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(max_resp_sz_cached);		/* Max resp sz cached */
18588c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->fc_attrs.max_ops);	/* max operations */
18598c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->fc_attrs.max_reqs);	/* max requests */
18608c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);				/* rdmachannel_attrs */
18618c2ecf20Sopenharmony_ci
18628c2ecf20Sopenharmony_ci	/* Back Channel */
18638c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);				/* header padding size */
18648c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz);	/* max req size */
18658c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz);	/* max resp size */
18668c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached);	/* Max resp sz cached */
18678c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->bc_attrs.max_ops);	/* max operations */
18688c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->bc_attrs.max_reqs);	/* max requests */
18698c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);				/* rdmachannel_attrs */
18708c2ecf20Sopenharmony_ci
18718c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->cb_program);		/* cb_program */
18728c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(1);
18738c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(RPC_AUTH_UNIX);			/* auth_sys */
18748c2ecf20Sopenharmony_ci
18758c2ecf20Sopenharmony_ci	/* authsys_parms rfc1831 */
18768c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(ktime_to_ns(nn->boot_time));	/* stamp */
18778c2ecf20Sopenharmony_ci	p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
18788c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);				/* UID */
18798c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);				/* GID */
18808c2ecf20Sopenharmony_ci	*p = cpu_to_be32(0);				/* No more gids */
18818c2ecf20Sopenharmony_ci}
18828c2ecf20Sopenharmony_ci
18838c2ecf20Sopenharmony_cistatic void encode_destroy_session(struct xdr_stream *xdr,
18848c2ecf20Sopenharmony_ci				   const struct nfs4_session *session,
18858c2ecf20Sopenharmony_ci				   struct compound_hdr *hdr)
18868c2ecf20Sopenharmony_ci{
18878c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_DESTROY_SESSION, decode_destroy_session_maxsz, hdr);
18888c2ecf20Sopenharmony_ci	encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
18898c2ecf20Sopenharmony_ci}
18908c2ecf20Sopenharmony_ci
18918c2ecf20Sopenharmony_cistatic void encode_destroy_clientid(struct xdr_stream *xdr,
18928c2ecf20Sopenharmony_ci				   uint64_t clientid,
18938c2ecf20Sopenharmony_ci				   struct compound_hdr *hdr)
18948c2ecf20Sopenharmony_ci{
18958c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_DESTROY_CLIENTID, decode_destroy_clientid_maxsz, hdr);
18968c2ecf20Sopenharmony_ci	encode_uint64(xdr, clientid);
18978c2ecf20Sopenharmony_ci}
18988c2ecf20Sopenharmony_ci
18998c2ecf20Sopenharmony_cistatic void encode_reclaim_complete(struct xdr_stream *xdr,
19008c2ecf20Sopenharmony_ci				    const struct nfs41_reclaim_complete_args *args,
19018c2ecf20Sopenharmony_ci				    struct compound_hdr *hdr)
19028c2ecf20Sopenharmony_ci{
19038c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_RECLAIM_COMPLETE, decode_reclaim_complete_maxsz, hdr);
19048c2ecf20Sopenharmony_ci	encode_uint32(xdr, args->one_fs);
19058c2ecf20Sopenharmony_ci}
19068c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
19078c2ecf20Sopenharmony_ci
19088c2ecf20Sopenharmony_cistatic void encode_sequence(struct xdr_stream *xdr,
19098c2ecf20Sopenharmony_ci			    const struct nfs4_sequence_args *args,
19108c2ecf20Sopenharmony_ci			    struct compound_hdr *hdr)
19118c2ecf20Sopenharmony_ci{
19128c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
19138c2ecf20Sopenharmony_ci	struct nfs4_session *session;
19148c2ecf20Sopenharmony_ci	struct nfs4_slot_table *tp;
19158c2ecf20Sopenharmony_ci	struct nfs4_slot *slot = args->sa_slot;
19168c2ecf20Sopenharmony_ci	__be32 *p;
19178c2ecf20Sopenharmony_ci
19188c2ecf20Sopenharmony_ci	tp = slot->table;
19198c2ecf20Sopenharmony_ci	session = tp->session;
19208c2ecf20Sopenharmony_ci	if (!session)
19218c2ecf20Sopenharmony_ci		return;
19228c2ecf20Sopenharmony_ci
19238c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SEQUENCE, decode_sequence_maxsz, hdr);
19248c2ecf20Sopenharmony_ci
19258c2ecf20Sopenharmony_ci	/*
19268c2ecf20Sopenharmony_ci	 * Sessionid + seqid + slotid + max slotid + cache_this
19278c2ecf20Sopenharmony_ci	 */
19288c2ecf20Sopenharmony_ci	dprintk("%s: sessionid=%u:%u:%u:%u seqid=%d slotid=%d "
19298c2ecf20Sopenharmony_ci		"max_slotid=%d cache_this=%d\n",
19308c2ecf20Sopenharmony_ci		__func__,
19318c2ecf20Sopenharmony_ci		((u32 *)session->sess_id.data)[0],
19328c2ecf20Sopenharmony_ci		((u32 *)session->sess_id.data)[1],
19338c2ecf20Sopenharmony_ci		((u32 *)session->sess_id.data)[2],
19348c2ecf20Sopenharmony_ci		((u32 *)session->sess_id.data)[3],
19358c2ecf20Sopenharmony_ci		slot->seq_nr, slot->slot_nr,
19368c2ecf20Sopenharmony_ci		tp->highest_used_slotid, args->sa_cache_this);
19378c2ecf20Sopenharmony_ci	p = reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 16);
19388c2ecf20Sopenharmony_ci	p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
19398c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(slot->seq_nr);
19408c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(slot->slot_nr);
19418c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(tp->highest_used_slotid);
19428c2ecf20Sopenharmony_ci	*p = cpu_to_be32(args->sa_cache_this);
19438c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
19448c2ecf20Sopenharmony_ci}
19458c2ecf20Sopenharmony_ci
19468c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_1
19478c2ecf20Sopenharmony_cistatic void
19488c2ecf20Sopenharmony_ciencode_getdeviceinfo(struct xdr_stream *xdr,
19498c2ecf20Sopenharmony_ci		     const struct nfs4_getdeviceinfo_args *args,
19508c2ecf20Sopenharmony_ci		     struct compound_hdr *hdr)
19518c2ecf20Sopenharmony_ci{
19528c2ecf20Sopenharmony_ci	__be32 *p;
19538c2ecf20Sopenharmony_ci
19548c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_GETDEVICEINFO, decode_getdeviceinfo_maxsz, hdr);
19558c2ecf20Sopenharmony_ci	p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 4 + 4);
19568c2ecf20Sopenharmony_ci	p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data,
19578c2ecf20Sopenharmony_ci				    NFS4_DEVICEID4_SIZE);
19588c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->pdev->layout_type);
19598c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->pdev->maxcount);	/* gdia_maxcount */
19608c2ecf20Sopenharmony_ci
19618c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 4 + 4);
19628c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(1);			/* bitmap length */
19638c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->notify_types);
19648c2ecf20Sopenharmony_ci}
19658c2ecf20Sopenharmony_ci
19668c2ecf20Sopenharmony_cistatic void
19678c2ecf20Sopenharmony_ciencode_layoutget(struct xdr_stream *xdr,
19688c2ecf20Sopenharmony_ci		      const struct nfs4_layoutget_args *args,
19698c2ecf20Sopenharmony_ci		      struct compound_hdr *hdr)
19708c2ecf20Sopenharmony_ci{
19718c2ecf20Sopenharmony_ci	__be32 *p;
19728c2ecf20Sopenharmony_ci
19738c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LAYOUTGET, decode_layoutget_maxsz, hdr);
19748c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 36);
19758c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);     /* Signal layout available */
19768c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->type);
19778c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->range.iomode);
19788c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->range.offset);
19798c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->range.length);
19808c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->minlength);
19818c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &args->stateid);
19828c2ecf20Sopenharmony_ci	encode_uint32(xdr, args->maxcount);
19838c2ecf20Sopenharmony_ci
19848c2ecf20Sopenharmony_ci	dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d\n",
19858c2ecf20Sopenharmony_ci		__func__,
19868c2ecf20Sopenharmony_ci		args->type,
19878c2ecf20Sopenharmony_ci		args->range.iomode,
19888c2ecf20Sopenharmony_ci		(unsigned long)args->range.offset,
19898c2ecf20Sopenharmony_ci		(unsigned long)args->range.length,
19908c2ecf20Sopenharmony_ci		args->maxcount);
19918c2ecf20Sopenharmony_ci}
19928c2ecf20Sopenharmony_ci
19938c2ecf20Sopenharmony_cistatic int
19948c2ecf20Sopenharmony_ciencode_layoutcommit(struct xdr_stream *xdr,
19958c2ecf20Sopenharmony_ci		    struct inode *inode,
19968c2ecf20Sopenharmony_ci		    const struct nfs4_layoutcommit_args *args,
19978c2ecf20Sopenharmony_ci		    struct compound_hdr *hdr)
19988c2ecf20Sopenharmony_ci{
19998c2ecf20Sopenharmony_ci	__be32 *p;
20008c2ecf20Sopenharmony_ci
20018c2ecf20Sopenharmony_ci	dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten,
20028c2ecf20Sopenharmony_ci		NFS_SERVER(args->inode)->pnfs_curr_ld->id);
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LAYOUTCOMMIT, decode_layoutcommit_maxsz, hdr);
20058c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 20);
20068c2ecf20Sopenharmony_ci	/* Only whole file layouts */
20078c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, 0); /* offset */
20088c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->lastbytewritten + 1);	/* length */
20098c2ecf20Sopenharmony_ci	*p = cpu_to_be32(0); /* reclaim */
20108c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &args->stateid);
20118c2ecf20Sopenharmony_ci	if (args->lastbytewritten != U64_MAX) {
20128c2ecf20Sopenharmony_ci		p = reserve_space(xdr, 20);
20138c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(1); /* newoffset = TRUE */
20148c2ecf20Sopenharmony_ci		p = xdr_encode_hyper(p, args->lastbytewritten);
20158c2ecf20Sopenharmony_ci	} else {
20168c2ecf20Sopenharmony_ci		p = reserve_space(xdr, 12);
20178c2ecf20Sopenharmony_ci		*p++ = cpu_to_be32(0); /* newoffset = FALSE */
20188c2ecf20Sopenharmony_ci	}
20198c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0); /* Never send time_modify_changed */
20208c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
20218c2ecf20Sopenharmony_ci
20228c2ecf20Sopenharmony_ci	encode_uint32(xdr, args->layoutupdate_len);
20238c2ecf20Sopenharmony_ci	if (args->layoutupdate_pages)
20248c2ecf20Sopenharmony_ci		xdr_write_pages(xdr, args->layoutupdate_pages, 0,
20258c2ecf20Sopenharmony_ci				args->layoutupdate_len);
20268c2ecf20Sopenharmony_ci
20278c2ecf20Sopenharmony_ci	return 0;
20288c2ecf20Sopenharmony_ci}
20298c2ecf20Sopenharmony_ci
20308c2ecf20Sopenharmony_cistatic void
20318c2ecf20Sopenharmony_ciencode_layoutreturn(struct xdr_stream *xdr,
20328c2ecf20Sopenharmony_ci		    const struct nfs4_layoutreturn_args *args,
20338c2ecf20Sopenharmony_ci		    struct compound_hdr *hdr)
20348c2ecf20Sopenharmony_ci{
20358c2ecf20Sopenharmony_ci	__be32 *p;
20368c2ecf20Sopenharmony_ci
20378c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_LAYOUTRETURN, decode_layoutreturn_maxsz, hdr);
20388c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 16);
20398c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(0);		/* reclaim. always 0 for now */
20408c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->layout_type);
20418c2ecf20Sopenharmony_ci	*p++ = cpu_to_be32(args->range.iomode);
20428c2ecf20Sopenharmony_ci	*p = cpu_to_be32(RETURN_FILE);
20438c2ecf20Sopenharmony_ci	p = reserve_space(xdr, 16);
20448c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->range.offset);
20458c2ecf20Sopenharmony_ci	p = xdr_encode_hyper(p, args->range.length);
20468c2ecf20Sopenharmony_ci	spin_lock(&args->inode->i_lock);
20478c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &args->stateid);
20488c2ecf20Sopenharmony_ci	spin_unlock(&args->inode->i_lock);
20498c2ecf20Sopenharmony_ci	if (args->ld_private->ops && args->ld_private->ops->encode)
20508c2ecf20Sopenharmony_ci		args->ld_private->ops->encode(xdr, args, args->ld_private);
20518c2ecf20Sopenharmony_ci	else
20528c2ecf20Sopenharmony_ci		encode_uint32(xdr, 0);
20538c2ecf20Sopenharmony_ci}
20548c2ecf20Sopenharmony_ci
20558c2ecf20Sopenharmony_cistatic int
20568c2ecf20Sopenharmony_ciencode_secinfo_no_name(struct xdr_stream *xdr,
20578c2ecf20Sopenharmony_ci		       const struct nfs41_secinfo_no_name_args *args,
20588c2ecf20Sopenharmony_ci		       struct compound_hdr *hdr)
20598c2ecf20Sopenharmony_ci{
20608c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_SECINFO_NO_NAME, decode_secinfo_no_name_maxsz, hdr);
20618c2ecf20Sopenharmony_ci	encode_uint32(xdr, args->style);
20628c2ecf20Sopenharmony_ci	return 0;
20638c2ecf20Sopenharmony_ci}
20648c2ecf20Sopenharmony_ci
20658c2ecf20Sopenharmony_cistatic void encode_test_stateid(struct xdr_stream *xdr,
20668c2ecf20Sopenharmony_ci				const struct nfs41_test_stateid_args *args,
20678c2ecf20Sopenharmony_ci				struct compound_hdr *hdr)
20688c2ecf20Sopenharmony_ci{
20698c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_TEST_STATEID, decode_test_stateid_maxsz, hdr);
20708c2ecf20Sopenharmony_ci	encode_uint32(xdr, 1);
20718c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, args->stateid);
20728c2ecf20Sopenharmony_ci}
20738c2ecf20Sopenharmony_ci
20748c2ecf20Sopenharmony_cistatic void encode_free_stateid(struct xdr_stream *xdr,
20758c2ecf20Sopenharmony_ci				const struct nfs41_free_stateid_args *args,
20768c2ecf20Sopenharmony_ci				struct compound_hdr *hdr)
20778c2ecf20Sopenharmony_ci{
20788c2ecf20Sopenharmony_ci	encode_op_hdr(xdr, OP_FREE_STATEID, decode_free_stateid_maxsz, hdr);
20798c2ecf20Sopenharmony_ci	encode_nfs4_stateid(xdr, &args->stateid);
20808c2ecf20Sopenharmony_ci}
20818c2ecf20Sopenharmony_ci#else
20828c2ecf20Sopenharmony_cistatic inline void
20838c2ecf20Sopenharmony_ciencode_layoutreturn(struct xdr_stream *xdr,
20848c2ecf20Sopenharmony_ci		    const struct nfs4_layoutreturn_args *args,
20858c2ecf20Sopenharmony_ci		    struct compound_hdr *hdr)
20868c2ecf20Sopenharmony_ci{
20878c2ecf20Sopenharmony_ci}
20888c2ecf20Sopenharmony_ci
20898c2ecf20Sopenharmony_cistatic void
20908c2ecf20Sopenharmony_ciencode_layoutget(struct xdr_stream *xdr,
20918c2ecf20Sopenharmony_ci		      const struct nfs4_layoutget_args *args,
20928c2ecf20Sopenharmony_ci		      struct compound_hdr *hdr)
20938c2ecf20Sopenharmony_ci{
20948c2ecf20Sopenharmony_ci}
20958c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
20968c2ecf20Sopenharmony_ci
20978c2ecf20Sopenharmony_ci/*
20988c2ecf20Sopenharmony_ci * END OF "GENERIC" ENCODE ROUTINES.
20998c2ecf20Sopenharmony_ci */
21008c2ecf20Sopenharmony_ci
21018c2ecf20Sopenharmony_cistatic u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
21028c2ecf20Sopenharmony_ci{
21038c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
21048c2ecf20Sopenharmony_ci	struct nfs4_session *session = args->sa_slot->table->session;
21058c2ecf20Sopenharmony_ci	if (session)
21068c2ecf20Sopenharmony_ci		return session->clp->cl_mvops->minor_version;
21078c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
21088c2ecf20Sopenharmony_ci	return 0;
21098c2ecf20Sopenharmony_ci}
21108c2ecf20Sopenharmony_ci
21118c2ecf20Sopenharmony_ci/*
21128c2ecf20Sopenharmony_ci * Encode an ACCESS request
21138c2ecf20Sopenharmony_ci */
21148c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr,
21158c2ecf20Sopenharmony_ci				const void *data)
21168c2ecf20Sopenharmony_ci{
21178c2ecf20Sopenharmony_ci	const struct nfs4_accessargs *args = data;
21188c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
21198c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
21208c2ecf20Sopenharmony_ci	};
21218c2ecf20Sopenharmony_ci
21228c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
21238c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
21248c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
21258c2ecf20Sopenharmony_ci	encode_access(xdr, args->access, &hdr);
21268c2ecf20Sopenharmony_ci	if (args->bitmask)
21278c2ecf20Sopenharmony_ci		encode_getfattr(xdr, args->bitmask, &hdr);
21288c2ecf20Sopenharmony_ci	encode_nops(&hdr);
21298c2ecf20Sopenharmony_ci}
21308c2ecf20Sopenharmony_ci
21318c2ecf20Sopenharmony_ci/*
21328c2ecf20Sopenharmony_ci * Encode LOOKUP request
21338c2ecf20Sopenharmony_ci */
21348c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
21358c2ecf20Sopenharmony_ci				const void *data)
21368c2ecf20Sopenharmony_ci{
21378c2ecf20Sopenharmony_ci	const struct nfs4_lookup_arg *args = data;
21388c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
21398c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
21408c2ecf20Sopenharmony_ci	};
21418c2ecf20Sopenharmony_ci
21428c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
21438c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
21448c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->dir_fh, &hdr);
21458c2ecf20Sopenharmony_ci	encode_lookup(xdr, args->name, &hdr);
21468c2ecf20Sopenharmony_ci	encode_getfh(xdr, &hdr);
21478c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
21488c2ecf20Sopenharmony_ci	encode_nops(&hdr);
21498c2ecf20Sopenharmony_ci}
21508c2ecf20Sopenharmony_ci
21518c2ecf20Sopenharmony_ci/*
21528c2ecf20Sopenharmony_ci * Encode LOOKUPP request
21538c2ecf20Sopenharmony_ci */
21548c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr,
21558c2ecf20Sopenharmony_ci		const void *data)
21568c2ecf20Sopenharmony_ci{
21578c2ecf20Sopenharmony_ci	const struct nfs4_lookupp_arg *args = data;
21588c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
21598c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
21608c2ecf20Sopenharmony_ci	};
21618c2ecf20Sopenharmony_ci
21628c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
21638c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
21648c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
21658c2ecf20Sopenharmony_ci	encode_lookupp(xdr, &hdr);
21668c2ecf20Sopenharmony_ci	encode_getfh(xdr, &hdr);
21678c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
21688c2ecf20Sopenharmony_ci	encode_nops(&hdr);
21698c2ecf20Sopenharmony_ci}
21708c2ecf20Sopenharmony_ci
21718c2ecf20Sopenharmony_ci/*
21728c2ecf20Sopenharmony_ci * Encode LOOKUP_ROOT request
21738c2ecf20Sopenharmony_ci */
21748c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
21758c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
21768c2ecf20Sopenharmony_ci				     const void *data)
21778c2ecf20Sopenharmony_ci{
21788c2ecf20Sopenharmony_ci	const struct nfs4_lookup_root_arg *args = data;
21798c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
21808c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
21818c2ecf20Sopenharmony_ci	};
21828c2ecf20Sopenharmony_ci
21838c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
21848c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
21858c2ecf20Sopenharmony_ci	encode_putrootfh(xdr, &hdr);
21868c2ecf20Sopenharmony_ci	encode_getfh(xdr, &hdr);
21878c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
21888c2ecf20Sopenharmony_ci	encode_nops(&hdr);
21898c2ecf20Sopenharmony_ci}
21908c2ecf20Sopenharmony_ci
21918c2ecf20Sopenharmony_ci/*
21928c2ecf20Sopenharmony_ci * Encode REMOVE request
21938c2ecf20Sopenharmony_ci */
21948c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr,
21958c2ecf20Sopenharmony_ci				const void *data)
21968c2ecf20Sopenharmony_ci{
21978c2ecf20Sopenharmony_ci	const struct nfs_removeargs *args = data;
21988c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
21998c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
22008c2ecf20Sopenharmony_ci	};
22018c2ecf20Sopenharmony_ci
22028c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
22038c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
22048c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
22058c2ecf20Sopenharmony_ci	encode_remove(xdr, &args->name, &hdr);
22068c2ecf20Sopenharmony_ci	encode_nops(&hdr);
22078c2ecf20Sopenharmony_ci}
22088c2ecf20Sopenharmony_ci
22098c2ecf20Sopenharmony_ci/*
22108c2ecf20Sopenharmony_ci * Encode RENAME request
22118c2ecf20Sopenharmony_ci */
22128c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr,
22138c2ecf20Sopenharmony_ci				const void *data)
22148c2ecf20Sopenharmony_ci{
22158c2ecf20Sopenharmony_ci	const struct nfs_renameargs *args = data;
22168c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
22178c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
22188c2ecf20Sopenharmony_ci	};
22198c2ecf20Sopenharmony_ci
22208c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
22218c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
22228c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->old_dir, &hdr);
22238c2ecf20Sopenharmony_ci	encode_savefh(xdr, &hdr);
22248c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->new_dir, &hdr);
22258c2ecf20Sopenharmony_ci	encode_rename(xdr, args->old_name, args->new_name, &hdr);
22268c2ecf20Sopenharmony_ci	encode_nops(&hdr);
22278c2ecf20Sopenharmony_ci}
22288c2ecf20Sopenharmony_ci
22298c2ecf20Sopenharmony_ci/*
22308c2ecf20Sopenharmony_ci * Encode LINK request
22318c2ecf20Sopenharmony_ci */
22328c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr,
22338c2ecf20Sopenharmony_ci			      const void *data)
22348c2ecf20Sopenharmony_ci{
22358c2ecf20Sopenharmony_ci	const struct nfs4_link_arg *args = data;
22368c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
22378c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
22388c2ecf20Sopenharmony_ci	};
22398c2ecf20Sopenharmony_ci
22408c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
22418c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
22428c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
22438c2ecf20Sopenharmony_ci	encode_savefh(xdr, &hdr);
22448c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->dir_fh, &hdr);
22458c2ecf20Sopenharmony_ci	encode_link(xdr, args->name, &hdr);
22468c2ecf20Sopenharmony_ci	encode_restorefh(xdr, &hdr);
22478c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
22488c2ecf20Sopenharmony_ci	encode_nops(&hdr);
22498c2ecf20Sopenharmony_ci}
22508c2ecf20Sopenharmony_ci
22518c2ecf20Sopenharmony_ci/*
22528c2ecf20Sopenharmony_ci * Encode CREATE request
22538c2ecf20Sopenharmony_ci */
22548c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr,
22558c2ecf20Sopenharmony_ci				const void *data)
22568c2ecf20Sopenharmony_ci{
22578c2ecf20Sopenharmony_ci	const struct nfs4_create_arg *args = data;
22588c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
22598c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
22608c2ecf20Sopenharmony_ci	};
22618c2ecf20Sopenharmony_ci
22628c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
22638c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
22648c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->dir_fh, &hdr);
22658c2ecf20Sopenharmony_ci	encode_create(xdr, args, &hdr);
22668c2ecf20Sopenharmony_ci	encode_getfh(xdr, &hdr);
22678c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
22688c2ecf20Sopenharmony_ci	encode_nops(&hdr);
22698c2ecf20Sopenharmony_ci}
22708c2ecf20Sopenharmony_ci
22718c2ecf20Sopenharmony_ci/*
22728c2ecf20Sopenharmony_ci * Encode SYMLINK request
22738c2ecf20Sopenharmony_ci */
22748c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr,
22758c2ecf20Sopenharmony_ci				 const void *data)
22768c2ecf20Sopenharmony_ci{
22778c2ecf20Sopenharmony_ci	const struct nfs4_create_arg *args = data;
22788c2ecf20Sopenharmony_ci
22798c2ecf20Sopenharmony_ci	nfs4_xdr_enc_create(req, xdr, args);
22808c2ecf20Sopenharmony_ci}
22818c2ecf20Sopenharmony_ci
22828c2ecf20Sopenharmony_ci/*
22838c2ecf20Sopenharmony_ci * Encode GETATTR request
22848c2ecf20Sopenharmony_ci */
22858c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr,
22868c2ecf20Sopenharmony_ci				 const void *data)
22878c2ecf20Sopenharmony_ci{
22888c2ecf20Sopenharmony_ci	const struct nfs4_getattr_arg *args = data;
22898c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
22908c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
22918c2ecf20Sopenharmony_ci	};
22928c2ecf20Sopenharmony_ci
22938c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
22948c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
22958c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
22968c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
22978c2ecf20Sopenharmony_ci	encode_nops(&hdr);
22988c2ecf20Sopenharmony_ci}
22998c2ecf20Sopenharmony_ci
23008c2ecf20Sopenharmony_ci/*
23018c2ecf20Sopenharmony_ci * Encode a CLOSE request
23028c2ecf20Sopenharmony_ci */
23038c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr,
23048c2ecf20Sopenharmony_ci			       const void *data)
23058c2ecf20Sopenharmony_ci{
23068c2ecf20Sopenharmony_ci	const struct nfs_closeargs *args = data;
23078c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
23088c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
23098c2ecf20Sopenharmony_ci	};
23108c2ecf20Sopenharmony_ci
23118c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
23128c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
23138c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
23148c2ecf20Sopenharmony_ci	if (args->lr_args)
23158c2ecf20Sopenharmony_ci		encode_layoutreturn(xdr, args->lr_args, &hdr);
23168c2ecf20Sopenharmony_ci	if (args->bitmask != NULL)
23178c2ecf20Sopenharmony_ci		encode_getfattr(xdr, args->bitmask, &hdr);
23188c2ecf20Sopenharmony_ci	encode_close(xdr, args, &hdr);
23198c2ecf20Sopenharmony_ci	encode_nops(&hdr);
23208c2ecf20Sopenharmony_ci}
23218c2ecf20Sopenharmony_ci
23228c2ecf20Sopenharmony_ci/*
23238c2ecf20Sopenharmony_ci * Encode an OPEN request
23248c2ecf20Sopenharmony_ci */
23258c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
23268c2ecf20Sopenharmony_ci			      const void *data)
23278c2ecf20Sopenharmony_ci{
23288c2ecf20Sopenharmony_ci	const struct nfs_openargs *args = data;
23298c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
23308c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
23318c2ecf20Sopenharmony_ci	};
23328c2ecf20Sopenharmony_ci
23338c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
23348c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
23358c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
23368c2ecf20Sopenharmony_ci	encode_open(xdr, args, &hdr);
23378c2ecf20Sopenharmony_ci	encode_getfh(xdr, &hdr);
23388c2ecf20Sopenharmony_ci	if (args->access)
23398c2ecf20Sopenharmony_ci		encode_access(xdr, args->access, &hdr);
23408c2ecf20Sopenharmony_ci	encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
23418c2ecf20Sopenharmony_ci	if (args->lg_args) {
23428c2ecf20Sopenharmony_ci		encode_layoutget(xdr, args->lg_args, &hdr);
23438c2ecf20Sopenharmony_ci		rpc_prepare_reply_pages(req, args->lg_args->layout.pages, 0,
23448c2ecf20Sopenharmony_ci					args->lg_args->layout.pglen,
23458c2ecf20Sopenharmony_ci					hdr.replen);
23468c2ecf20Sopenharmony_ci	}
23478c2ecf20Sopenharmony_ci	encode_nops(&hdr);
23488c2ecf20Sopenharmony_ci}
23498c2ecf20Sopenharmony_ci
23508c2ecf20Sopenharmony_ci/*
23518c2ecf20Sopenharmony_ci * Encode an OPEN_CONFIRM request
23528c2ecf20Sopenharmony_ci */
23538c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req,
23548c2ecf20Sopenharmony_ci				      struct xdr_stream *xdr,
23558c2ecf20Sopenharmony_ci				      const void *data)
23568c2ecf20Sopenharmony_ci{
23578c2ecf20Sopenharmony_ci	const struct nfs_open_confirmargs *args = data;
23588c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
23598c2ecf20Sopenharmony_ci		.nops   = 0,
23608c2ecf20Sopenharmony_ci	};
23618c2ecf20Sopenharmony_ci
23628c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
23638c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
23648c2ecf20Sopenharmony_ci	encode_open_confirm(xdr, args, &hdr);
23658c2ecf20Sopenharmony_ci	encode_nops(&hdr);
23668c2ecf20Sopenharmony_ci}
23678c2ecf20Sopenharmony_ci
23688c2ecf20Sopenharmony_ci/*
23698c2ecf20Sopenharmony_ci * Encode an OPEN request with no attributes.
23708c2ecf20Sopenharmony_ci */
23718c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
23728c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
23738c2ecf20Sopenharmony_ci				     const void *data)
23748c2ecf20Sopenharmony_ci{
23758c2ecf20Sopenharmony_ci	const struct nfs_openargs *args = data;
23768c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
23778c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
23788c2ecf20Sopenharmony_ci	};
23798c2ecf20Sopenharmony_ci
23808c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
23818c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
23828c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
23838c2ecf20Sopenharmony_ci	encode_open(xdr, args, &hdr);
23848c2ecf20Sopenharmony_ci	if (args->access)
23858c2ecf20Sopenharmony_ci		encode_access(xdr, args->access, &hdr);
23868c2ecf20Sopenharmony_ci	encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
23878c2ecf20Sopenharmony_ci	if (args->lg_args) {
23888c2ecf20Sopenharmony_ci		encode_layoutget(xdr, args->lg_args, &hdr);
23898c2ecf20Sopenharmony_ci		rpc_prepare_reply_pages(req, args->lg_args->layout.pages, 0,
23908c2ecf20Sopenharmony_ci					args->lg_args->layout.pglen,
23918c2ecf20Sopenharmony_ci					hdr.replen);
23928c2ecf20Sopenharmony_ci	}
23938c2ecf20Sopenharmony_ci	encode_nops(&hdr);
23948c2ecf20Sopenharmony_ci}
23958c2ecf20Sopenharmony_ci
23968c2ecf20Sopenharmony_ci/*
23978c2ecf20Sopenharmony_ci * Encode an OPEN_DOWNGRADE request
23988c2ecf20Sopenharmony_ci */
23998c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req,
24008c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
24018c2ecf20Sopenharmony_ci					const void *data)
24028c2ecf20Sopenharmony_ci{
24038c2ecf20Sopenharmony_ci	const struct nfs_closeargs *args = data;
24048c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
24058c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
24068c2ecf20Sopenharmony_ci	};
24078c2ecf20Sopenharmony_ci
24088c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
24098c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
24108c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
24118c2ecf20Sopenharmony_ci	if (args->lr_args)
24128c2ecf20Sopenharmony_ci		encode_layoutreturn(xdr, args->lr_args, &hdr);
24138c2ecf20Sopenharmony_ci	encode_open_downgrade(xdr, args, &hdr);
24148c2ecf20Sopenharmony_ci	encode_nops(&hdr);
24158c2ecf20Sopenharmony_ci}
24168c2ecf20Sopenharmony_ci
24178c2ecf20Sopenharmony_ci/*
24188c2ecf20Sopenharmony_ci * Encode a LOCK request
24198c2ecf20Sopenharmony_ci */
24208c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr,
24218c2ecf20Sopenharmony_ci			      const void *data)
24228c2ecf20Sopenharmony_ci{
24238c2ecf20Sopenharmony_ci	const struct nfs_lock_args *args = data;
24248c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
24258c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
24268c2ecf20Sopenharmony_ci	};
24278c2ecf20Sopenharmony_ci
24288c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
24298c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
24308c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
24318c2ecf20Sopenharmony_ci	encode_lock(xdr, args, &hdr);
24328c2ecf20Sopenharmony_ci	encode_nops(&hdr);
24338c2ecf20Sopenharmony_ci}
24348c2ecf20Sopenharmony_ci
24358c2ecf20Sopenharmony_ci/*
24368c2ecf20Sopenharmony_ci * Encode a LOCKT request
24378c2ecf20Sopenharmony_ci */
24388c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr,
24398c2ecf20Sopenharmony_ci			       const void *data)
24408c2ecf20Sopenharmony_ci{
24418c2ecf20Sopenharmony_ci	const struct nfs_lockt_args *args = data;
24428c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
24438c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
24448c2ecf20Sopenharmony_ci	};
24458c2ecf20Sopenharmony_ci
24468c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
24478c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
24488c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
24498c2ecf20Sopenharmony_ci	encode_lockt(xdr, args, &hdr);
24508c2ecf20Sopenharmony_ci	encode_nops(&hdr);
24518c2ecf20Sopenharmony_ci}
24528c2ecf20Sopenharmony_ci
24538c2ecf20Sopenharmony_ci/*
24548c2ecf20Sopenharmony_ci * Encode a LOCKU request
24558c2ecf20Sopenharmony_ci */
24568c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr,
24578c2ecf20Sopenharmony_ci			       const void *data)
24588c2ecf20Sopenharmony_ci{
24598c2ecf20Sopenharmony_ci	const struct nfs_locku_args *args = data;
24608c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
24618c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
24628c2ecf20Sopenharmony_ci	};
24638c2ecf20Sopenharmony_ci
24648c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
24658c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
24668c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
24678c2ecf20Sopenharmony_ci	encode_locku(xdr, args, &hdr);
24688c2ecf20Sopenharmony_ci	encode_nops(&hdr);
24698c2ecf20Sopenharmony_ci}
24708c2ecf20Sopenharmony_ci
24718c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req,
24728c2ecf20Sopenharmony_ci					   struct xdr_stream *xdr,
24738c2ecf20Sopenharmony_ci					   const void *data)
24748c2ecf20Sopenharmony_ci{
24758c2ecf20Sopenharmony_ci	const struct nfs_release_lockowner_args *args = data;
24768c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
24778c2ecf20Sopenharmony_ci		.minorversion = 0,
24788c2ecf20Sopenharmony_ci	};
24798c2ecf20Sopenharmony_ci
24808c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
24818c2ecf20Sopenharmony_ci	encode_release_lockowner(xdr, &args->lock_owner, &hdr);
24828c2ecf20Sopenharmony_ci	encode_nops(&hdr);
24838c2ecf20Sopenharmony_ci}
24848c2ecf20Sopenharmony_ci
24858c2ecf20Sopenharmony_ci/*
24868c2ecf20Sopenharmony_ci * Encode a READLINK request
24878c2ecf20Sopenharmony_ci */
24888c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr,
24898c2ecf20Sopenharmony_ci				  const void *data)
24908c2ecf20Sopenharmony_ci{
24918c2ecf20Sopenharmony_ci	const struct nfs4_readlink *args = data;
24928c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
24938c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
24948c2ecf20Sopenharmony_ci	};
24958c2ecf20Sopenharmony_ci
24968c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
24978c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
24988c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
24998c2ecf20Sopenharmony_ci	encode_readlink(xdr, args, req, &hdr);
25008c2ecf20Sopenharmony_ci
25018c2ecf20Sopenharmony_ci	rpc_prepare_reply_pages(req, args->pages, args->pgbase,
25028c2ecf20Sopenharmony_ci				args->pglen, hdr.replen);
25038c2ecf20Sopenharmony_ci	encode_nops(&hdr);
25048c2ecf20Sopenharmony_ci}
25058c2ecf20Sopenharmony_ci
25068c2ecf20Sopenharmony_ci/*
25078c2ecf20Sopenharmony_ci * Encode a READDIR request
25088c2ecf20Sopenharmony_ci */
25098c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr,
25108c2ecf20Sopenharmony_ci				 const void *data)
25118c2ecf20Sopenharmony_ci{
25128c2ecf20Sopenharmony_ci	const struct nfs4_readdir_arg *args = data;
25138c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
25148c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
25158c2ecf20Sopenharmony_ci	};
25168c2ecf20Sopenharmony_ci
25178c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
25188c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
25198c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
25208c2ecf20Sopenharmony_ci	encode_readdir(xdr, args, req, &hdr);
25218c2ecf20Sopenharmony_ci
25228c2ecf20Sopenharmony_ci	rpc_prepare_reply_pages(req, args->pages, args->pgbase,
25238c2ecf20Sopenharmony_ci				args->count, hdr.replen);
25248c2ecf20Sopenharmony_ci	encode_nops(&hdr);
25258c2ecf20Sopenharmony_ci}
25268c2ecf20Sopenharmony_ci
25278c2ecf20Sopenharmony_ci/*
25288c2ecf20Sopenharmony_ci * Encode a READ request
25298c2ecf20Sopenharmony_ci */
25308c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr,
25318c2ecf20Sopenharmony_ci			      const void *data)
25328c2ecf20Sopenharmony_ci{
25338c2ecf20Sopenharmony_ci	const struct nfs_pgio_args *args = data;
25348c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
25358c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
25368c2ecf20Sopenharmony_ci	};
25378c2ecf20Sopenharmony_ci
25388c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
25398c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
25408c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
25418c2ecf20Sopenharmony_ci	encode_read(xdr, args, &hdr);
25428c2ecf20Sopenharmony_ci
25438c2ecf20Sopenharmony_ci	rpc_prepare_reply_pages(req, args->pages, args->pgbase,
25448c2ecf20Sopenharmony_ci				args->count, hdr.replen);
25458c2ecf20Sopenharmony_ci	req->rq_rcv_buf.flags |= XDRBUF_READ;
25468c2ecf20Sopenharmony_ci	encode_nops(&hdr);
25478c2ecf20Sopenharmony_ci}
25488c2ecf20Sopenharmony_ci
25498c2ecf20Sopenharmony_ci/*
25508c2ecf20Sopenharmony_ci * Encode an SETATTR request
25518c2ecf20Sopenharmony_ci */
25528c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr,
25538c2ecf20Sopenharmony_ci				 const void *data)
25548c2ecf20Sopenharmony_ci{
25558c2ecf20Sopenharmony_ci	const struct nfs_setattrargs *args = data;
25568c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
25578c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
25588c2ecf20Sopenharmony_ci	};
25598c2ecf20Sopenharmony_ci
25608c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
25618c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
25628c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
25638c2ecf20Sopenharmony_ci	encode_setattr(xdr, args, args->server, &hdr);
25648c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
25658c2ecf20Sopenharmony_ci	encode_nops(&hdr);
25668c2ecf20Sopenharmony_ci}
25678c2ecf20Sopenharmony_ci
25688c2ecf20Sopenharmony_ci/*
25698c2ecf20Sopenharmony_ci * Encode a GETACL request
25708c2ecf20Sopenharmony_ci */
25718c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
25728c2ecf20Sopenharmony_ci				const void *data)
25738c2ecf20Sopenharmony_ci{
25748c2ecf20Sopenharmony_ci	const struct nfs_getaclargs *args = data;
25758c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
25768c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
25778c2ecf20Sopenharmony_ci	};
25788c2ecf20Sopenharmony_ci	const __u32 nfs4_acl_bitmap[1] = {
25798c2ecf20Sopenharmony_ci		[0] = FATTR4_WORD0_ACL,
25808c2ecf20Sopenharmony_ci	};
25818c2ecf20Sopenharmony_ci	uint32_t replen;
25828c2ecf20Sopenharmony_ci
25838c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
25848c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
25858c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
25868c2ecf20Sopenharmony_ci	replen = hdr.replen + op_decode_hdr_maxsz;
25878c2ecf20Sopenharmony_ci	encode_getattr(xdr, nfs4_acl_bitmap, NULL,
25888c2ecf20Sopenharmony_ci			ARRAY_SIZE(nfs4_acl_bitmap), &hdr);
25898c2ecf20Sopenharmony_ci
25908c2ecf20Sopenharmony_ci	rpc_prepare_reply_pages(req, args->acl_pages, 0,
25918c2ecf20Sopenharmony_ci				args->acl_len, replen + 1);
25928c2ecf20Sopenharmony_ci	encode_nops(&hdr);
25938c2ecf20Sopenharmony_ci}
25948c2ecf20Sopenharmony_ci
25958c2ecf20Sopenharmony_ci/*
25968c2ecf20Sopenharmony_ci * Encode a WRITE request
25978c2ecf20Sopenharmony_ci */
25988c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr,
25998c2ecf20Sopenharmony_ci			       const void *data)
26008c2ecf20Sopenharmony_ci{
26018c2ecf20Sopenharmony_ci	const struct nfs_pgio_args *args = data;
26028c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
26038c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
26048c2ecf20Sopenharmony_ci	};
26058c2ecf20Sopenharmony_ci
26068c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
26078c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
26088c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
26098c2ecf20Sopenharmony_ci	encode_write(xdr, args, &hdr);
26108c2ecf20Sopenharmony_ci	req->rq_snd_buf.flags |= XDRBUF_WRITE;
26118c2ecf20Sopenharmony_ci	if (args->bitmask)
26128c2ecf20Sopenharmony_ci		encode_getfattr(xdr, args->bitmask, &hdr);
26138c2ecf20Sopenharmony_ci	encode_nops(&hdr);
26148c2ecf20Sopenharmony_ci}
26158c2ecf20Sopenharmony_ci
26168c2ecf20Sopenharmony_ci/*
26178c2ecf20Sopenharmony_ci *  a COMMIT request
26188c2ecf20Sopenharmony_ci */
26198c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr,
26208c2ecf20Sopenharmony_ci				const void *data)
26218c2ecf20Sopenharmony_ci{
26228c2ecf20Sopenharmony_ci	const struct nfs_commitargs *args = data;
26238c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
26248c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
26258c2ecf20Sopenharmony_ci	};
26268c2ecf20Sopenharmony_ci
26278c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
26288c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
26298c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
26308c2ecf20Sopenharmony_ci	encode_commit(xdr, args, &hdr);
26318c2ecf20Sopenharmony_ci	encode_nops(&hdr);
26328c2ecf20Sopenharmony_ci}
26338c2ecf20Sopenharmony_ci
26348c2ecf20Sopenharmony_ci/*
26358c2ecf20Sopenharmony_ci * FSINFO request
26368c2ecf20Sopenharmony_ci */
26378c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr,
26388c2ecf20Sopenharmony_ci				const void *data)
26398c2ecf20Sopenharmony_ci{
26408c2ecf20Sopenharmony_ci	const struct nfs4_fsinfo_arg *args = data;
26418c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
26428c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
26438c2ecf20Sopenharmony_ci	};
26448c2ecf20Sopenharmony_ci
26458c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
26468c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
26478c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
26488c2ecf20Sopenharmony_ci	encode_fsinfo(xdr, args->bitmask, &hdr);
26498c2ecf20Sopenharmony_ci	encode_nops(&hdr);
26508c2ecf20Sopenharmony_ci}
26518c2ecf20Sopenharmony_ci
26528c2ecf20Sopenharmony_ci/*
26538c2ecf20Sopenharmony_ci * a PATHCONF request
26548c2ecf20Sopenharmony_ci */
26558c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
26568c2ecf20Sopenharmony_ci				  const void *data)
26578c2ecf20Sopenharmony_ci{
26588c2ecf20Sopenharmony_ci	const struct nfs4_pathconf_arg *args = data;
26598c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
26608c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
26618c2ecf20Sopenharmony_ci	};
26628c2ecf20Sopenharmony_ci
26638c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
26648c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
26658c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
26668c2ecf20Sopenharmony_ci	encode_getattr(xdr, nfs4_pathconf_bitmap, args->bitmask,
26678c2ecf20Sopenharmony_ci			ARRAY_SIZE(nfs4_pathconf_bitmap), &hdr);
26688c2ecf20Sopenharmony_ci	encode_nops(&hdr);
26698c2ecf20Sopenharmony_ci}
26708c2ecf20Sopenharmony_ci
26718c2ecf20Sopenharmony_ci/*
26728c2ecf20Sopenharmony_ci * a STATFS request
26738c2ecf20Sopenharmony_ci */
26748c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
26758c2ecf20Sopenharmony_ci				const void *data)
26768c2ecf20Sopenharmony_ci{
26778c2ecf20Sopenharmony_ci	const struct nfs4_statfs_arg *args = data;
26788c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
26798c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
26808c2ecf20Sopenharmony_ci	};
26818c2ecf20Sopenharmony_ci
26828c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
26838c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
26848c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
26858c2ecf20Sopenharmony_ci	encode_getattr(xdr, nfs4_statfs_bitmap, args->bitmask,
26868c2ecf20Sopenharmony_ci			ARRAY_SIZE(nfs4_statfs_bitmap), &hdr);
26878c2ecf20Sopenharmony_ci	encode_nops(&hdr);
26888c2ecf20Sopenharmony_ci}
26898c2ecf20Sopenharmony_ci
26908c2ecf20Sopenharmony_ci/*
26918c2ecf20Sopenharmony_ci * GETATTR_BITMAP request
26928c2ecf20Sopenharmony_ci */
26938c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
26948c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
26958c2ecf20Sopenharmony_ci				     const void *data)
26968c2ecf20Sopenharmony_ci{
26978c2ecf20Sopenharmony_ci	const struct nfs4_server_caps_arg *args = data;
26988c2ecf20Sopenharmony_ci	const u32 *bitmask = args->bitmask;
26998c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
27008c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
27018c2ecf20Sopenharmony_ci	};
27028c2ecf20Sopenharmony_ci
27038c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
27048c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
27058c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fhandle, &hdr);
27068c2ecf20Sopenharmony_ci	encode_getattr(xdr, bitmask, NULL, 3, &hdr);
27078c2ecf20Sopenharmony_ci	encode_nops(&hdr);
27088c2ecf20Sopenharmony_ci}
27098c2ecf20Sopenharmony_ci
27108c2ecf20Sopenharmony_ci/*
27118c2ecf20Sopenharmony_ci * a RENEW request
27128c2ecf20Sopenharmony_ci */
27138c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr,
27148c2ecf20Sopenharmony_ci			       const void *data)
27158c2ecf20Sopenharmony_ci
27168c2ecf20Sopenharmony_ci{
27178c2ecf20Sopenharmony_ci	const struct nfs_client *clp = data;
27188c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
27198c2ecf20Sopenharmony_ci		.nops	= 0,
27208c2ecf20Sopenharmony_ci	};
27218c2ecf20Sopenharmony_ci
27228c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
27238c2ecf20Sopenharmony_ci	encode_renew(xdr, clp->cl_clientid, &hdr);
27248c2ecf20Sopenharmony_ci	encode_nops(&hdr);
27258c2ecf20Sopenharmony_ci}
27268c2ecf20Sopenharmony_ci
27278c2ecf20Sopenharmony_ci/*
27288c2ecf20Sopenharmony_ci * a SETCLIENTID request
27298c2ecf20Sopenharmony_ci */
27308c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_setclientid(struct rpc_rqst *req,
27318c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
27328c2ecf20Sopenharmony_ci				     const void *data)
27338c2ecf20Sopenharmony_ci{
27348c2ecf20Sopenharmony_ci	const struct nfs4_setclientid *sc = data;
27358c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
27368c2ecf20Sopenharmony_ci		.nops	= 0,
27378c2ecf20Sopenharmony_ci	};
27388c2ecf20Sopenharmony_ci
27398c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
27408c2ecf20Sopenharmony_ci	encode_setclientid(xdr, sc, &hdr);
27418c2ecf20Sopenharmony_ci	encode_nops(&hdr);
27428c2ecf20Sopenharmony_ci}
27438c2ecf20Sopenharmony_ci
27448c2ecf20Sopenharmony_ci/*
27458c2ecf20Sopenharmony_ci * a SETCLIENTID_CONFIRM request
27468c2ecf20Sopenharmony_ci */
27478c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req,
27488c2ecf20Sopenharmony_ci					     struct xdr_stream *xdr,
27498c2ecf20Sopenharmony_ci					     const void *data)
27508c2ecf20Sopenharmony_ci{
27518c2ecf20Sopenharmony_ci	const struct nfs4_setclientid_res *arg = data;
27528c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
27538c2ecf20Sopenharmony_ci		.nops	= 0,
27548c2ecf20Sopenharmony_ci	};
27558c2ecf20Sopenharmony_ci
27568c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
27578c2ecf20Sopenharmony_ci	encode_setclientid_confirm(xdr, arg, &hdr);
27588c2ecf20Sopenharmony_ci	encode_nops(&hdr);
27598c2ecf20Sopenharmony_ci}
27608c2ecf20Sopenharmony_ci
27618c2ecf20Sopenharmony_ci/*
27628c2ecf20Sopenharmony_ci * DELEGRETURN request
27638c2ecf20Sopenharmony_ci */
27648c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req,
27658c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
27668c2ecf20Sopenharmony_ci				     const void *data)
27678c2ecf20Sopenharmony_ci{
27688c2ecf20Sopenharmony_ci	const struct nfs4_delegreturnargs *args = data;
27698c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
27708c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
27718c2ecf20Sopenharmony_ci	};
27728c2ecf20Sopenharmony_ci
27738c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
27748c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
27758c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fhandle, &hdr);
27768c2ecf20Sopenharmony_ci	if (args->lr_args)
27778c2ecf20Sopenharmony_ci		encode_layoutreturn(xdr, args->lr_args, &hdr);
27788c2ecf20Sopenharmony_ci	if (args->bitmask)
27798c2ecf20Sopenharmony_ci		encode_getfattr(xdr, args->bitmask, &hdr);
27808c2ecf20Sopenharmony_ci	encode_delegreturn(xdr, args->stateid, &hdr);
27818c2ecf20Sopenharmony_ci	encode_nops(&hdr);
27828c2ecf20Sopenharmony_ci}
27838c2ecf20Sopenharmony_ci
27848c2ecf20Sopenharmony_ci/*
27858c2ecf20Sopenharmony_ci * Encode FS_LOCATIONS request
27868c2ecf20Sopenharmony_ci */
27878c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req,
27888c2ecf20Sopenharmony_ci				      struct xdr_stream *xdr,
27898c2ecf20Sopenharmony_ci				      const void *data)
27908c2ecf20Sopenharmony_ci{
27918c2ecf20Sopenharmony_ci	const struct nfs4_fs_locations_arg *args = data;
27928c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
27938c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
27948c2ecf20Sopenharmony_ci	};
27958c2ecf20Sopenharmony_ci	uint32_t replen;
27968c2ecf20Sopenharmony_ci
27978c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
27988c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
27998c2ecf20Sopenharmony_ci	if (args->migration) {
28008c2ecf20Sopenharmony_ci		encode_putfh(xdr, args->fh, &hdr);
28018c2ecf20Sopenharmony_ci		replen = hdr.replen;
28028c2ecf20Sopenharmony_ci		encode_fs_locations(xdr, args->bitmask, &hdr);
28038c2ecf20Sopenharmony_ci		if (args->renew)
28048c2ecf20Sopenharmony_ci			encode_renew(xdr, args->clientid, &hdr);
28058c2ecf20Sopenharmony_ci	} else {
28068c2ecf20Sopenharmony_ci		encode_putfh(xdr, args->dir_fh, &hdr);
28078c2ecf20Sopenharmony_ci		encode_lookup(xdr, args->name, &hdr);
28088c2ecf20Sopenharmony_ci		replen = hdr.replen;
28098c2ecf20Sopenharmony_ci		encode_fs_locations(xdr, args->bitmask, &hdr);
28108c2ecf20Sopenharmony_ci	}
28118c2ecf20Sopenharmony_ci
28128c2ecf20Sopenharmony_ci	rpc_prepare_reply_pages(req, (struct page **)&args->page, 0,
28138c2ecf20Sopenharmony_ci				PAGE_SIZE, replen + 1);
28148c2ecf20Sopenharmony_ci	encode_nops(&hdr);
28158c2ecf20Sopenharmony_ci}
28168c2ecf20Sopenharmony_ci
28178c2ecf20Sopenharmony_ci/*
28188c2ecf20Sopenharmony_ci * Encode SECINFO request
28198c2ecf20Sopenharmony_ci */
28208c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_secinfo(struct rpc_rqst *req,
28218c2ecf20Sopenharmony_ci				struct xdr_stream *xdr,
28228c2ecf20Sopenharmony_ci				const void *data)
28238c2ecf20Sopenharmony_ci{
28248c2ecf20Sopenharmony_ci	const struct nfs4_secinfo_arg *args = data;
28258c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
28268c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
28278c2ecf20Sopenharmony_ci	};
28288c2ecf20Sopenharmony_ci
28298c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
28308c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
28318c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->dir_fh, &hdr);
28328c2ecf20Sopenharmony_ci	encode_secinfo(xdr, args->name, &hdr);
28338c2ecf20Sopenharmony_ci	encode_nops(&hdr);
28348c2ecf20Sopenharmony_ci}
28358c2ecf20Sopenharmony_ci
28368c2ecf20Sopenharmony_ci/*
28378c2ecf20Sopenharmony_ci * Encode FSID_PRESENT request
28388c2ecf20Sopenharmony_ci */
28398c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_fsid_present(struct rpc_rqst *req,
28408c2ecf20Sopenharmony_ci				      struct xdr_stream *xdr,
28418c2ecf20Sopenharmony_ci				      const void *data)
28428c2ecf20Sopenharmony_ci{
28438c2ecf20Sopenharmony_ci	const struct nfs4_fsid_present_arg *args = data;
28448c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
28458c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
28468c2ecf20Sopenharmony_ci	};
28478c2ecf20Sopenharmony_ci
28488c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
28498c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
28508c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
28518c2ecf20Sopenharmony_ci	encode_getfh(xdr, &hdr);
28528c2ecf20Sopenharmony_ci	if (args->renew)
28538c2ecf20Sopenharmony_ci		encode_renew(xdr, args->clientid, &hdr);
28548c2ecf20Sopenharmony_ci	encode_nops(&hdr);
28558c2ecf20Sopenharmony_ci}
28568c2ecf20Sopenharmony_ci
28578c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
28588c2ecf20Sopenharmony_ci/*
28598c2ecf20Sopenharmony_ci * BIND_CONN_TO_SESSION request
28608c2ecf20Sopenharmony_ci */
28618c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req,
28628c2ecf20Sopenharmony_ci				struct xdr_stream *xdr,
28638c2ecf20Sopenharmony_ci				const void *data)
28648c2ecf20Sopenharmony_ci{
28658c2ecf20Sopenharmony_ci	const struct nfs41_bind_conn_to_session_args *args = data;
28668c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
28678c2ecf20Sopenharmony_ci		.minorversion = args->client->cl_mvops->minor_version,
28688c2ecf20Sopenharmony_ci	};
28698c2ecf20Sopenharmony_ci
28708c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
28718c2ecf20Sopenharmony_ci	encode_bind_conn_to_session(xdr, args, &hdr);
28728c2ecf20Sopenharmony_ci	encode_nops(&hdr);
28738c2ecf20Sopenharmony_ci}
28748c2ecf20Sopenharmony_ci
28758c2ecf20Sopenharmony_ci/*
28768c2ecf20Sopenharmony_ci * EXCHANGE_ID request
28778c2ecf20Sopenharmony_ci */
28788c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req,
28798c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
28808c2ecf20Sopenharmony_ci				     const void *data)
28818c2ecf20Sopenharmony_ci{
28828c2ecf20Sopenharmony_ci	const struct nfs41_exchange_id_args *args = data;
28838c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
28848c2ecf20Sopenharmony_ci		.minorversion = args->client->cl_mvops->minor_version,
28858c2ecf20Sopenharmony_ci	};
28868c2ecf20Sopenharmony_ci
28878c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
28888c2ecf20Sopenharmony_ci	encode_exchange_id(xdr, args, &hdr);
28898c2ecf20Sopenharmony_ci	encode_nops(&hdr);
28908c2ecf20Sopenharmony_ci}
28918c2ecf20Sopenharmony_ci
28928c2ecf20Sopenharmony_ci/*
28938c2ecf20Sopenharmony_ci * a CREATE_SESSION request
28948c2ecf20Sopenharmony_ci */
28958c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_create_session(struct rpc_rqst *req,
28968c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
28978c2ecf20Sopenharmony_ci					const void *data)
28988c2ecf20Sopenharmony_ci{
28998c2ecf20Sopenharmony_ci	const struct nfs41_create_session_args *args = data;
29008c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
29018c2ecf20Sopenharmony_ci		.minorversion = args->client->cl_mvops->minor_version,
29028c2ecf20Sopenharmony_ci	};
29038c2ecf20Sopenharmony_ci
29048c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
29058c2ecf20Sopenharmony_ci	encode_create_session(xdr, args, &hdr);
29068c2ecf20Sopenharmony_ci	encode_nops(&hdr);
29078c2ecf20Sopenharmony_ci}
29088c2ecf20Sopenharmony_ci
29098c2ecf20Sopenharmony_ci/*
29108c2ecf20Sopenharmony_ci * a DESTROY_SESSION request
29118c2ecf20Sopenharmony_ci */
29128c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req,
29138c2ecf20Sopenharmony_ci					 struct xdr_stream *xdr,
29148c2ecf20Sopenharmony_ci					 const void *data)
29158c2ecf20Sopenharmony_ci{
29168c2ecf20Sopenharmony_ci	const struct nfs4_session *session = data;
29178c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
29188c2ecf20Sopenharmony_ci		.minorversion = session->clp->cl_mvops->minor_version,
29198c2ecf20Sopenharmony_ci	};
29208c2ecf20Sopenharmony_ci
29218c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
29228c2ecf20Sopenharmony_ci	encode_destroy_session(xdr, session, &hdr);
29238c2ecf20Sopenharmony_ci	encode_nops(&hdr);
29248c2ecf20Sopenharmony_ci}
29258c2ecf20Sopenharmony_ci
29268c2ecf20Sopenharmony_ci/*
29278c2ecf20Sopenharmony_ci * a DESTROY_CLIENTID request
29288c2ecf20Sopenharmony_ci */
29298c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_destroy_clientid(struct rpc_rqst *req,
29308c2ecf20Sopenharmony_ci					 struct xdr_stream *xdr,
29318c2ecf20Sopenharmony_ci					 const void *data)
29328c2ecf20Sopenharmony_ci{
29338c2ecf20Sopenharmony_ci	const struct nfs_client *clp = data;
29348c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
29358c2ecf20Sopenharmony_ci		.minorversion = clp->cl_mvops->minor_version,
29368c2ecf20Sopenharmony_ci	};
29378c2ecf20Sopenharmony_ci
29388c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
29398c2ecf20Sopenharmony_ci	encode_destroy_clientid(xdr, clp->cl_clientid, &hdr);
29408c2ecf20Sopenharmony_ci	encode_nops(&hdr);
29418c2ecf20Sopenharmony_ci}
29428c2ecf20Sopenharmony_ci
29438c2ecf20Sopenharmony_ci/*
29448c2ecf20Sopenharmony_ci * a SEQUENCE request
29458c2ecf20Sopenharmony_ci */
29468c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr,
29478c2ecf20Sopenharmony_ci				  const void *data)
29488c2ecf20Sopenharmony_ci{
29498c2ecf20Sopenharmony_ci	const struct nfs4_sequence_args *args = data;
29508c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
29518c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(args),
29528c2ecf20Sopenharmony_ci	};
29538c2ecf20Sopenharmony_ci
29548c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
29558c2ecf20Sopenharmony_ci	encode_sequence(xdr, args, &hdr);
29568c2ecf20Sopenharmony_ci	encode_nops(&hdr);
29578c2ecf20Sopenharmony_ci}
29588c2ecf20Sopenharmony_ci
29598c2ecf20Sopenharmony_ci#endif
29608c2ecf20Sopenharmony_ci
29618c2ecf20Sopenharmony_ci/*
29628c2ecf20Sopenharmony_ci * a GET_LEASE_TIME request
29638c2ecf20Sopenharmony_ci */
29648c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req,
29658c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
29668c2ecf20Sopenharmony_ci					const void *data)
29678c2ecf20Sopenharmony_ci{
29688c2ecf20Sopenharmony_ci	const struct nfs4_get_lease_time_args *args = data;
29698c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
29708c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->la_seq_args),
29718c2ecf20Sopenharmony_ci	};
29728c2ecf20Sopenharmony_ci	const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
29738c2ecf20Sopenharmony_ci
29748c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
29758c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->la_seq_args, &hdr);
29768c2ecf20Sopenharmony_ci	encode_putrootfh(xdr, &hdr);
29778c2ecf20Sopenharmony_ci	encode_fsinfo(xdr, lease_bitmap, &hdr);
29788c2ecf20Sopenharmony_ci	encode_nops(&hdr);
29798c2ecf20Sopenharmony_ci}
29808c2ecf20Sopenharmony_ci
29818c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_1
29828c2ecf20Sopenharmony_ci
29838c2ecf20Sopenharmony_ci/*
29848c2ecf20Sopenharmony_ci * a RECLAIM_COMPLETE request
29858c2ecf20Sopenharmony_ci */
29868c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req,
29878c2ecf20Sopenharmony_ci					  struct xdr_stream *xdr,
29888c2ecf20Sopenharmony_ci					  const void *data)
29898c2ecf20Sopenharmony_ci{
29908c2ecf20Sopenharmony_ci	const struct nfs41_reclaim_complete_args *args = data;
29918c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
29928c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args)
29938c2ecf20Sopenharmony_ci	};
29948c2ecf20Sopenharmony_ci
29958c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
29968c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
29978c2ecf20Sopenharmony_ci	encode_reclaim_complete(xdr, args, &hdr);
29988c2ecf20Sopenharmony_ci	encode_nops(&hdr);
29998c2ecf20Sopenharmony_ci}
30008c2ecf20Sopenharmony_ci
30018c2ecf20Sopenharmony_ci/*
30028c2ecf20Sopenharmony_ci * Encode GETDEVICEINFO request
30038c2ecf20Sopenharmony_ci */
30048c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req,
30058c2ecf20Sopenharmony_ci				       struct xdr_stream *xdr,
30068c2ecf20Sopenharmony_ci				       const void *data)
30078c2ecf20Sopenharmony_ci{
30088c2ecf20Sopenharmony_ci	const struct nfs4_getdeviceinfo_args *args = data;
30098c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
30108c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
30118c2ecf20Sopenharmony_ci	};
30128c2ecf20Sopenharmony_ci	uint32_t replen;
30138c2ecf20Sopenharmony_ci
30148c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
30158c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
30168c2ecf20Sopenharmony_ci
30178c2ecf20Sopenharmony_ci	replen = hdr.replen + op_decode_hdr_maxsz;
30188c2ecf20Sopenharmony_ci
30198c2ecf20Sopenharmony_ci	encode_getdeviceinfo(xdr, args, &hdr);
30208c2ecf20Sopenharmony_ci
30218c2ecf20Sopenharmony_ci	/* set up reply kvec. device_addr4 opaque data is read into the
30228c2ecf20Sopenharmony_ci	 * pages */
30238c2ecf20Sopenharmony_ci	rpc_prepare_reply_pages(req, args->pdev->pages, args->pdev->pgbase,
30248c2ecf20Sopenharmony_ci				args->pdev->pglen, replen + 2 + 1);
30258c2ecf20Sopenharmony_ci	encode_nops(&hdr);
30268c2ecf20Sopenharmony_ci}
30278c2ecf20Sopenharmony_ci
30288c2ecf20Sopenharmony_ci/*
30298c2ecf20Sopenharmony_ci *  Encode LAYOUTGET request
30308c2ecf20Sopenharmony_ci */
30318c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
30328c2ecf20Sopenharmony_ci				   struct xdr_stream *xdr,
30338c2ecf20Sopenharmony_ci				   const void *data)
30348c2ecf20Sopenharmony_ci{
30358c2ecf20Sopenharmony_ci	const struct nfs4_layoutget_args *args = data;
30368c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
30378c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
30388c2ecf20Sopenharmony_ci	};
30398c2ecf20Sopenharmony_ci
30408c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
30418c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
30428c2ecf20Sopenharmony_ci	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
30438c2ecf20Sopenharmony_ci	encode_layoutget(xdr, args, &hdr);
30448c2ecf20Sopenharmony_ci
30458c2ecf20Sopenharmony_ci	rpc_prepare_reply_pages(req, args->layout.pages, 0,
30468c2ecf20Sopenharmony_ci				args->layout.pglen, hdr.replen);
30478c2ecf20Sopenharmony_ci	encode_nops(&hdr);
30488c2ecf20Sopenharmony_ci}
30498c2ecf20Sopenharmony_ci
30508c2ecf20Sopenharmony_ci/*
30518c2ecf20Sopenharmony_ci *  Encode LAYOUTCOMMIT request
30528c2ecf20Sopenharmony_ci */
30538c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
30548c2ecf20Sopenharmony_ci				      struct xdr_stream *xdr,
30558c2ecf20Sopenharmony_ci				      const void *priv)
30568c2ecf20Sopenharmony_ci{
30578c2ecf20Sopenharmony_ci	const struct nfs4_layoutcommit_args *args = priv;
30588c2ecf20Sopenharmony_ci	struct nfs4_layoutcommit_data *data =
30598c2ecf20Sopenharmony_ci		container_of(args, struct nfs4_layoutcommit_data, args);
30608c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
30618c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
30628c2ecf20Sopenharmony_ci	};
30638c2ecf20Sopenharmony_ci
30648c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
30658c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
30668c2ecf20Sopenharmony_ci	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
30678c2ecf20Sopenharmony_ci	encode_layoutcommit(xdr, data->args.inode, args, &hdr);
30688c2ecf20Sopenharmony_ci	encode_getfattr(xdr, args->bitmask, &hdr);
30698c2ecf20Sopenharmony_ci	encode_nops(&hdr);
30708c2ecf20Sopenharmony_ci}
30718c2ecf20Sopenharmony_ci
30728c2ecf20Sopenharmony_ci/*
30738c2ecf20Sopenharmony_ci * Encode LAYOUTRETURN request
30748c2ecf20Sopenharmony_ci */
30758c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req,
30768c2ecf20Sopenharmony_ci				      struct xdr_stream *xdr,
30778c2ecf20Sopenharmony_ci				      const void *data)
30788c2ecf20Sopenharmony_ci{
30798c2ecf20Sopenharmony_ci	const struct nfs4_layoutreturn_args *args = data;
30808c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
30818c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
30828c2ecf20Sopenharmony_ci	};
30838c2ecf20Sopenharmony_ci
30848c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
30858c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
30868c2ecf20Sopenharmony_ci	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
30878c2ecf20Sopenharmony_ci	encode_layoutreturn(xdr, args, &hdr);
30888c2ecf20Sopenharmony_ci	encode_nops(&hdr);
30898c2ecf20Sopenharmony_ci}
30908c2ecf20Sopenharmony_ci
30918c2ecf20Sopenharmony_ci/*
30928c2ecf20Sopenharmony_ci * Encode SECINFO_NO_NAME request
30938c2ecf20Sopenharmony_ci */
30948c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req,
30958c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
30968c2ecf20Sopenharmony_ci					const void *data)
30978c2ecf20Sopenharmony_ci{
30988c2ecf20Sopenharmony_ci	const struct nfs41_secinfo_no_name_args *args = data;
30998c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
31008c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
31018c2ecf20Sopenharmony_ci	};
31028c2ecf20Sopenharmony_ci
31038c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
31048c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
31058c2ecf20Sopenharmony_ci	encode_putrootfh(xdr, &hdr);
31068c2ecf20Sopenharmony_ci	encode_secinfo_no_name(xdr, args, &hdr);
31078c2ecf20Sopenharmony_ci	encode_nops(&hdr);
31088c2ecf20Sopenharmony_ci}
31098c2ecf20Sopenharmony_ci
31108c2ecf20Sopenharmony_ci/*
31118c2ecf20Sopenharmony_ci *  Encode TEST_STATEID request
31128c2ecf20Sopenharmony_ci */
31138c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req,
31148c2ecf20Sopenharmony_ci				      struct xdr_stream *xdr,
31158c2ecf20Sopenharmony_ci				      const void *data)
31168c2ecf20Sopenharmony_ci{
31178c2ecf20Sopenharmony_ci	const struct nfs41_test_stateid_args *args = data;
31188c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
31198c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
31208c2ecf20Sopenharmony_ci	};
31218c2ecf20Sopenharmony_ci
31228c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
31238c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
31248c2ecf20Sopenharmony_ci	encode_test_stateid(xdr, args, &hdr);
31258c2ecf20Sopenharmony_ci	encode_nops(&hdr);
31268c2ecf20Sopenharmony_ci}
31278c2ecf20Sopenharmony_ci
31288c2ecf20Sopenharmony_ci/*
31298c2ecf20Sopenharmony_ci *  Encode FREE_STATEID request
31308c2ecf20Sopenharmony_ci */
31318c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req,
31328c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
31338c2ecf20Sopenharmony_ci				     const void *data)
31348c2ecf20Sopenharmony_ci{
31358c2ecf20Sopenharmony_ci	const struct nfs41_free_stateid_args *args = data;
31368c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
31378c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
31388c2ecf20Sopenharmony_ci	};
31398c2ecf20Sopenharmony_ci
31408c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
31418c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
31428c2ecf20Sopenharmony_ci	encode_free_stateid(xdr, args, &hdr);
31438c2ecf20Sopenharmony_ci	encode_nops(&hdr);
31448c2ecf20Sopenharmony_ci}
31458c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
31468c2ecf20Sopenharmony_ci
31478c2ecf20Sopenharmony_cistatic int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string)
31488c2ecf20Sopenharmony_ci{
31498c2ecf20Sopenharmony_ci	ssize_t ret = xdr_stream_decode_opaque_inline(xdr, (void **)string,
31508c2ecf20Sopenharmony_ci			NFS4_OPAQUE_LIMIT);
31518c2ecf20Sopenharmony_ci	if (unlikely(ret < 0))
31528c2ecf20Sopenharmony_ci		return -EIO;
31538c2ecf20Sopenharmony_ci	*len = ret;
31548c2ecf20Sopenharmony_ci	return 0;
31558c2ecf20Sopenharmony_ci}
31568c2ecf20Sopenharmony_ci
31578c2ecf20Sopenharmony_cistatic int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
31588c2ecf20Sopenharmony_ci{
31598c2ecf20Sopenharmony_ci	__be32 *p;
31608c2ecf20Sopenharmony_ci
31618c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
31628c2ecf20Sopenharmony_ci	if (unlikely(!p))
31638c2ecf20Sopenharmony_ci		return -EIO;
31648c2ecf20Sopenharmony_ci	hdr->status = be32_to_cpup(p++);
31658c2ecf20Sopenharmony_ci	hdr->taglen = be32_to_cpup(p);
31668c2ecf20Sopenharmony_ci
31678c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, hdr->taglen + 4);
31688c2ecf20Sopenharmony_ci	if (unlikely(!p))
31698c2ecf20Sopenharmony_ci		return -EIO;
31708c2ecf20Sopenharmony_ci	hdr->tag = (char *)p;
31718c2ecf20Sopenharmony_ci	p += XDR_QUADLEN(hdr->taglen);
31728c2ecf20Sopenharmony_ci	hdr->nops = be32_to_cpup(p);
31738c2ecf20Sopenharmony_ci	if (unlikely(hdr->nops < 1))
31748c2ecf20Sopenharmony_ci		return nfs4_stat_to_errno(hdr->status);
31758c2ecf20Sopenharmony_ci	return 0;
31768c2ecf20Sopenharmony_ci}
31778c2ecf20Sopenharmony_ci
31788c2ecf20Sopenharmony_cistatic bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected,
31798c2ecf20Sopenharmony_ci		int *nfs_retval)
31808c2ecf20Sopenharmony_ci{
31818c2ecf20Sopenharmony_ci	__be32 *p;
31828c2ecf20Sopenharmony_ci	uint32_t opnum;
31838c2ecf20Sopenharmony_ci	int32_t nfserr;
31848c2ecf20Sopenharmony_ci
31858c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
31868c2ecf20Sopenharmony_ci	if (unlikely(!p))
31878c2ecf20Sopenharmony_ci		goto out_overflow;
31888c2ecf20Sopenharmony_ci	opnum = be32_to_cpup(p++);
31898c2ecf20Sopenharmony_ci	if (unlikely(opnum != expected))
31908c2ecf20Sopenharmony_ci		goto out_bad_operation;
31918c2ecf20Sopenharmony_ci	if (unlikely(*p != cpu_to_be32(NFS_OK)))
31928c2ecf20Sopenharmony_ci		goto out_status;
31938c2ecf20Sopenharmony_ci	*nfs_retval = 0;
31948c2ecf20Sopenharmony_ci	return true;
31958c2ecf20Sopenharmony_ciout_status:
31968c2ecf20Sopenharmony_ci	nfserr = be32_to_cpup(p);
31978c2ecf20Sopenharmony_ci	trace_nfs4_xdr_status(xdr, opnum, nfserr);
31988c2ecf20Sopenharmony_ci	*nfs_retval = nfs4_stat_to_errno(nfserr);
31998c2ecf20Sopenharmony_ci	return true;
32008c2ecf20Sopenharmony_ciout_bad_operation:
32018c2ecf20Sopenharmony_ci	dprintk("nfs: Server returned operation"
32028c2ecf20Sopenharmony_ci		" %d but we issued a request for %d\n",
32038c2ecf20Sopenharmony_ci			opnum, expected);
32048c2ecf20Sopenharmony_ci	*nfs_retval = -EREMOTEIO;
32058c2ecf20Sopenharmony_ci	return false;
32068c2ecf20Sopenharmony_ciout_overflow:
32078c2ecf20Sopenharmony_ci	*nfs_retval = -EIO;
32088c2ecf20Sopenharmony_ci	return false;
32098c2ecf20Sopenharmony_ci}
32108c2ecf20Sopenharmony_ci
32118c2ecf20Sopenharmony_cistatic int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
32128c2ecf20Sopenharmony_ci{
32138c2ecf20Sopenharmony_ci	int retval;
32148c2ecf20Sopenharmony_ci
32158c2ecf20Sopenharmony_ci	__decode_op_hdr(xdr, expected, &retval);
32168c2ecf20Sopenharmony_ci	return retval;
32178c2ecf20Sopenharmony_ci}
32188c2ecf20Sopenharmony_ci
32198c2ecf20Sopenharmony_ci/* Dummy routine */
32208c2ecf20Sopenharmony_cistatic int decode_ace(struct xdr_stream *xdr, void *ace)
32218c2ecf20Sopenharmony_ci{
32228c2ecf20Sopenharmony_ci	__be32 *p;
32238c2ecf20Sopenharmony_ci	unsigned int strlen;
32248c2ecf20Sopenharmony_ci	char *str;
32258c2ecf20Sopenharmony_ci
32268c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 12);
32278c2ecf20Sopenharmony_ci	if (unlikely(!p))
32288c2ecf20Sopenharmony_ci		return -EIO;
32298c2ecf20Sopenharmony_ci	return decode_opaque_inline(xdr, &strlen, &str);
32308c2ecf20Sopenharmony_ci}
32318c2ecf20Sopenharmony_ci
32328c2ecf20Sopenharmony_cistatic ssize_t
32338c2ecf20Sopenharmony_cidecode_bitmap4(struct xdr_stream *xdr, uint32_t *bitmap, size_t sz)
32348c2ecf20Sopenharmony_ci{
32358c2ecf20Sopenharmony_ci	ssize_t ret;
32368c2ecf20Sopenharmony_ci
32378c2ecf20Sopenharmony_ci	ret = xdr_stream_decode_uint32_array(xdr, bitmap, sz);
32388c2ecf20Sopenharmony_ci	if (likely(ret >= 0))
32398c2ecf20Sopenharmony_ci		return ret;
32408c2ecf20Sopenharmony_ci	if (ret != -EMSGSIZE)
32418c2ecf20Sopenharmony_ci		return -EIO;
32428c2ecf20Sopenharmony_ci	return sz;
32438c2ecf20Sopenharmony_ci}
32448c2ecf20Sopenharmony_ci
32458c2ecf20Sopenharmony_cistatic int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
32468c2ecf20Sopenharmony_ci{
32478c2ecf20Sopenharmony_ci	ssize_t ret;
32488c2ecf20Sopenharmony_ci	ret = decode_bitmap4(xdr, bitmap, 3);
32498c2ecf20Sopenharmony_ci	return ret < 0 ? ret : 0;
32508c2ecf20Sopenharmony_ci}
32518c2ecf20Sopenharmony_ci
32528c2ecf20Sopenharmony_cistatic int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, unsigned int *savep)
32538c2ecf20Sopenharmony_ci{
32548c2ecf20Sopenharmony_ci	__be32 *p;
32558c2ecf20Sopenharmony_ci
32568c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
32578c2ecf20Sopenharmony_ci	if (unlikely(!p))
32588c2ecf20Sopenharmony_ci		return -EIO;
32598c2ecf20Sopenharmony_ci	*attrlen = be32_to_cpup(p);
32608c2ecf20Sopenharmony_ci	*savep = xdr_stream_pos(xdr);
32618c2ecf20Sopenharmony_ci	return 0;
32628c2ecf20Sopenharmony_ci}
32638c2ecf20Sopenharmony_ci
32648c2ecf20Sopenharmony_cistatic int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask)
32658c2ecf20Sopenharmony_ci{
32668c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) {
32678c2ecf20Sopenharmony_ci		int ret;
32688c2ecf20Sopenharmony_ci		ret = decode_attr_bitmap(xdr, bitmask);
32698c2ecf20Sopenharmony_ci		if (unlikely(ret < 0))
32708c2ecf20Sopenharmony_ci			return ret;
32718c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS;
32728c2ecf20Sopenharmony_ci	} else
32738c2ecf20Sopenharmony_ci		bitmask[0] = bitmask[1] = bitmask[2] = 0;
32748c2ecf20Sopenharmony_ci	dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__,
32758c2ecf20Sopenharmony_ci		bitmask[0], bitmask[1], bitmask[2]);
32768c2ecf20Sopenharmony_ci	return 0;
32778c2ecf20Sopenharmony_ci}
32788c2ecf20Sopenharmony_ci
32798c2ecf20Sopenharmony_cistatic int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type)
32808c2ecf20Sopenharmony_ci{
32818c2ecf20Sopenharmony_ci	__be32 *p;
32828c2ecf20Sopenharmony_ci	int ret = 0;
32838c2ecf20Sopenharmony_ci
32848c2ecf20Sopenharmony_ci	*type = 0;
32858c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U)))
32868c2ecf20Sopenharmony_ci		return -EIO;
32878c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) {
32888c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
32898c2ecf20Sopenharmony_ci		if (unlikely(!p))
32908c2ecf20Sopenharmony_ci			return -EIO;
32918c2ecf20Sopenharmony_ci		*type = be32_to_cpup(p);
32928c2ecf20Sopenharmony_ci		if (*type < NF4REG || *type > NF4NAMEDATTR) {
32938c2ecf20Sopenharmony_ci			dprintk("%s: bad type %d\n", __func__, *type);
32948c2ecf20Sopenharmony_ci			return -EIO;
32958c2ecf20Sopenharmony_ci		}
32968c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_TYPE;
32978c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_TYPE;
32988c2ecf20Sopenharmony_ci	}
32998c2ecf20Sopenharmony_ci	dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]);
33008c2ecf20Sopenharmony_ci	return ret;
33018c2ecf20Sopenharmony_ci}
33028c2ecf20Sopenharmony_ci
33038c2ecf20Sopenharmony_cistatic int decode_attr_fh_expire_type(struct xdr_stream *xdr,
33048c2ecf20Sopenharmony_ci				      uint32_t *bitmap, uint32_t *type)
33058c2ecf20Sopenharmony_ci{
33068c2ecf20Sopenharmony_ci	__be32 *p;
33078c2ecf20Sopenharmony_ci
33088c2ecf20Sopenharmony_ci	*type = 0;
33098c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FH_EXPIRE_TYPE - 1U)))
33108c2ecf20Sopenharmony_ci		return -EIO;
33118c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_FH_EXPIRE_TYPE)) {
33128c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
33138c2ecf20Sopenharmony_ci		if (unlikely(!p))
33148c2ecf20Sopenharmony_ci			return -EIO;
33158c2ecf20Sopenharmony_ci		*type = be32_to_cpup(p);
33168c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_FH_EXPIRE_TYPE;
33178c2ecf20Sopenharmony_ci	}
33188c2ecf20Sopenharmony_ci	dprintk("%s: expire type=0x%x\n", __func__, *type);
33198c2ecf20Sopenharmony_ci	return 0;
33208c2ecf20Sopenharmony_ci}
33218c2ecf20Sopenharmony_ci
33228c2ecf20Sopenharmony_cistatic int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change)
33238c2ecf20Sopenharmony_ci{
33248c2ecf20Sopenharmony_ci	__be32 *p;
33258c2ecf20Sopenharmony_ci	int ret = 0;
33268c2ecf20Sopenharmony_ci
33278c2ecf20Sopenharmony_ci	*change = 0;
33288c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U)))
33298c2ecf20Sopenharmony_ci		return -EIO;
33308c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) {
33318c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
33328c2ecf20Sopenharmony_ci		if (unlikely(!p))
33338c2ecf20Sopenharmony_ci			return -EIO;
33348c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, change);
33358c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_CHANGE;
33368c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_CHANGE;
33378c2ecf20Sopenharmony_ci	}
33388c2ecf20Sopenharmony_ci	dprintk("%s: change attribute=%Lu\n", __func__,
33398c2ecf20Sopenharmony_ci			(unsigned long long)*change);
33408c2ecf20Sopenharmony_ci	return ret;
33418c2ecf20Sopenharmony_ci}
33428c2ecf20Sopenharmony_ci
33438c2ecf20Sopenharmony_cistatic int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size)
33448c2ecf20Sopenharmony_ci{
33458c2ecf20Sopenharmony_ci	__be32 *p;
33468c2ecf20Sopenharmony_ci	int ret = 0;
33478c2ecf20Sopenharmony_ci
33488c2ecf20Sopenharmony_ci	*size = 0;
33498c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U)))
33508c2ecf20Sopenharmony_ci		return -EIO;
33518c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) {
33528c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
33538c2ecf20Sopenharmony_ci		if (unlikely(!p))
33548c2ecf20Sopenharmony_ci			return -EIO;
33558c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, size);
33568c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_SIZE;
33578c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_SIZE;
33588c2ecf20Sopenharmony_ci	}
33598c2ecf20Sopenharmony_ci	dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size);
33608c2ecf20Sopenharmony_ci	return ret;
33618c2ecf20Sopenharmony_ci}
33628c2ecf20Sopenharmony_ci
33638c2ecf20Sopenharmony_cistatic int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
33648c2ecf20Sopenharmony_ci{
33658c2ecf20Sopenharmony_ci	__be32 *p;
33668c2ecf20Sopenharmony_ci
33678c2ecf20Sopenharmony_ci	*res = 0;
33688c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U)))
33698c2ecf20Sopenharmony_ci		return -EIO;
33708c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) {
33718c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
33728c2ecf20Sopenharmony_ci		if (unlikely(!p))
33738c2ecf20Sopenharmony_ci			return -EIO;
33748c2ecf20Sopenharmony_ci		*res = be32_to_cpup(p);
33758c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT;
33768c2ecf20Sopenharmony_ci	}
33778c2ecf20Sopenharmony_ci	dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true");
33788c2ecf20Sopenharmony_ci	return 0;
33798c2ecf20Sopenharmony_ci}
33808c2ecf20Sopenharmony_ci
33818c2ecf20Sopenharmony_cistatic int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
33828c2ecf20Sopenharmony_ci{
33838c2ecf20Sopenharmony_ci	__be32 *p;
33848c2ecf20Sopenharmony_ci
33858c2ecf20Sopenharmony_ci	*res = 0;
33868c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U)))
33878c2ecf20Sopenharmony_ci		return -EIO;
33888c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) {
33898c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
33908c2ecf20Sopenharmony_ci		if (unlikely(!p))
33918c2ecf20Sopenharmony_ci			return -EIO;
33928c2ecf20Sopenharmony_ci		*res = be32_to_cpup(p);
33938c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT;
33948c2ecf20Sopenharmony_ci	}
33958c2ecf20Sopenharmony_ci	dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true");
33968c2ecf20Sopenharmony_ci	return 0;
33978c2ecf20Sopenharmony_ci}
33988c2ecf20Sopenharmony_ci
33998c2ecf20Sopenharmony_cistatic int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
34008c2ecf20Sopenharmony_ci{
34018c2ecf20Sopenharmony_ci	__be32 *p;
34028c2ecf20Sopenharmony_ci	int ret = 0;
34038c2ecf20Sopenharmony_ci
34048c2ecf20Sopenharmony_ci	fsid->major = 0;
34058c2ecf20Sopenharmony_ci	fsid->minor = 0;
34068c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U)))
34078c2ecf20Sopenharmony_ci		return -EIO;
34088c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_FSID)) {
34098c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 16);
34108c2ecf20Sopenharmony_ci		if (unlikely(!p))
34118c2ecf20Sopenharmony_ci			return -EIO;
34128c2ecf20Sopenharmony_ci		p = xdr_decode_hyper(p, &fsid->major);
34138c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, &fsid->minor);
34148c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_FSID;
34158c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_FSID;
34168c2ecf20Sopenharmony_ci	}
34178c2ecf20Sopenharmony_ci	dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __func__,
34188c2ecf20Sopenharmony_ci			(unsigned long long)fsid->major,
34198c2ecf20Sopenharmony_ci			(unsigned long long)fsid->minor);
34208c2ecf20Sopenharmony_ci	return ret;
34218c2ecf20Sopenharmony_ci}
34228c2ecf20Sopenharmony_ci
34238c2ecf20Sopenharmony_cistatic int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
34248c2ecf20Sopenharmony_ci{
34258c2ecf20Sopenharmony_ci	__be32 *p;
34268c2ecf20Sopenharmony_ci
34278c2ecf20Sopenharmony_ci	*res = 60;
34288c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U)))
34298c2ecf20Sopenharmony_ci		return -EIO;
34308c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) {
34318c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
34328c2ecf20Sopenharmony_ci		if (unlikely(!p))
34338c2ecf20Sopenharmony_ci			return -EIO;
34348c2ecf20Sopenharmony_ci		*res = be32_to_cpup(p);
34358c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME;
34368c2ecf20Sopenharmony_ci	}
34378c2ecf20Sopenharmony_ci	dprintk("%s: lease time=%u\n", __func__, (unsigned int)*res);
34388c2ecf20Sopenharmony_ci	return 0;
34398c2ecf20Sopenharmony_ci}
34408c2ecf20Sopenharmony_ci
34418c2ecf20Sopenharmony_cistatic int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res)
34428c2ecf20Sopenharmony_ci{
34438c2ecf20Sopenharmony_ci	__be32 *p;
34448c2ecf20Sopenharmony_ci
34458c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_RDATTR_ERROR - 1U)))
34468c2ecf20Sopenharmony_ci		return -EIO;
34478c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) {
34488c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
34498c2ecf20Sopenharmony_ci		if (unlikely(!p))
34508c2ecf20Sopenharmony_ci			return -EIO;
34518c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
34528c2ecf20Sopenharmony_ci		*res = -be32_to_cpup(p);
34538c2ecf20Sopenharmony_ci	}
34548c2ecf20Sopenharmony_ci	return 0;
34558c2ecf20Sopenharmony_ci}
34568c2ecf20Sopenharmony_ci
34578c2ecf20Sopenharmony_cistatic int decode_attr_exclcreat_supported(struct xdr_stream *xdr,
34588c2ecf20Sopenharmony_ci				 uint32_t *bitmap, uint32_t *bitmask)
34598c2ecf20Sopenharmony_ci{
34608c2ecf20Sopenharmony_ci	if (likely(bitmap[2] & FATTR4_WORD2_SUPPATTR_EXCLCREAT)) {
34618c2ecf20Sopenharmony_ci		int ret;
34628c2ecf20Sopenharmony_ci		ret = decode_attr_bitmap(xdr, bitmask);
34638c2ecf20Sopenharmony_ci		if (unlikely(ret < 0))
34648c2ecf20Sopenharmony_ci			return ret;
34658c2ecf20Sopenharmony_ci		bitmap[2] &= ~FATTR4_WORD2_SUPPATTR_EXCLCREAT;
34668c2ecf20Sopenharmony_ci	} else
34678c2ecf20Sopenharmony_ci		bitmask[0] = bitmask[1] = bitmask[2] = 0;
34688c2ecf20Sopenharmony_ci	dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__,
34698c2ecf20Sopenharmony_ci		bitmask[0], bitmask[1], bitmask[2]);
34708c2ecf20Sopenharmony_ci	return 0;
34718c2ecf20Sopenharmony_ci}
34728c2ecf20Sopenharmony_ci
34738c2ecf20Sopenharmony_cistatic int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fh *fh)
34748c2ecf20Sopenharmony_ci{
34758c2ecf20Sopenharmony_ci	__be32 *p;
34768c2ecf20Sopenharmony_ci	u32 len;
34778c2ecf20Sopenharmony_ci
34788c2ecf20Sopenharmony_ci	if (fh != NULL)
34798c2ecf20Sopenharmony_ci		memset(fh, 0, sizeof(*fh));
34808c2ecf20Sopenharmony_ci
34818c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEHANDLE - 1U)))
34828c2ecf20Sopenharmony_ci		return -EIO;
34838c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) {
34848c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
34858c2ecf20Sopenharmony_ci		if (unlikely(!p))
34868c2ecf20Sopenharmony_ci			return -EIO;
34878c2ecf20Sopenharmony_ci		len = be32_to_cpup(p);
34888c2ecf20Sopenharmony_ci		if (len > NFS4_FHSIZE)
34898c2ecf20Sopenharmony_ci			return -EIO;
34908c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, len);
34918c2ecf20Sopenharmony_ci		if (unlikely(!p))
34928c2ecf20Sopenharmony_ci			return -EIO;
34938c2ecf20Sopenharmony_ci		if (fh != NULL) {
34948c2ecf20Sopenharmony_ci			memcpy(fh->data, p, len);
34958c2ecf20Sopenharmony_ci			fh->size = len;
34968c2ecf20Sopenharmony_ci		}
34978c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE;
34988c2ecf20Sopenharmony_ci	}
34998c2ecf20Sopenharmony_ci	return 0;
35008c2ecf20Sopenharmony_ci}
35018c2ecf20Sopenharmony_ci
35028c2ecf20Sopenharmony_cistatic int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
35038c2ecf20Sopenharmony_ci{
35048c2ecf20Sopenharmony_ci	__be32 *p;
35058c2ecf20Sopenharmony_ci
35068c2ecf20Sopenharmony_ci	*res = 0;
35078c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U)))
35088c2ecf20Sopenharmony_ci		return -EIO;
35098c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) {
35108c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
35118c2ecf20Sopenharmony_ci		if (unlikely(!p))
35128c2ecf20Sopenharmony_ci			return -EIO;
35138c2ecf20Sopenharmony_ci		*res = be32_to_cpup(p);
35148c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT;
35158c2ecf20Sopenharmony_ci	}
35168c2ecf20Sopenharmony_ci	dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res);
35178c2ecf20Sopenharmony_ci	return 0;
35188c2ecf20Sopenharmony_ci}
35198c2ecf20Sopenharmony_ci
35208c2ecf20Sopenharmony_cistatic int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
35218c2ecf20Sopenharmony_ci{
35228c2ecf20Sopenharmony_ci	__be32 *p;
35238c2ecf20Sopenharmony_ci	int ret = 0;
35248c2ecf20Sopenharmony_ci
35258c2ecf20Sopenharmony_ci	*fileid = 0;
35268c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U)))
35278c2ecf20Sopenharmony_ci		return -EIO;
35288c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) {
35298c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
35308c2ecf20Sopenharmony_ci		if (unlikely(!p))
35318c2ecf20Sopenharmony_ci			return -EIO;
35328c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, fileid);
35338c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_FILEID;
35348c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_FILEID;
35358c2ecf20Sopenharmony_ci	}
35368c2ecf20Sopenharmony_ci	dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
35378c2ecf20Sopenharmony_ci	return ret;
35388c2ecf20Sopenharmony_ci}
35398c2ecf20Sopenharmony_ci
35408c2ecf20Sopenharmony_cistatic int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
35418c2ecf20Sopenharmony_ci{
35428c2ecf20Sopenharmony_ci	__be32 *p;
35438c2ecf20Sopenharmony_ci	int ret = 0;
35448c2ecf20Sopenharmony_ci
35458c2ecf20Sopenharmony_ci	*fileid = 0;
35468c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U)))
35478c2ecf20Sopenharmony_ci		return -EIO;
35488c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) {
35498c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
35508c2ecf20Sopenharmony_ci		if (unlikely(!p))
35518c2ecf20Sopenharmony_ci			return -EIO;
35528c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, fileid);
35538c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
35548c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID;
35558c2ecf20Sopenharmony_ci	}
35568c2ecf20Sopenharmony_ci	dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
35578c2ecf20Sopenharmony_ci	return ret;
35588c2ecf20Sopenharmony_ci}
35598c2ecf20Sopenharmony_ci
35608c2ecf20Sopenharmony_cistatic int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
35618c2ecf20Sopenharmony_ci{
35628c2ecf20Sopenharmony_ci	__be32 *p;
35638c2ecf20Sopenharmony_ci	int status = 0;
35648c2ecf20Sopenharmony_ci
35658c2ecf20Sopenharmony_ci	*res = 0;
35668c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U)))
35678c2ecf20Sopenharmony_ci		return -EIO;
35688c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) {
35698c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
35708c2ecf20Sopenharmony_ci		if (unlikely(!p))
35718c2ecf20Sopenharmony_ci			return -EIO;
35728c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
35738c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL;
35748c2ecf20Sopenharmony_ci	}
35758c2ecf20Sopenharmony_ci	dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res);
35768c2ecf20Sopenharmony_ci	return status;
35778c2ecf20Sopenharmony_ci}
35788c2ecf20Sopenharmony_ci
35798c2ecf20Sopenharmony_cistatic int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
35808c2ecf20Sopenharmony_ci{
35818c2ecf20Sopenharmony_ci	__be32 *p;
35828c2ecf20Sopenharmony_ci	int status = 0;
35838c2ecf20Sopenharmony_ci
35848c2ecf20Sopenharmony_ci	*res = 0;
35858c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U)))
35868c2ecf20Sopenharmony_ci		return -EIO;
35878c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) {
35888c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
35898c2ecf20Sopenharmony_ci		if (unlikely(!p))
35908c2ecf20Sopenharmony_ci			return -EIO;
35918c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
35928c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_FILES_FREE;
35938c2ecf20Sopenharmony_ci	}
35948c2ecf20Sopenharmony_ci	dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res);
35958c2ecf20Sopenharmony_ci	return status;
35968c2ecf20Sopenharmony_ci}
35978c2ecf20Sopenharmony_ci
35988c2ecf20Sopenharmony_cistatic int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
35998c2ecf20Sopenharmony_ci{
36008c2ecf20Sopenharmony_ci	__be32 *p;
36018c2ecf20Sopenharmony_ci	int status = 0;
36028c2ecf20Sopenharmony_ci
36038c2ecf20Sopenharmony_ci	*res = 0;
36048c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U)))
36058c2ecf20Sopenharmony_ci		return -EIO;
36068c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) {
36078c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
36088c2ecf20Sopenharmony_ci		if (unlikely(!p))
36098c2ecf20Sopenharmony_ci			return -EIO;
36108c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
36118c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL;
36128c2ecf20Sopenharmony_ci	}
36138c2ecf20Sopenharmony_ci	dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res);
36148c2ecf20Sopenharmony_ci	return status;
36158c2ecf20Sopenharmony_ci}
36168c2ecf20Sopenharmony_ci
36178c2ecf20Sopenharmony_cistatic int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
36188c2ecf20Sopenharmony_ci{
36198c2ecf20Sopenharmony_ci	u32 n;
36208c2ecf20Sopenharmony_ci	__be32 *p;
36218c2ecf20Sopenharmony_ci	int status = 0;
36228c2ecf20Sopenharmony_ci
36238c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
36248c2ecf20Sopenharmony_ci	if (unlikely(!p))
36258c2ecf20Sopenharmony_ci		return -EIO;
36268c2ecf20Sopenharmony_ci	n = be32_to_cpup(p);
36278c2ecf20Sopenharmony_ci	if (n == 0)
36288c2ecf20Sopenharmony_ci		goto root_path;
36298c2ecf20Sopenharmony_ci	dprintk("pathname4: ");
36308c2ecf20Sopenharmony_ci	if (n > NFS4_PATHNAME_MAXCOMPONENTS) {
36318c2ecf20Sopenharmony_ci		dprintk("cannot parse %d components in path\n", n);
36328c2ecf20Sopenharmony_ci		goto out_eio;
36338c2ecf20Sopenharmony_ci	}
36348c2ecf20Sopenharmony_ci	for (path->ncomponents = 0; path->ncomponents < n; path->ncomponents++) {
36358c2ecf20Sopenharmony_ci		struct nfs4_string *component = &path->components[path->ncomponents];
36368c2ecf20Sopenharmony_ci		status = decode_opaque_inline(xdr, &component->len, &component->data);
36378c2ecf20Sopenharmony_ci		if (unlikely(status != 0))
36388c2ecf20Sopenharmony_ci			goto out_eio;
36398c2ecf20Sopenharmony_ci		ifdebug (XDR)
36408c2ecf20Sopenharmony_ci			pr_cont("%s%.*s ",
36418c2ecf20Sopenharmony_ci				(path->ncomponents != n ? "/ " : ""),
36428c2ecf20Sopenharmony_ci				component->len, component->data);
36438c2ecf20Sopenharmony_ci	}
36448c2ecf20Sopenharmony_ciout:
36458c2ecf20Sopenharmony_ci	return status;
36468c2ecf20Sopenharmony_ciroot_path:
36478c2ecf20Sopenharmony_ci/* a root pathname is sent as a zero component4 */
36488c2ecf20Sopenharmony_ci	path->ncomponents = 1;
36498c2ecf20Sopenharmony_ci	path->components[0].len=0;
36508c2ecf20Sopenharmony_ci	path->components[0].data=NULL;
36518c2ecf20Sopenharmony_ci	dprintk("pathname4: /\n");
36528c2ecf20Sopenharmony_ci	goto out;
36538c2ecf20Sopenharmony_ciout_eio:
36548c2ecf20Sopenharmony_ci	dprintk(" status %d", status);
36558c2ecf20Sopenharmony_ci	status = -EIO;
36568c2ecf20Sopenharmony_ci	goto out;
36578c2ecf20Sopenharmony_ci}
36588c2ecf20Sopenharmony_ci
36598c2ecf20Sopenharmony_cistatic int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res)
36608c2ecf20Sopenharmony_ci{
36618c2ecf20Sopenharmony_ci	int n;
36628c2ecf20Sopenharmony_ci	__be32 *p;
36638c2ecf20Sopenharmony_ci	int status = -EIO;
36648c2ecf20Sopenharmony_ci
36658c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U)))
36668c2ecf20Sopenharmony_ci		goto out;
36678c2ecf20Sopenharmony_ci	status = 0;
36688c2ecf20Sopenharmony_ci	if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
36698c2ecf20Sopenharmony_ci		goto out;
36708c2ecf20Sopenharmony_ci	bitmap[0] &= ~FATTR4_WORD0_FS_LOCATIONS;
36718c2ecf20Sopenharmony_ci	status = -EIO;
36728c2ecf20Sopenharmony_ci	/* Ignore borken servers that return unrequested attrs */
36738c2ecf20Sopenharmony_ci	if (unlikely(res == NULL))
36748c2ecf20Sopenharmony_ci		goto out;
36758c2ecf20Sopenharmony_ci	dprintk("%s: fsroot:\n", __func__);
36768c2ecf20Sopenharmony_ci	status = decode_pathname(xdr, &res->fs_path);
36778c2ecf20Sopenharmony_ci	if (unlikely(status != 0))
36788c2ecf20Sopenharmony_ci		goto out;
36798c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
36808c2ecf20Sopenharmony_ci	if (unlikely(!p))
36818c2ecf20Sopenharmony_ci		goto out_eio;
36828c2ecf20Sopenharmony_ci	n = be32_to_cpup(p);
36838c2ecf20Sopenharmony_ci	for (res->nlocations = 0; res->nlocations < n; res->nlocations++) {
36848c2ecf20Sopenharmony_ci		u32 m;
36858c2ecf20Sopenharmony_ci		struct nfs4_fs_location *loc;
36868c2ecf20Sopenharmony_ci
36878c2ecf20Sopenharmony_ci		if (res->nlocations == NFS4_FS_LOCATIONS_MAXENTRIES)
36888c2ecf20Sopenharmony_ci			break;
36898c2ecf20Sopenharmony_ci		loc = &res->locations[res->nlocations];
36908c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
36918c2ecf20Sopenharmony_ci		if (unlikely(!p))
36928c2ecf20Sopenharmony_ci			goto out_eio;
36938c2ecf20Sopenharmony_ci		m = be32_to_cpup(p);
36948c2ecf20Sopenharmony_ci
36958c2ecf20Sopenharmony_ci		dprintk("%s: servers:\n", __func__);
36968c2ecf20Sopenharmony_ci		for (loc->nservers = 0; loc->nservers < m; loc->nservers++) {
36978c2ecf20Sopenharmony_ci			struct nfs4_string *server;
36988c2ecf20Sopenharmony_ci
36998c2ecf20Sopenharmony_ci			if (loc->nservers == NFS4_FS_LOCATION_MAXSERVERS) {
37008c2ecf20Sopenharmony_ci				unsigned int i;
37018c2ecf20Sopenharmony_ci				dprintk("%s: using first %u of %u servers "
37028c2ecf20Sopenharmony_ci					"returned for location %u\n",
37038c2ecf20Sopenharmony_ci						__func__,
37048c2ecf20Sopenharmony_ci						NFS4_FS_LOCATION_MAXSERVERS,
37058c2ecf20Sopenharmony_ci						m, res->nlocations);
37068c2ecf20Sopenharmony_ci				for (i = loc->nservers; i < m; i++) {
37078c2ecf20Sopenharmony_ci					unsigned int len;
37088c2ecf20Sopenharmony_ci					char *data;
37098c2ecf20Sopenharmony_ci					status = decode_opaque_inline(xdr, &len, &data);
37108c2ecf20Sopenharmony_ci					if (unlikely(status != 0))
37118c2ecf20Sopenharmony_ci						goto out_eio;
37128c2ecf20Sopenharmony_ci				}
37138c2ecf20Sopenharmony_ci				break;
37148c2ecf20Sopenharmony_ci			}
37158c2ecf20Sopenharmony_ci			server = &loc->servers[loc->nservers];
37168c2ecf20Sopenharmony_ci			status = decode_opaque_inline(xdr, &server->len, &server->data);
37178c2ecf20Sopenharmony_ci			if (unlikely(status != 0))
37188c2ecf20Sopenharmony_ci				goto out_eio;
37198c2ecf20Sopenharmony_ci			dprintk("%s ", server->data);
37208c2ecf20Sopenharmony_ci		}
37218c2ecf20Sopenharmony_ci		status = decode_pathname(xdr, &loc->rootpath);
37228c2ecf20Sopenharmony_ci		if (unlikely(status != 0))
37238c2ecf20Sopenharmony_ci			goto out_eio;
37248c2ecf20Sopenharmony_ci	}
37258c2ecf20Sopenharmony_ci	if (res->nlocations != 0)
37268c2ecf20Sopenharmony_ci		status = NFS_ATTR_FATTR_V4_LOCATIONS;
37278c2ecf20Sopenharmony_ciout:
37288c2ecf20Sopenharmony_ci	dprintk("%s: fs_locations done, error = %d\n", __func__, status);
37298c2ecf20Sopenharmony_ci	return status;
37308c2ecf20Sopenharmony_ciout_eio:
37318c2ecf20Sopenharmony_ci	status = -EIO;
37328c2ecf20Sopenharmony_ci	goto out;
37338c2ecf20Sopenharmony_ci}
37348c2ecf20Sopenharmony_ci
37358c2ecf20Sopenharmony_cistatic int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
37368c2ecf20Sopenharmony_ci{
37378c2ecf20Sopenharmony_ci	__be32 *p;
37388c2ecf20Sopenharmony_ci	int status = 0;
37398c2ecf20Sopenharmony_ci
37408c2ecf20Sopenharmony_ci	*res = 0;
37418c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U)))
37428c2ecf20Sopenharmony_ci		return -EIO;
37438c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) {
37448c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
37458c2ecf20Sopenharmony_ci		if (unlikely(!p))
37468c2ecf20Sopenharmony_ci			return -EIO;
37478c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
37488c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE;
37498c2ecf20Sopenharmony_ci	}
37508c2ecf20Sopenharmony_ci	dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res);
37518c2ecf20Sopenharmony_ci	return status;
37528c2ecf20Sopenharmony_ci}
37538c2ecf20Sopenharmony_ci
37548c2ecf20Sopenharmony_cistatic int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink)
37558c2ecf20Sopenharmony_ci{
37568c2ecf20Sopenharmony_ci	__be32 *p;
37578c2ecf20Sopenharmony_ci	int status = 0;
37588c2ecf20Sopenharmony_ci
37598c2ecf20Sopenharmony_ci	*maxlink = 1;
37608c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U)))
37618c2ecf20Sopenharmony_ci		return -EIO;
37628c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) {
37638c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
37648c2ecf20Sopenharmony_ci		if (unlikely(!p))
37658c2ecf20Sopenharmony_ci			return -EIO;
37668c2ecf20Sopenharmony_ci		*maxlink = be32_to_cpup(p);
37678c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_MAXLINK;
37688c2ecf20Sopenharmony_ci	}
37698c2ecf20Sopenharmony_ci	dprintk("%s: maxlink=%u\n", __func__, *maxlink);
37708c2ecf20Sopenharmony_ci	return status;
37718c2ecf20Sopenharmony_ci}
37728c2ecf20Sopenharmony_ci
37738c2ecf20Sopenharmony_cistatic int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname)
37748c2ecf20Sopenharmony_ci{
37758c2ecf20Sopenharmony_ci	__be32 *p;
37768c2ecf20Sopenharmony_ci	int status = 0;
37778c2ecf20Sopenharmony_ci
37788c2ecf20Sopenharmony_ci	*maxname = 1024;
37798c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U)))
37808c2ecf20Sopenharmony_ci		return -EIO;
37818c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) {
37828c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
37838c2ecf20Sopenharmony_ci		if (unlikely(!p))
37848c2ecf20Sopenharmony_ci			return -EIO;
37858c2ecf20Sopenharmony_ci		*maxname = be32_to_cpup(p);
37868c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_MAXNAME;
37878c2ecf20Sopenharmony_ci	}
37888c2ecf20Sopenharmony_ci	dprintk("%s: maxname=%u\n", __func__, *maxname);
37898c2ecf20Sopenharmony_ci	return status;
37908c2ecf20Sopenharmony_ci}
37918c2ecf20Sopenharmony_ci
37928c2ecf20Sopenharmony_cistatic int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
37938c2ecf20Sopenharmony_ci{
37948c2ecf20Sopenharmony_ci	__be32 *p;
37958c2ecf20Sopenharmony_ci	int status = 0;
37968c2ecf20Sopenharmony_ci
37978c2ecf20Sopenharmony_ci	*res = 1024;
37988c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXREAD - 1U)))
37998c2ecf20Sopenharmony_ci		return -EIO;
38008c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) {
38018c2ecf20Sopenharmony_ci		uint64_t maxread;
38028c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
38038c2ecf20Sopenharmony_ci		if (unlikely(!p))
38048c2ecf20Sopenharmony_ci			return -EIO;
38058c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, &maxread);
38068c2ecf20Sopenharmony_ci		if (maxread > 0x7FFFFFFF)
38078c2ecf20Sopenharmony_ci			maxread = 0x7FFFFFFF;
38088c2ecf20Sopenharmony_ci		*res = (uint32_t)maxread;
38098c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_MAXREAD;
38108c2ecf20Sopenharmony_ci	}
38118c2ecf20Sopenharmony_ci	dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res);
38128c2ecf20Sopenharmony_ci	return status;
38138c2ecf20Sopenharmony_ci}
38148c2ecf20Sopenharmony_ci
38158c2ecf20Sopenharmony_cistatic int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
38168c2ecf20Sopenharmony_ci{
38178c2ecf20Sopenharmony_ci	__be32 *p;
38188c2ecf20Sopenharmony_ci	int status = 0;
38198c2ecf20Sopenharmony_ci
38208c2ecf20Sopenharmony_ci	*res = 1024;
38218c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXWRITE - 1U)))
38228c2ecf20Sopenharmony_ci		return -EIO;
38238c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) {
38248c2ecf20Sopenharmony_ci		uint64_t maxwrite;
38258c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
38268c2ecf20Sopenharmony_ci		if (unlikely(!p))
38278c2ecf20Sopenharmony_ci			return -EIO;
38288c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, &maxwrite);
38298c2ecf20Sopenharmony_ci		if (maxwrite > 0x7FFFFFFF)
38308c2ecf20Sopenharmony_ci			maxwrite = 0x7FFFFFFF;
38318c2ecf20Sopenharmony_ci		*res = (uint32_t)maxwrite;
38328c2ecf20Sopenharmony_ci		bitmap[0] &= ~FATTR4_WORD0_MAXWRITE;
38338c2ecf20Sopenharmony_ci	}
38348c2ecf20Sopenharmony_ci	dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res);
38358c2ecf20Sopenharmony_ci	return status;
38368c2ecf20Sopenharmony_ci}
38378c2ecf20Sopenharmony_ci
38388c2ecf20Sopenharmony_cistatic int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode)
38398c2ecf20Sopenharmony_ci{
38408c2ecf20Sopenharmony_ci	uint32_t tmp;
38418c2ecf20Sopenharmony_ci	__be32 *p;
38428c2ecf20Sopenharmony_ci	int ret = 0;
38438c2ecf20Sopenharmony_ci
38448c2ecf20Sopenharmony_ci	*mode = 0;
38458c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U)))
38468c2ecf20Sopenharmony_ci		return -EIO;
38478c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_MODE)) {
38488c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
38498c2ecf20Sopenharmony_ci		if (unlikely(!p))
38508c2ecf20Sopenharmony_ci			return -EIO;
38518c2ecf20Sopenharmony_ci		tmp = be32_to_cpup(p);
38528c2ecf20Sopenharmony_ci		*mode = tmp & ~S_IFMT;
38538c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_MODE;
38548c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_MODE;
38558c2ecf20Sopenharmony_ci	}
38568c2ecf20Sopenharmony_ci	dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode);
38578c2ecf20Sopenharmony_ci	return ret;
38588c2ecf20Sopenharmony_ci}
38598c2ecf20Sopenharmony_ci
38608c2ecf20Sopenharmony_cistatic int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink)
38618c2ecf20Sopenharmony_ci{
38628c2ecf20Sopenharmony_ci	__be32 *p;
38638c2ecf20Sopenharmony_ci	int ret = 0;
38648c2ecf20Sopenharmony_ci
38658c2ecf20Sopenharmony_ci	*nlink = 1;
38668c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U)))
38678c2ecf20Sopenharmony_ci		return -EIO;
38688c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) {
38698c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
38708c2ecf20Sopenharmony_ci		if (unlikely(!p))
38718c2ecf20Sopenharmony_ci			return -EIO;
38728c2ecf20Sopenharmony_ci		*nlink = be32_to_cpup(p);
38738c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_NUMLINKS;
38748c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_NLINK;
38758c2ecf20Sopenharmony_ci	}
38768c2ecf20Sopenharmony_ci	dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink);
38778c2ecf20Sopenharmony_ci	return ret;
38788c2ecf20Sopenharmony_ci}
38798c2ecf20Sopenharmony_ci
38808c2ecf20Sopenharmony_cistatic ssize_t decode_nfs4_string(struct xdr_stream *xdr,
38818c2ecf20Sopenharmony_ci		struct nfs4_string *name, gfp_t gfp_flags)
38828c2ecf20Sopenharmony_ci{
38838c2ecf20Sopenharmony_ci	ssize_t ret;
38848c2ecf20Sopenharmony_ci
38858c2ecf20Sopenharmony_ci	ret = xdr_stream_decode_string_dup(xdr, &name->data,
38868c2ecf20Sopenharmony_ci			XDR_MAX_NETOBJ, gfp_flags);
38878c2ecf20Sopenharmony_ci	name->len = 0;
38888c2ecf20Sopenharmony_ci	if (ret > 0)
38898c2ecf20Sopenharmony_ci		name->len = ret;
38908c2ecf20Sopenharmony_ci	return ret;
38918c2ecf20Sopenharmony_ci}
38928c2ecf20Sopenharmony_ci
38938c2ecf20Sopenharmony_cistatic int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap,
38948c2ecf20Sopenharmony_ci		const struct nfs_server *server, kuid_t *uid,
38958c2ecf20Sopenharmony_ci		struct nfs4_string *owner_name)
38968c2ecf20Sopenharmony_ci{
38978c2ecf20Sopenharmony_ci	ssize_t len;
38988c2ecf20Sopenharmony_ci	char *p;
38998c2ecf20Sopenharmony_ci
39008c2ecf20Sopenharmony_ci	*uid = make_kuid(&init_user_ns, -2);
39018c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
39028c2ecf20Sopenharmony_ci		return -EIO;
39038c2ecf20Sopenharmony_ci	if (!(bitmap[1] & FATTR4_WORD1_OWNER))
39048c2ecf20Sopenharmony_ci		return 0;
39058c2ecf20Sopenharmony_ci	bitmap[1] &= ~FATTR4_WORD1_OWNER;
39068c2ecf20Sopenharmony_ci
39078c2ecf20Sopenharmony_ci	if (owner_name != NULL) {
39088c2ecf20Sopenharmony_ci		len = decode_nfs4_string(xdr, owner_name, GFP_NOIO);
39098c2ecf20Sopenharmony_ci		if (len <= 0)
39108c2ecf20Sopenharmony_ci			goto out;
39118c2ecf20Sopenharmony_ci		dprintk("%s: name=%s\n", __func__, owner_name->data);
39128c2ecf20Sopenharmony_ci		return NFS_ATTR_FATTR_OWNER_NAME;
39138c2ecf20Sopenharmony_ci	} else {
39148c2ecf20Sopenharmony_ci		len = xdr_stream_decode_opaque_inline(xdr, (void **)&p,
39158c2ecf20Sopenharmony_ci				XDR_MAX_NETOBJ);
39168c2ecf20Sopenharmony_ci		if (len <= 0 || nfs_map_name_to_uid(server, p, len, uid) != 0)
39178c2ecf20Sopenharmony_ci			goto out;
39188c2ecf20Sopenharmony_ci		dprintk("%s: uid=%d\n", __func__, (int)from_kuid(&init_user_ns, *uid));
39198c2ecf20Sopenharmony_ci		return NFS_ATTR_FATTR_OWNER;
39208c2ecf20Sopenharmony_ci	}
39218c2ecf20Sopenharmony_ciout:
39228c2ecf20Sopenharmony_ci	if (len == -EBADMSG)
39238c2ecf20Sopenharmony_ci		return -EIO;
39248c2ecf20Sopenharmony_ci	return 0;
39258c2ecf20Sopenharmony_ci}
39268c2ecf20Sopenharmony_ci
39278c2ecf20Sopenharmony_cistatic int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap,
39288c2ecf20Sopenharmony_ci		const struct nfs_server *server, kgid_t *gid,
39298c2ecf20Sopenharmony_ci		struct nfs4_string *group_name)
39308c2ecf20Sopenharmony_ci{
39318c2ecf20Sopenharmony_ci	ssize_t len;
39328c2ecf20Sopenharmony_ci	char *p;
39338c2ecf20Sopenharmony_ci
39348c2ecf20Sopenharmony_ci	*gid = make_kgid(&init_user_ns, -2);
39358c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
39368c2ecf20Sopenharmony_ci		return -EIO;
39378c2ecf20Sopenharmony_ci	if (!(bitmap[1] & FATTR4_WORD1_OWNER_GROUP))
39388c2ecf20Sopenharmony_ci		return 0;
39398c2ecf20Sopenharmony_ci	bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP;
39408c2ecf20Sopenharmony_ci
39418c2ecf20Sopenharmony_ci	if (group_name != NULL) {
39428c2ecf20Sopenharmony_ci		len = decode_nfs4_string(xdr, group_name, GFP_NOIO);
39438c2ecf20Sopenharmony_ci		if (len <= 0)
39448c2ecf20Sopenharmony_ci			goto out;
39458c2ecf20Sopenharmony_ci		dprintk("%s: name=%s\n", __func__, group_name->data);
39468c2ecf20Sopenharmony_ci		return NFS_ATTR_FATTR_GROUP_NAME;
39478c2ecf20Sopenharmony_ci	} else {
39488c2ecf20Sopenharmony_ci		len = xdr_stream_decode_opaque_inline(xdr, (void **)&p,
39498c2ecf20Sopenharmony_ci				XDR_MAX_NETOBJ);
39508c2ecf20Sopenharmony_ci		if (len <= 0 || nfs_map_group_to_gid(server, p, len, gid) != 0)
39518c2ecf20Sopenharmony_ci			goto out;
39528c2ecf20Sopenharmony_ci		dprintk("%s: gid=%d\n", __func__, (int)from_kgid(&init_user_ns, *gid));
39538c2ecf20Sopenharmony_ci		return NFS_ATTR_FATTR_GROUP;
39548c2ecf20Sopenharmony_ci	}
39558c2ecf20Sopenharmony_ciout:
39568c2ecf20Sopenharmony_ci	if (len == -EBADMSG)
39578c2ecf20Sopenharmony_ci		return -EIO;
39588c2ecf20Sopenharmony_ci	return 0;
39598c2ecf20Sopenharmony_ci}
39608c2ecf20Sopenharmony_ci
39618c2ecf20Sopenharmony_cistatic int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev)
39628c2ecf20Sopenharmony_ci{
39638c2ecf20Sopenharmony_ci	uint32_t major = 0, minor = 0;
39648c2ecf20Sopenharmony_ci	__be32 *p;
39658c2ecf20Sopenharmony_ci	int ret = 0;
39668c2ecf20Sopenharmony_ci
39678c2ecf20Sopenharmony_ci	*rdev = MKDEV(0,0);
39688c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U)))
39698c2ecf20Sopenharmony_ci		return -EIO;
39708c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) {
39718c2ecf20Sopenharmony_ci		dev_t tmp;
39728c2ecf20Sopenharmony_ci
39738c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
39748c2ecf20Sopenharmony_ci		if (unlikely(!p))
39758c2ecf20Sopenharmony_ci			return -EIO;
39768c2ecf20Sopenharmony_ci		major = be32_to_cpup(p++);
39778c2ecf20Sopenharmony_ci		minor = be32_to_cpup(p);
39788c2ecf20Sopenharmony_ci		tmp = MKDEV(major, minor);
39798c2ecf20Sopenharmony_ci		if (MAJOR(tmp) == major && MINOR(tmp) == minor)
39808c2ecf20Sopenharmony_ci			*rdev = tmp;
39818c2ecf20Sopenharmony_ci		bitmap[1] &= ~ FATTR4_WORD1_RAWDEV;
39828c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_RDEV;
39838c2ecf20Sopenharmony_ci	}
39848c2ecf20Sopenharmony_ci	dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor);
39858c2ecf20Sopenharmony_ci	return ret;
39868c2ecf20Sopenharmony_ci}
39878c2ecf20Sopenharmony_ci
39888c2ecf20Sopenharmony_cistatic int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
39898c2ecf20Sopenharmony_ci{
39908c2ecf20Sopenharmony_ci	__be32 *p;
39918c2ecf20Sopenharmony_ci	int status = 0;
39928c2ecf20Sopenharmony_ci
39938c2ecf20Sopenharmony_ci	*res = 0;
39948c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U)))
39958c2ecf20Sopenharmony_ci		return -EIO;
39968c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) {
39978c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
39988c2ecf20Sopenharmony_ci		if (unlikely(!p))
39998c2ecf20Sopenharmony_ci			return -EIO;
40008c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
40018c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL;
40028c2ecf20Sopenharmony_ci	}
40038c2ecf20Sopenharmony_ci	dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res);
40048c2ecf20Sopenharmony_ci	return status;
40058c2ecf20Sopenharmony_ci}
40068c2ecf20Sopenharmony_ci
40078c2ecf20Sopenharmony_cistatic int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
40088c2ecf20Sopenharmony_ci{
40098c2ecf20Sopenharmony_ci	__be32 *p;
40108c2ecf20Sopenharmony_ci	int status = 0;
40118c2ecf20Sopenharmony_ci
40128c2ecf20Sopenharmony_ci	*res = 0;
40138c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U)))
40148c2ecf20Sopenharmony_ci		return -EIO;
40158c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) {
40168c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
40178c2ecf20Sopenharmony_ci		if (unlikely(!p))
40188c2ecf20Sopenharmony_ci			return -EIO;
40198c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
40208c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE;
40218c2ecf20Sopenharmony_ci	}
40228c2ecf20Sopenharmony_ci	dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res);
40238c2ecf20Sopenharmony_ci	return status;
40248c2ecf20Sopenharmony_ci}
40258c2ecf20Sopenharmony_ci
40268c2ecf20Sopenharmony_cistatic int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
40278c2ecf20Sopenharmony_ci{
40288c2ecf20Sopenharmony_ci	__be32 *p;
40298c2ecf20Sopenharmony_ci	int status = 0;
40308c2ecf20Sopenharmony_ci
40318c2ecf20Sopenharmony_ci	*res = 0;
40328c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U)))
40338c2ecf20Sopenharmony_ci		return -EIO;
40348c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) {
40358c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
40368c2ecf20Sopenharmony_ci		if (unlikely(!p))
40378c2ecf20Sopenharmony_ci			return -EIO;
40388c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
40398c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL;
40408c2ecf20Sopenharmony_ci	}
40418c2ecf20Sopenharmony_ci	dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res);
40428c2ecf20Sopenharmony_ci	return status;
40438c2ecf20Sopenharmony_ci}
40448c2ecf20Sopenharmony_ci
40458c2ecf20Sopenharmony_cistatic int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used)
40468c2ecf20Sopenharmony_ci{
40478c2ecf20Sopenharmony_ci	__be32 *p;
40488c2ecf20Sopenharmony_ci	int ret = 0;
40498c2ecf20Sopenharmony_ci
40508c2ecf20Sopenharmony_ci	*used = 0;
40518c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U)))
40528c2ecf20Sopenharmony_ci		return -EIO;
40538c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) {
40548c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
40558c2ecf20Sopenharmony_ci		if (unlikely(!p))
40568c2ecf20Sopenharmony_ci			return -EIO;
40578c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, used);
40588c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_SPACE_USED;
40598c2ecf20Sopenharmony_ci		ret = NFS_ATTR_FATTR_SPACE_USED;
40608c2ecf20Sopenharmony_ci	}
40618c2ecf20Sopenharmony_ci	dprintk("%s: space used=%Lu\n", __func__,
40628c2ecf20Sopenharmony_ci			(unsigned long long)*used);
40638c2ecf20Sopenharmony_ci	return ret;
40648c2ecf20Sopenharmony_ci}
40658c2ecf20Sopenharmony_ci
40668c2ecf20Sopenharmony_cistatic __be32 *
40678c2ecf20Sopenharmony_cixdr_decode_nfstime4(__be32 *p, struct timespec64 *t)
40688c2ecf20Sopenharmony_ci{
40698c2ecf20Sopenharmony_ci	__u64 sec;
40708c2ecf20Sopenharmony_ci
40718c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &sec);
40728c2ecf20Sopenharmony_ci	t-> tv_sec = sec;
40738c2ecf20Sopenharmony_ci	t->tv_nsec = be32_to_cpup(p++);
40748c2ecf20Sopenharmony_ci	return p;
40758c2ecf20Sopenharmony_ci}
40768c2ecf20Sopenharmony_ci
40778c2ecf20Sopenharmony_cistatic int decode_attr_time(struct xdr_stream *xdr, struct timespec64 *time)
40788c2ecf20Sopenharmony_ci{
40798c2ecf20Sopenharmony_ci	__be32 *p;
40808c2ecf20Sopenharmony_ci
40818c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, nfstime4_maxsz << 2);
40828c2ecf20Sopenharmony_ci	if (unlikely(!p))
40838c2ecf20Sopenharmony_ci		return -EIO;
40848c2ecf20Sopenharmony_ci	xdr_decode_nfstime4(p, time);
40858c2ecf20Sopenharmony_ci	return 0;
40868c2ecf20Sopenharmony_ci}
40878c2ecf20Sopenharmony_ci
40888c2ecf20Sopenharmony_cistatic int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
40898c2ecf20Sopenharmony_ci{
40908c2ecf20Sopenharmony_ci	int status = 0;
40918c2ecf20Sopenharmony_ci
40928c2ecf20Sopenharmony_ci	time->tv_sec = 0;
40938c2ecf20Sopenharmony_ci	time->tv_nsec = 0;
40948c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_ACCESS - 1U)))
40958c2ecf20Sopenharmony_ci		return -EIO;
40968c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_TIME_ACCESS)) {
40978c2ecf20Sopenharmony_ci		status = decode_attr_time(xdr, time);
40988c2ecf20Sopenharmony_ci		if (status == 0)
40998c2ecf20Sopenharmony_ci			status = NFS_ATTR_FATTR_ATIME;
41008c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_TIME_ACCESS;
41018c2ecf20Sopenharmony_ci	}
41028c2ecf20Sopenharmony_ci	dprintk("%s: atime=%lld\n", __func__, time->tv_sec);
41038c2ecf20Sopenharmony_ci	return status;
41048c2ecf20Sopenharmony_ci}
41058c2ecf20Sopenharmony_ci
41068c2ecf20Sopenharmony_cistatic int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
41078c2ecf20Sopenharmony_ci{
41088c2ecf20Sopenharmony_ci	int status = 0;
41098c2ecf20Sopenharmony_ci
41108c2ecf20Sopenharmony_ci	time->tv_sec = 0;
41118c2ecf20Sopenharmony_ci	time->tv_nsec = 0;
41128c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_METADATA - 1U)))
41138c2ecf20Sopenharmony_ci		return -EIO;
41148c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) {
41158c2ecf20Sopenharmony_ci		status = decode_attr_time(xdr, time);
41168c2ecf20Sopenharmony_ci		if (status == 0)
41178c2ecf20Sopenharmony_ci			status = NFS_ATTR_FATTR_CTIME;
41188c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_TIME_METADATA;
41198c2ecf20Sopenharmony_ci	}
41208c2ecf20Sopenharmony_ci	dprintk("%s: ctime=%lld\n", __func__, time->tv_sec);
41218c2ecf20Sopenharmony_ci	return status;
41228c2ecf20Sopenharmony_ci}
41238c2ecf20Sopenharmony_ci
41248c2ecf20Sopenharmony_cistatic int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap,
41258c2ecf20Sopenharmony_ci				  struct timespec64 *time)
41268c2ecf20Sopenharmony_ci{
41278c2ecf20Sopenharmony_ci	int status = 0;
41288c2ecf20Sopenharmony_ci
41298c2ecf20Sopenharmony_ci	time->tv_sec = 0;
41308c2ecf20Sopenharmony_ci	time->tv_nsec = 0;
41318c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_DELTA - 1U)))
41328c2ecf20Sopenharmony_ci		return -EIO;
41338c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_TIME_DELTA)) {
41348c2ecf20Sopenharmony_ci		status = decode_attr_time(xdr, time);
41358c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_TIME_DELTA;
41368c2ecf20Sopenharmony_ci	}
41378c2ecf20Sopenharmony_ci	dprintk("%s: time_delta=%lld %ld\n", __func__, time->tv_sec,
41388c2ecf20Sopenharmony_ci		time->tv_nsec);
41398c2ecf20Sopenharmony_ci	return status;
41408c2ecf20Sopenharmony_ci}
41418c2ecf20Sopenharmony_ci
41428c2ecf20Sopenharmony_cistatic int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
41438c2ecf20Sopenharmony_ci					struct nfs4_label *label)
41448c2ecf20Sopenharmony_ci{
41458c2ecf20Sopenharmony_ci	uint32_t pi = 0;
41468c2ecf20Sopenharmony_ci	uint32_t lfs = 0;
41478c2ecf20Sopenharmony_ci	__u32 len;
41488c2ecf20Sopenharmony_ci	__be32 *p;
41498c2ecf20Sopenharmony_ci	int status = 0;
41508c2ecf20Sopenharmony_ci
41518c2ecf20Sopenharmony_ci	if (unlikely(bitmap[2] & (FATTR4_WORD2_SECURITY_LABEL - 1U)))
41528c2ecf20Sopenharmony_ci		return -EIO;
41538c2ecf20Sopenharmony_ci	if (likely(bitmap[2] & FATTR4_WORD2_SECURITY_LABEL)) {
41548c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
41558c2ecf20Sopenharmony_ci		if (unlikely(!p))
41568c2ecf20Sopenharmony_ci			return -EIO;
41578c2ecf20Sopenharmony_ci		lfs = be32_to_cpup(p++);
41588c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
41598c2ecf20Sopenharmony_ci		if (unlikely(!p))
41608c2ecf20Sopenharmony_ci			return -EIO;
41618c2ecf20Sopenharmony_ci		pi = be32_to_cpup(p++);
41628c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
41638c2ecf20Sopenharmony_ci		if (unlikely(!p))
41648c2ecf20Sopenharmony_ci			return -EIO;
41658c2ecf20Sopenharmony_ci		len = be32_to_cpup(p++);
41668c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, len);
41678c2ecf20Sopenharmony_ci		if (unlikely(!p))
41688c2ecf20Sopenharmony_ci			return -EIO;
41698c2ecf20Sopenharmony_ci		bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
41708c2ecf20Sopenharmony_ci		if (len < NFS4_MAXLABELLEN) {
41718c2ecf20Sopenharmony_ci			if (label && label->len) {
41728c2ecf20Sopenharmony_ci				if (label->len < len)
41738c2ecf20Sopenharmony_ci					return -ERANGE;
41748c2ecf20Sopenharmony_ci				memcpy(label->label, p, len);
41758c2ecf20Sopenharmony_ci				label->len = len;
41768c2ecf20Sopenharmony_ci				label->pi = pi;
41778c2ecf20Sopenharmony_ci				label->lfs = lfs;
41788c2ecf20Sopenharmony_ci				status = NFS_ATTR_FATTR_V4_SECURITY_LABEL;
41798c2ecf20Sopenharmony_ci			}
41808c2ecf20Sopenharmony_ci		} else
41818c2ecf20Sopenharmony_ci			printk(KERN_WARNING "%s: label too long (%u)!\n",
41828c2ecf20Sopenharmony_ci					__func__, len);
41838c2ecf20Sopenharmony_ci		if (label && label->label)
41848c2ecf20Sopenharmony_ci			dprintk("%s: label=%.*s, len=%d, PI=%d, LFS=%d\n",
41858c2ecf20Sopenharmony_ci				__func__, label->len, (char *)label->label,
41868c2ecf20Sopenharmony_ci				label->len, label->pi, label->lfs);
41878c2ecf20Sopenharmony_ci	}
41888c2ecf20Sopenharmony_ci	return status;
41898c2ecf20Sopenharmony_ci}
41908c2ecf20Sopenharmony_ci
41918c2ecf20Sopenharmony_cistatic int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
41928c2ecf20Sopenharmony_ci{
41938c2ecf20Sopenharmony_ci	int status = 0;
41948c2ecf20Sopenharmony_ci
41958c2ecf20Sopenharmony_ci	time->tv_sec = 0;
41968c2ecf20Sopenharmony_ci	time->tv_nsec = 0;
41978c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_MODIFY - 1U)))
41988c2ecf20Sopenharmony_ci		return -EIO;
41998c2ecf20Sopenharmony_ci	if (likely(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) {
42008c2ecf20Sopenharmony_ci		status = decode_attr_time(xdr, time);
42018c2ecf20Sopenharmony_ci		if (status == 0)
42028c2ecf20Sopenharmony_ci			status = NFS_ATTR_FATTR_MTIME;
42038c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_TIME_MODIFY;
42048c2ecf20Sopenharmony_ci	}
42058c2ecf20Sopenharmony_ci	dprintk("%s: mtime=%lld\n", __func__, time->tv_sec);
42068c2ecf20Sopenharmony_ci	return status;
42078c2ecf20Sopenharmony_ci}
42088c2ecf20Sopenharmony_ci
42098c2ecf20Sopenharmony_cistatic int decode_attr_xattrsupport(struct xdr_stream *xdr, uint32_t *bitmap,
42108c2ecf20Sopenharmony_ci				    uint32_t *res)
42118c2ecf20Sopenharmony_ci{
42128c2ecf20Sopenharmony_ci	__be32 *p;
42138c2ecf20Sopenharmony_ci
42148c2ecf20Sopenharmony_ci	*res = 0;
42158c2ecf20Sopenharmony_ci	if (unlikely(bitmap[2] & (FATTR4_WORD2_XATTR_SUPPORT - 1U)))
42168c2ecf20Sopenharmony_ci		return -EIO;
42178c2ecf20Sopenharmony_ci	if (likely(bitmap[2] & FATTR4_WORD2_XATTR_SUPPORT)) {
42188c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
42198c2ecf20Sopenharmony_ci		if (unlikely(!p))
42208c2ecf20Sopenharmony_ci			return -EIO;
42218c2ecf20Sopenharmony_ci		*res = be32_to_cpup(p);
42228c2ecf20Sopenharmony_ci		bitmap[2] &= ~FATTR4_WORD2_XATTR_SUPPORT;
42238c2ecf20Sopenharmony_ci	}
42248c2ecf20Sopenharmony_ci	dprintk("%s: XATTR support=%s\n", __func__,
42258c2ecf20Sopenharmony_ci		*res == 0 ? "false" : "true");
42268c2ecf20Sopenharmony_ci	return 0;
42278c2ecf20Sopenharmony_ci}
42288c2ecf20Sopenharmony_ci
42298c2ecf20Sopenharmony_cistatic int verify_attr_len(struct xdr_stream *xdr, unsigned int savep, uint32_t attrlen)
42308c2ecf20Sopenharmony_ci{
42318c2ecf20Sopenharmony_ci	unsigned int attrwords = XDR_QUADLEN(attrlen);
42328c2ecf20Sopenharmony_ci	unsigned int nwords = (xdr_stream_pos(xdr) - savep) >> 2;
42338c2ecf20Sopenharmony_ci
42348c2ecf20Sopenharmony_ci	if (unlikely(attrwords != nwords)) {
42358c2ecf20Sopenharmony_ci		dprintk("%s: server returned incorrect attribute length: "
42368c2ecf20Sopenharmony_ci			"%u %c %u\n",
42378c2ecf20Sopenharmony_ci				__func__,
42388c2ecf20Sopenharmony_ci				attrwords << 2,
42398c2ecf20Sopenharmony_ci				(attrwords < nwords) ? '<' : '>',
42408c2ecf20Sopenharmony_ci				nwords << 2);
42418c2ecf20Sopenharmony_ci		return -EIO;
42428c2ecf20Sopenharmony_ci	}
42438c2ecf20Sopenharmony_ci	return 0;
42448c2ecf20Sopenharmony_ci}
42458c2ecf20Sopenharmony_ci
42468c2ecf20Sopenharmony_cistatic int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
42478c2ecf20Sopenharmony_ci{
42488c2ecf20Sopenharmony_ci	__be32 *p;
42498c2ecf20Sopenharmony_ci
42508c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 20);
42518c2ecf20Sopenharmony_ci	if (unlikely(!p))
42528c2ecf20Sopenharmony_ci		return -EIO;
42538c2ecf20Sopenharmony_ci	cinfo->atomic = be32_to_cpup(p++);
42548c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &cinfo->before);
42558c2ecf20Sopenharmony_ci	xdr_decode_hyper(p, &cinfo->after);
42568c2ecf20Sopenharmony_ci	return 0;
42578c2ecf20Sopenharmony_ci}
42588c2ecf20Sopenharmony_ci
42598c2ecf20Sopenharmony_cistatic int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access)
42608c2ecf20Sopenharmony_ci{
42618c2ecf20Sopenharmony_ci	__be32 *p;
42628c2ecf20Sopenharmony_ci	uint32_t supp, acc;
42638c2ecf20Sopenharmony_ci	int status;
42648c2ecf20Sopenharmony_ci
42658c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_ACCESS);
42668c2ecf20Sopenharmony_ci	if (status)
42678c2ecf20Sopenharmony_ci		return status;
42688c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
42698c2ecf20Sopenharmony_ci	if (unlikely(!p))
42708c2ecf20Sopenharmony_ci		return -EIO;
42718c2ecf20Sopenharmony_ci	supp = be32_to_cpup(p++);
42728c2ecf20Sopenharmony_ci	acc = be32_to_cpup(p);
42738c2ecf20Sopenharmony_ci	*supported = supp;
42748c2ecf20Sopenharmony_ci	*access = acc;
42758c2ecf20Sopenharmony_ci	return 0;
42768c2ecf20Sopenharmony_ci}
42778c2ecf20Sopenharmony_ci
42788c2ecf20Sopenharmony_cistatic int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len)
42798c2ecf20Sopenharmony_ci{
42808c2ecf20Sopenharmony_ci	ssize_t ret = xdr_stream_decode_opaque_fixed(xdr, buf, len);
42818c2ecf20Sopenharmony_ci	if (unlikely(ret < 0))
42828c2ecf20Sopenharmony_ci		return -EIO;
42838c2ecf20Sopenharmony_ci	return 0;
42848c2ecf20Sopenharmony_ci}
42858c2ecf20Sopenharmony_ci
42868c2ecf20Sopenharmony_cistatic int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
42878c2ecf20Sopenharmony_ci{
42888c2ecf20Sopenharmony_ci	return decode_opaque_fixed(xdr, stateid, NFS4_STATEID_SIZE);
42898c2ecf20Sopenharmony_ci}
42908c2ecf20Sopenharmony_ci
42918c2ecf20Sopenharmony_cistatic int decode_open_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
42928c2ecf20Sopenharmony_ci{
42938c2ecf20Sopenharmony_ci	stateid->type = NFS4_OPEN_STATEID_TYPE;
42948c2ecf20Sopenharmony_ci	return decode_stateid(xdr, stateid);
42958c2ecf20Sopenharmony_ci}
42968c2ecf20Sopenharmony_ci
42978c2ecf20Sopenharmony_cistatic int decode_lock_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
42988c2ecf20Sopenharmony_ci{
42998c2ecf20Sopenharmony_ci	stateid->type = NFS4_LOCK_STATEID_TYPE;
43008c2ecf20Sopenharmony_ci	return decode_stateid(xdr, stateid);
43018c2ecf20Sopenharmony_ci}
43028c2ecf20Sopenharmony_ci
43038c2ecf20Sopenharmony_cistatic int decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
43048c2ecf20Sopenharmony_ci{
43058c2ecf20Sopenharmony_ci	stateid->type = NFS4_DELEGATION_STATEID_TYPE;
43068c2ecf20Sopenharmony_ci	return decode_stateid(xdr, stateid);
43078c2ecf20Sopenharmony_ci}
43088c2ecf20Sopenharmony_ci
43098c2ecf20Sopenharmony_cistatic int decode_invalid_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
43108c2ecf20Sopenharmony_ci{
43118c2ecf20Sopenharmony_ci	nfs4_stateid dummy;
43128c2ecf20Sopenharmony_ci
43138c2ecf20Sopenharmony_ci	nfs4_stateid_copy(stateid, &invalid_stateid);
43148c2ecf20Sopenharmony_ci	return decode_stateid(xdr, &dummy);
43158c2ecf20Sopenharmony_ci}
43168c2ecf20Sopenharmony_ci
43178c2ecf20Sopenharmony_cistatic int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
43188c2ecf20Sopenharmony_ci{
43198c2ecf20Sopenharmony_ci	int status;
43208c2ecf20Sopenharmony_ci
43218c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_CLOSE);
43228c2ecf20Sopenharmony_ci	if (status != -EIO)
43238c2ecf20Sopenharmony_ci		nfs_increment_open_seqid(status, res->seqid);
43248c2ecf20Sopenharmony_ci	if (!status)
43258c2ecf20Sopenharmony_ci		status = decode_invalid_stateid(xdr, &res->stateid);
43268c2ecf20Sopenharmony_ci	return status;
43278c2ecf20Sopenharmony_ci}
43288c2ecf20Sopenharmony_ci
43298c2ecf20Sopenharmony_cistatic int decode_verifier(struct xdr_stream *xdr, void *verifier)
43308c2ecf20Sopenharmony_ci{
43318c2ecf20Sopenharmony_ci	return decode_opaque_fixed(xdr, verifier, NFS4_VERIFIER_SIZE);
43328c2ecf20Sopenharmony_ci}
43338c2ecf20Sopenharmony_ci
43348c2ecf20Sopenharmony_cistatic int decode_write_verifier(struct xdr_stream *xdr, struct nfs_write_verifier *verifier)
43358c2ecf20Sopenharmony_ci{
43368c2ecf20Sopenharmony_ci	return decode_opaque_fixed(xdr, verifier->data, NFS4_VERIFIER_SIZE);
43378c2ecf20Sopenharmony_ci}
43388c2ecf20Sopenharmony_ci
43398c2ecf20Sopenharmony_cistatic int decode_commit(struct xdr_stream *xdr, struct nfs_commitres *res)
43408c2ecf20Sopenharmony_ci{
43418c2ecf20Sopenharmony_ci	struct nfs_writeverf *verf = res->verf;
43428c2ecf20Sopenharmony_ci	int status;
43438c2ecf20Sopenharmony_ci
43448c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_COMMIT);
43458c2ecf20Sopenharmony_ci	if (!status)
43468c2ecf20Sopenharmony_ci		status = decode_write_verifier(xdr, &verf->verifier);
43478c2ecf20Sopenharmony_ci	if (!status)
43488c2ecf20Sopenharmony_ci		verf->committed = NFS_FILE_SYNC;
43498c2ecf20Sopenharmony_ci	return status;
43508c2ecf20Sopenharmony_ci}
43518c2ecf20Sopenharmony_ci
43528c2ecf20Sopenharmony_cistatic int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
43538c2ecf20Sopenharmony_ci{
43548c2ecf20Sopenharmony_ci	__be32 *p;
43558c2ecf20Sopenharmony_ci	uint32_t bmlen;
43568c2ecf20Sopenharmony_ci	int status;
43578c2ecf20Sopenharmony_ci
43588c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_CREATE);
43598c2ecf20Sopenharmony_ci	if (status)
43608c2ecf20Sopenharmony_ci		return status;
43618c2ecf20Sopenharmony_ci	if ((status = decode_change_info(xdr, cinfo)))
43628c2ecf20Sopenharmony_ci		return status;
43638c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
43648c2ecf20Sopenharmony_ci	if (unlikely(!p))
43658c2ecf20Sopenharmony_ci		return -EIO;
43668c2ecf20Sopenharmony_ci	bmlen = be32_to_cpup(p);
43678c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, bmlen << 2);
43688c2ecf20Sopenharmony_ci	if (likely(p))
43698c2ecf20Sopenharmony_ci		return 0;
43708c2ecf20Sopenharmony_ci	return -EIO;
43718c2ecf20Sopenharmony_ci}
43728c2ecf20Sopenharmony_ci
43738c2ecf20Sopenharmony_cistatic int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
43748c2ecf20Sopenharmony_ci{
43758c2ecf20Sopenharmony_ci	unsigned int savep;
43768c2ecf20Sopenharmony_ci	uint32_t attrlen, bitmap[3] = {0};
43778c2ecf20Sopenharmony_ci	int status;
43788c2ecf20Sopenharmony_ci
43798c2ecf20Sopenharmony_ci	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
43808c2ecf20Sopenharmony_ci		goto xdr_error;
43818c2ecf20Sopenharmony_ci	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
43828c2ecf20Sopenharmony_ci		goto xdr_error;
43838c2ecf20Sopenharmony_ci	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
43848c2ecf20Sopenharmony_ci		goto xdr_error;
43858c2ecf20Sopenharmony_ci	if ((status = decode_attr_supported(xdr, bitmap, res->attr_bitmask)) != 0)
43868c2ecf20Sopenharmony_ci		goto xdr_error;
43878c2ecf20Sopenharmony_ci	if ((status = decode_attr_fh_expire_type(xdr, bitmap,
43888c2ecf20Sopenharmony_ci						 &res->fh_expire_type)) != 0)
43898c2ecf20Sopenharmony_ci		goto xdr_error;
43908c2ecf20Sopenharmony_ci	if ((status = decode_attr_link_support(xdr, bitmap, &res->has_links)) != 0)
43918c2ecf20Sopenharmony_ci		goto xdr_error;
43928c2ecf20Sopenharmony_ci	if ((status = decode_attr_symlink_support(xdr, bitmap, &res->has_symlinks)) != 0)
43938c2ecf20Sopenharmony_ci		goto xdr_error;
43948c2ecf20Sopenharmony_ci	if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0)
43958c2ecf20Sopenharmony_ci		goto xdr_error;
43968c2ecf20Sopenharmony_ci	if ((status = decode_attr_exclcreat_supported(xdr, bitmap,
43978c2ecf20Sopenharmony_ci				res->exclcreat_bitmask)) != 0)
43988c2ecf20Sopenharmony_ci		goto xdr_error;
43998c2ecf20Sopenharmony_ci	status = verify_attr_len(xdr, savep, attrlen);
44008c2ecf20Sopenharmony_cixdr_error:
44018c2ecf20Sopenharmony_ci	dprintk("%s: xdr returned %d!\n", __func__, -status);
44028c2ecf20Sopenharmony_ci	return status;
44038c2ecf20Sopenharmony_ci}
44048c2ecf20Sopenharmony_ci
44058c2ecf20Sopenharmony_cistatic int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
44068c2ecf20Sopenharmony_ci{
44078c2ecf20Sopenharmony_ci	unsigned int savep;
44088c2ecf20Sopenharmony_ci	uint32_t attrlen, bitmap[3] = {0};
44098c2ecf20Sopenharmony_ci	int status;
44108c2ecf20Sopenharmony_ci
44118c2ecf20Sopenharmony_ci	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
44128c2ecf20Sopenharmony_ci		goto xdr_error;
44138c2ecf20Sopenharmony_ci	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
44148c2ecf20Sopenharmony_ci		goto xdr_error;
44158c2ecf20Sopenharmony_ci	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
44168c2ecf20Sopenharmony_ci		goto xdr_error;
44178c2ecf20Sopenharmony_ci
44188c2ecf20Sopenharmony_ci	if ((status = decode_attr_files_avail(xdr, bitmap, &fsstat->afiles)) != 0)
44198c2ecf20Sopenharmony_ci		goto xdr_error;
44208c2ecf20Sopenharmony_ci	if ((status = decode_attr_files_free(xdr, bitmap, &fsstat->ffiles)) != 0)
44218c2ecf20Sopenharmony_ci		goto xdr_error;
44228c2ecf20Sopenharmony_ci	if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0)
44238c2ecf20Sopenharmony_ci		goto xdr_error;
44248c2ecf20Sopenharmony_ci
44258c2ecf20Sopenharmony_ci	status = -EIO;
44268c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0]))
44278c2ecf20Sopenharmony_ci		goto xdr_error;
44288c2ecf20Sopenharmony_ci
44298c2ecf20Sopenharmony_ci	if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0)
44308c2ecf20Sopenharmony_ci		goto xdr_error;
44318c2ecf20Sopenharmony_ci	if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0)
44328c2ecf20Sopenharmony_ci		goto xdr_error;
44338c2ecf20Sopenharmony_ci	if ((status = decode_attr_space_total(xdr, bitmap, &fsstat->tbytes)) != 0)
44348c2ecf20Sopenharmony_ci		goto xdr_error;
44358c2ecf20Sopenharmony_ci
44368c2ecf20Sopenharmony_ci	status = verify_attr_len(xdr, savep, attrlen);
44378c2ecf20Sopenharmony_cixdr_error:
44388c2ecf20Sopenharmony_ci	dprintk("%s: xdr returned %d!\n", __func__, -status);
44398c2ecf20Sopenharmony_ci	return status;
44408c2ecf20Sopenharmony_ci}
44418c2ecf20Sopenharmony_ci
44428c2ecf20Sopenharmony_cistatic int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf)
44438c2ecf20Sopenharmony_ci{
44448c2ecf20Sopenharmony_ci	unsigned int savep;
44458c2ecf20Sopenharmony_ci	uint32_t attrlen, bitmap[3] = {0};
44468c2ecf20Sopenharmony_ci	int status;
44478c2ecf20Sopenharmony_ci
44488c2ecf20Sopenharmony_ci	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
44498c2ecf20Sopenharmony_ci		goto xdr_error;
44508c2ecf20Sopenharmony_ci	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
44518c2ecf20Sopenharmony_ci		goto xdr_error;
44528c2ecf20Sopenharmony_ci	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
44538c2ecf20Sopenharmony_ci		goto xdr_error;
44548c2ecf20Sopenharmony_ci
44558c2ecf20Sopenharmony_ci	if ((status = decode_attr_maxlink(xdr, bitmap, &pathconf->max_link)) != 0)
44568c2ecf20Sopenharmony_ci		goto xdr_error;
44578c2ecf20Sopenharmony_ci	if ((status = decode_attr_maxname(xdr, bitmap, &pathconf->max_namelen)) != 0)
44588c2ecf20Sopenharmony_ci		goto xdr_error;
44598c2ecf20Sopenharmony_ci
44608c2ecf20Sopenharmony_ci	status = verify_attr_len(xdr, savep, attrlen);
44618c2ecf20Sopenharmony_cixdr_error:
44628c2ecf20Sopenharmony_ci	dprintk("%s: xdr returned %d!\n", __func__, -status);
44638c2ecf20Sopenharmony_ci	return status;
44648c2ecf20Sopenharmony_ci}
44658c2ecf20Sopenharmony_ci
44668c2ecf20Sopenharmony_cistatic int decode_threshold_hint(struct xdr_stream *xdr,
44678c2ecf20Sopenharmony_ci				  uint32_t *bitmap,
44688c2ecf20Sopenharmony_ci				  uint64_t *res,
44698c2ecf20Sopenharmony_ci				  uint32_t hint_bit)
44708c2ecf20Sopenharmony_ci{
44718c2ecf20Sopenharmony_ci	__be32 *p;
44728c2ecf20Sopenharmony_ci
44738c2ecf20Sopenharmony_ci	*res = 0;
44748c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & hint_bit)) {
44758c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
44768c2ecf20Sopenharmony_ci		if (unlikely(!p))
44778c2ecf20Sopenharmony_ci			return -EIO;
44788c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, res);
44798c2ecf20Sopenharmony_ci	}
44808c2ecf20Sopenharmony_ci	return 0;
44818c2ecf20Sopenharmony_ci}
44828c2ecf20Sopenharmony_ci
44838c2ecf20Sopenharmony_cistatic int decode_first_threshold_item4(struct xdr_stream *xdr,
44848c2ecf20Sopenharmony_ci					struct nfs4_threshold *res)
44858c2ecf20Sopenharmony_ci{
44868c2ecf20Sopenharmony_ci	__be32 *p;
44878c2ecf20Sopenharmony_ci	unsigned int savep;
44888c2ecf20Sopenharmony_ci	uint32_t bitmap[3] = {0,}, attrlen;
44898c2ecf20Sopenharmony_ci	int status;
44908c2ecf20Sopenharmony_ci
44918c2ecf20Sopenharmony_ci	/* layout type */
44928c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
44938c2ecf20Sopenharmony_ci	if (unlikely(!p))
44948c2ecf20Sopenharmony_ci		return -EIO;
44958c2ecf20Sopenharmony_ci	res->l_type = be32_to_cpup(p);
44968c2ecf20Sopenharmony_ci
44978c2ecf20Sopenharmony_ci	/* thi_hintset bitmap */
44988c2ecf20Sopenharmony_ci	status = decode_attr_bitmap(xdr, bitmap);
44998c2ecf20Sopenharmony_ci	if (status < 0)
45008c2ecf20Sopenharmony_ci		goto xdr_error;
45018c2ecf20Sopenharmony_ci
45028c2ecf20Sopenharmony_ci	/* thi_hintlist length */
45038c2ecf20Sopenharmony_ci	status = decode_attr_length(xdr, &attrlen, &savep);
45048c2ecf20Sopenharmony_ci	if (status < 0)
45058c2ecf20Sopenharmony_ci		goto xdr_error;
45068c2ecf20Sopenharmony_ci	/* thi_hintlist */
45078c2ecf20Sopenharmony_ci	status = decode_threshold_hint(xdr, bitmap, &res->rd_sz, THRESHOLD_RD);
45088c2ecf20Sopenharmony_ci	if (status < 0)
45098c2ecf20Sopenharmony_ci		goto xdr_error;
45108c2ecf20Sopenharmony_ci	status = decode_threshold_hint(xdr, bitmap, &res->wr_sz, THRESHOLD_WR);
45118c2ecf20Sopenharmony_ci	if (status < 0)
45128c2ecf20Sopenharmony_ci		goto xdr_error;
45138c2ecf20Sopenharmony_ci	status = decode_threshold_hint(xdr, bitmap, &res->rd_io_sz,
45148c2ecf20Sopenharmony_ci				       THRESHOLD_RD_IO);
45158c2ecf20Sopenharmony_ci	if (status < 0)
45168c2ecf20Sopenharmony_ci		goto xdr_error;
45178c2ecf20Sopenharmony_ci	status = decode_threshold_hint(xdr, bitmap, &res->wr_io_sz,
45188c2ecf20Sopenharmony_ci				       THRESHOLD_WR_IO);
45198c2ecf20Sopenharmony_ci	if (status < 0)
45208c2ecf20Sopenharmony_ci		goto xdr_error;
45218c2ecf20Sopenharmony_ci
45228c2ecf20Sopenharmony_ci	status = verify_attr_len(xdr, savep, attrlen);
45238c2ecf20Sopenharmony_ci	res->bm = bitmap[0];
45248c2ecf20Sopenharmony_ci
45258c2ecf20Sopenharmony_ci	dprintk("%s bm=0x%x rd_sz=%llu wr_sz=%llu rd_io=%llu wr_io=%llu\n",
45268c2ecf20Sopenharmony_ci		 __func__, res->bm, res->rd_sz, res->wr_sz, res->rd_io_sz,
45278c2ecf20Sopenharmony_ci		res->wr_io_sz);
45288c2ecf20Sopenharmony_cixdr_error:
45298c2ecf20Sopenharmony_ci	dprintk("%s ret=%d!\n", __func__, status);
45308c2ecf20Sopenharmony_ci	return status;
45318c2ecf20Sopenharmony_ci}
45328c2ecf20Sopenharmony_ci
45338c2ecf20Sopenharmony_ci/*
45348c2ecf20Sopenharmony_ci * Thresholds on pNFS direct I/O vrs MDS I/O
45358c2ecf20Sopenharmony_ci */
45368c2ecf20Sopenharmony_cistatic int decode_attr_mdsthreshold(struct xdr_stream *xdr,
45378c2ecf20Sopenharmony_ci				    uint32_t *bitmap,
45388c2ecf20Sopenharmony_ci				    struct nfs4_threshold *res)
45398c2ecf20Sopenharmony_ci{
45408c2ecf20Sopenharmony_ci	__be32 *p;
45418c2ecf20Sopenharmony_ci	int status = 0;
45428c2ecf20Sopenharmony_ci	uint32_t num;
45438c2ecf20Sopenharmony_ci
45448c2ecf20Sopenharmony_ci	if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U)))
45458c2ecf20Sopenharmony_ci		return -EIO;
45468c2ecf20Sopenharmony_ci	if (bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD) {
45478c2ecf20Sopenharmony_ci		/* Did the server return an unrequested attribute? */
45488c2ecf20Sopenharmony_ci		if (unlikely(res == NULL))
45498c2ecf20Sopenharmony_ci			return -EREMOTEIO;
45508c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
45518c2ecf20Sopenharmony_ci		if (unlikely(!p))
45528c2ecf20Sopenharmony_ci			return -EIO;
45538c2ecf20Sopenharmony_ci		num = be32_to_cpup(p);
45548c2ecf20Sopenharmony_ci		if (num == 0)
45558c2ecf20Sopenharmony_ci			return 0;
45568c2ecf20Sopenharmony_ci		if (num > 1)
45578c2ecf20Sopenharmony_ci			printk(KERN_INFO "%s: Warning: Multiple pNFS layout "
45588c2ecf20Sopenharmony_ci				"drivers per filesystem not supported\n",
45598c2ecf20Sopenharmony_ci				__func__);
45608c2ecf20Sopenharmony_ci
45618c2ecf20Sopenharmony_ci		status = decode_first_threshold_item4(xdr, res);
45628c2ecf20Sopenharmony_ci		bitmap[2] &= ~FATTR4_WORD2_MDSTHRESHOLD;
45638c2ecf20Sopenharmony_ci	}
45648c2ecf20Sopenharmony_ci	return status;
45658c2ecf20Sopenharmony_ci}
45668c2ecf20Sopenharmony_ci
45678c2ecf20Sopenharmony_cistatic int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
45688c2ecf20Sopenharmony_ci		struct nfs_fattr *fattr, struct nfs_fh *fh,
45698c2ecf20Sopenharmony_ci		struct nfs4_fs_locations *fs_loc, struct nfs4_label *label,
45708c2ecf20Sopenharmony_ci		const struct nfs_server *server)
45718c2ecf20Sopenharmony_ci{
45728c2ecf20Sopenharmony_ci	int status;
45738c2ecf20Sopenharmony_ci	umode_t fmode = 0;
45748c2ecf20Sopenharmony_ci	uint32_t type;
45758c2ecf20Sopenharmony_ci	int32_t err;
45768c2ecf20Sopenharmony_ci
45778c2ecf20Sopenharmony_ci	status = decode_attr_type(xdr, bitmap, &type);
45788c2ecf20Sopenharmony_ci	if (status < 0)
45798c2ecf20Sopenharmony_ci		goto xdr_error;
45808c2ecf20Sopenharmony_ci	fattr->mode = 0;
45818c2ecf20Sopenharmony_ci	if (status != 0) {
45828c2ecf20Sopenharmony_ci		fattr->mode |= nfs_type2fmt[type];
45838c2ecf20Sopenharmony_ci		fattr->valid |= status;
45848c2ecf20Sopenharmony_ci	}
45858c2ecf20Sopenharmony_ci
45868c2ecf20Sopenharmony_ci	status = decode_attr_change(xdr, bitmap, &fattr->change_attr);
45878c2ecf20Sopenharmony_ci	if (status < 0)
45888c2ecf20Sopenharmony_ci		goto xdr_error;
45898c2ecf20Sopenharmony_ci	fattr->valid |= status;
45908c2ecf20Sopenharmony_ci
45918c2ecf20Sopenharmony_ci	status = decode_attr_size(xdr, bitmap, &fattr->size);
45928c2ecf20Sopenharmony_ci	if (status < 0)
45938c2ecf20Sopenharmony_ci		goto xdr_error;
45948c2ecf20Sopenharmony_ci	fattr->valid |= status;
45958c2ecf20Sopenharmony_ci
45968c2ecf20Sopenharmony_ci	status = decode_attr_fsid(xdr, bitmap, &fattr->fsid);
45978c2ecf20Sopenharmony_ci	if (status < 0)
45988c2ecf20Sopenharmony_ci		goto xdr_error;
45998c2ecf20Sopenharmony_ci	fattr->valid |= status;
46008c2ecf20Sopenharmony_ci
46018c2ecf20Sopenharmony_ci	err = 0;
46028c2ecf20Sopenharmony_ci	status = decode_attr_error(xdr, bitmap, &err);
46038c2ecf20Sopenharmony_ci	if (status < 0)
46048c2ecf20Sopenharmony_ci		goto xdr_error;
46058c2ecf20Sopenharmony_ci
46068c2ecf20Sopenharmony_ci	status = decode_attr_filehandle(xdr, bitmap, fh);
46078c2ecf20Sopenharmony_ci	if (status < 0)
46088c2ecf20Sopenharmony_ci		goto xdr_error;
46098c2ecf20Sopenharmony_ci
46108c2ecf20Sopenharmony_ci	status = decode_attr_fileid(xdr, bitmap, &fattr->fileid);
46118c2ecf20Sopenharmony_ci	if (status < 0)
46128c2ecf20Sopenharmony_ci		goto xdr_error;
46138c2ecf20Sopenharmony_ci	fattr->valid |= status;
46148c2ecf20Sopenharmony_ci
46158c2ecf20Sopenharmony_ci	status = decode_attr_fs_locations(xdr, bitmap, fs_loc);
46168c2ecf20Sopenharmony_ci	if (status < 0)
46178c2ecf20Sopenharmony_ci		goto xdr_error;
46188c2ecf20Sopenharmony_ci	fattr->valid |= status;
46198c2ecf20Sopenharmony_ci
46208c2ecf20Sopenharmony_ci	status = -EIO;
46218c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0]))
46228c2ecf20Sopenharmony_ci		goto xdr_error;
46238c2ecf20Sopenharmony_ci
46248c2ecf20Sopenharmony_ci	status = decode_attr_mode(xdr, bitmap, &fmode);
46258c2ecf20Sopenharmony_ci	if (status < 0)
46268c2ecf20Sopenharmony_ci		goto xdr_error;
46278c2ecf20Sopenharmony_ci	if (status != 0) {
46288c2ecf20Sopenharmony_ci		fattr->mode |= fmode;
46298c2ecf20Sopenharmony_ci		fattr->valid |= status;
46308c2ecf20Sopenharmony_ci	}
46318c2ecf20Sopenharmony_ci
46328c2ecf20Sopenharmony_ci	status = decode_attr_nlink(xdr, bitmap, &fattr->nlink);
46338c2ecf20Sopenharmony_ci	if (status < 0)
46348c2ecf20Sopenharmony_ci		goto xdr_error;
46358c2ecf20Sopenharmony_ci	fattr->valid |= status;
46368c2ecf20Sopenharmony_ci
46378c2ecf20Sopenharmony_ci	status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, fattr->owner_name);
46388c2ecf20Sopenharmony_ci	if (status < 0)
46398c2ecf20Sopenharmony_ci		goto xdr_error;
46408c2ecf20Sopenharmony_ci	fattr->valid |= status;
46418c2ecf20Sopenharmony_ci
46428c2ecf20Sopenharmony_ci	status = decode_attr_group(xdr, bitmap, server, &fattr->gid, fattr->group_name);
46438c2ecf20Sopenharmony_ci	if (status < 0)
46448c2ecf20Sopenharmony_ci		goto xdr_error;
46458c2ecf20Sopenharmony_ci	fattr->valid |= status;
46468c2ecf20Sopenharmony_ci
46478c2ecf20Sopenharmony_ci	status = decode_attr_rdev(xdr, bitmap, &fattr->rdev);
46488c2ecf20Sopenharmony_ci	if (status < 0)
46498c2ecf20Sopenharmony_ci		goto xdr_error;
46508c2ecf20Sopenharmony_ci	fattr->valid |= status;
46518c2ecf20Sopenharmony_ci
46528c2ecf20Sopenharmony_ci	status = decode_attr_space_used(xdr, bitmap, &fattr->du.nfs3.used);
46538c2ecf20Sopenharmony_ci	if (status < 0)
46548c2ecf20Sopenharmony_ci		goto xdr_error;
46558c2ecf20Sopenharmony_ci	fattr->valid |= status;
46568c2ecf20Sopenharmony_ci
46578c2ecf20Sopenharmony_ci	status = decode_attr_time_access(xdr, bitmap, &fattr->atime);
46588c2ecf20Sopenharmony_ci	if (status < 0)
46598c2ecf20Sopenharmony_ci		goto xdr_error;
46608c2ecf20Sopenharmony_ci	fattr->valid |= status;
46618c2ecf20Sopenharmony_ci
46628c2ecf20Sopenharmony_ci	status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime);
46638c2ecf20Sopenharmony_ci	if (status < 0)
46648c2ecf20Sopenharmony_ci		goto xdr_error;
46658c2ecf20Sopenharmony_ci	fattr->valid |= status;
46668c2ecf20Sopenharmony_ci
46678c2ecf20Sopenharmony_ci	status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime);
46688c2ecf20Sopenharmony_ci	if (status < 0)
46698c2ecf20Sopenharmony_ci		goto xdr_error;
46708c2ecf20Sopenharmony_ci	fattr->valid |= status;
46718c2ecf20Sopenharmony_ci
46728c2ecf20Sopenharmony_ci	status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid);
46738c2ecf20Sopenharmony_ci	if (status < 0)
46748c2ecf20Sopenharmony_ci		goto xdr_error;
46758c2ecf20Sopenharmony_ci	fattr->valid |= status;
46768c2ecf20Sopenharmony_ci
46778c2ecf20Sopenharmony_ci	status = -EIO;
46788c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1]))
46798c2ecf20Sopenharmony_ci		goto xdr_error;
46808c2ecf20Sopenharmony_ci
46818c2ecf20Sopenharmony_ci	status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold);
46828c2ecf20Sopenharmony_ci	if (status < 0)
46838c2ecf20Sopenharmony_ci		goto xdr_error;
46848c2ecf20Sopenharmony_ci
46858c2ecf20Sopenharmony_ci	if (label) {
46868c2ecf20Sopenharmony_ci		status = decode_attr_security_label(xdr, bitmap, label);
46878c2ecf20Sopenharmony_ci		if (status < 0)
46888c2ecf20Sopenharmony_ci			goto xdr_error;
46898c2ecf20Sopenharmony_ci		fattr->valid |= status;
46908c2ecf20Sopenharmony_ci	}
46918c2ecf20Sopenharmony_ci
46928c2ecf20Sopenharmony_cixdr_error:
46938c2ecf20Sopenharmony_ci	dprintk("%s: xdr returned %d\n", __func__, -status);
46948c2ecf20Sopenharmony_ci	return status;
46958c2ecf20Sopenharmony_ci}
46968c2ecf20Sopenharmony_ci
46978c2ecf20Sopenharmony_cistatic int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
46988c2ecf20Sopenharmony_ci		struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc,
46998c2ecf20Sopenharmony_ci		struct nfs4_label *label, const struct nfs_server *server)
47008c2ecf20Sopenharmony_ci{
47018c2ecf20Sopenharmony_ci	unsigned int savep;
47028c2ecf20Sopenharmony_ci	uint32_t attrlen,
47038c2ecf20Sopenharmony_ci		 bitmap[3] = {0};
47048c2ecf20Sopenharmony_ci	int status;
47058c2ecf20Sopenharmony_ci
47068c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_GETATTR);
47078c2ecf20Sopenharmony_ci	if (status < 0)
47088c2ecf20Sopenharmony_ci		goto xdr_error;
47098c2ecf20Sopenharmony_ci
47108c2ecf20Sopenharmony_ci	status = decode_attr_bitmap(xdr, bitmap);
47118c2ecf20Sopenharmony_ci	if (status < 0)
47128c2ecf20Sopenharmony_ci		goto xdr_error;
47138c2ecf20Sopenharmony_ci
47148c2ecf20Sopenharmony_ci	status = decode_attr_length(xdr, &attrlen, &savep);
47158c2ecf20Sopenharmony_ci	if (status < 0)
47168c2ecf20Sopenharmony_ci		goto xdr_error;
47178c2ecf20Sopenharmony_ci
47188c2ecf20Sopenharmony_ci	status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc,
47198c2ecf20Sopenharmony_ci					label, server);
47208c2ecf20Sopenharmony_ci	if (status < 0)
47218c2ecf20Sopenharmony_ci		goto xdr_error;
47228c2ecf20Sopenharmony_ci
47238c2ecf20Sopenharmony_ci	status = verify_attr_len(xdr, savep, attrlen);
47248c2ecf20Sopenharmony_cixdr_error:
47258c2ecf20Sopenharmony_ci	dprintk("%s: xdr returned %d\n", __func__, -status);
47268c2ecf20Sopenharmony_ci	return status;
47278c2ecf20Sopenharmony_ci}
47288c2ecf20Sopenharmony_ci
47298c2ecf20Sopenharmony_cistatic int decode_getfattr_label(struct xdr_stream *xdr, struct nfs_fattr *fattr,
47308c2ecf20Sopenharmony_ci		struct nfs4_label *label, const struct nfs_server *server)
47318c2ecf20Sopenharmony_ci{
47328c2ecf20Sopenharmony_ci	return decode_getfattr_generic(xdr, fattr, NULL, NULL, label, server);
47338c2ecf20Sopenharmony_ci}
47348c2ecf20Sopenharmony_ci
47358c2ecf20Sopenharmony_cistatic int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
47368c2ecf20Sopenharmony_ci		const struct nfs_server *server)
47378c2ecf20Sopenharmony_ci{
47388c2ecf20Sopenharmony_ci	return decode_getfattr_generic(xdr, fattr, NULL, NULL, NULL, server);
47398c2ecf20Sopenharmony_ci}
47408c2ecf20Sopenharmony_ci
47418c2ecf20Sopenharmony_ci/*
47428c2ecf20Sopenharmony_ci * Decode potentially multiple layout types.
47438c2ecf20Sopenharmony_ci */
47448c2ecf20Sopenharmony_cistatic int decode_pnfs_layout_types(struct xdr_stream *xdr,
47458c2ecf20Sopenharmony_ci				    struct nfs_fsinfo *fsinfo)
47468c2ecf20Sopenharmony_ci{
47478c2ecf20Sopenharmony_ci	__be32 *p;
47488c2ecf20Sopenharmony_ci	uint32_t i;
47498c2ecf20Sopenharmony_ci
47508c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
47518c2ecf20Sopenharmony_ci	if (unlikely(!p))
47528c2ecf20Sopenharmony_ci		return -EIO;
47538c2ecf20Sopenharmony_ci	fsinfo->nlayouttypes = be32_to_cpup(p);
47548c2ecf20Sopenharmony_ci
47558c2ecf20Sopenharmony_ci	/* pNFS is not supported by the underlying file system */
47568c2ecf20Sopenharmony_ci	if (fsinfo->nlayouttypes == 0)
47578c2ecf20Sopenharmony_ci		return 0;
47588c2ecf20Sopenharmony_ci
47598c2ecf20Sopenharmony_ci	/* Decode and set first layout type, move xdr->p past unused types */
47608c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, fsinfo->nlayouttypes * 4);
47618c2ecf20Sopenharmony_ci	if (unlikely(!p))
47628c2ecf20Sopenharmony_ci		return -EIO;
47638c2ecf20Sopenharmony_ci
47648c2ecf20Sopenharmony_ci	/* If we get too many, then just cap it at the max */
47658c2ecf20Sopenharmony_ci	if (fsinfo->nlayouttypes > NFS_MAX_LAYOUT_TYPES) {
47668c2ecf20Sopenharmony_ci		printk(KERN_INFO "NFS: %s: Warning: Too many (%u) pNFS layout types\n",
47678c2ecf20Sopenharmony_ci			__func__, fsinfo->nlayouttypes);
47688c2ecf20Sopenharmony_ci		fsinfo->nlayouttypes = NFS_MAX_LAYOUT_TYPES;
47698c2ecf20Sopenharmony_ci	}
47708c2ecf20Sopenharmony_ci
47718c2ecf20Sopenharmony_ci	for(i = 0; i < fsinfo->nlayouttypes; ++i)
47728c2ecf20Sopenharmony_ci		fsinfo->layouttype[i] = be32_to_cpup(p++);
47738c2ecf20Sopenharmony_ci	return 0;
47748c2ecf20Sopenharmony_ci}
47758c2ecf20Sopenharmony_ci
47768c2ecf20Sopenharmony_ci/*
47778c2ecf20Sopenharmony_ci * The type of file system exported.
47788c2ecf20Sopenharmony_ci * Note we must ensure that layouttype is set in any non-error case.
47798c2ecf20Sopenharmony_ci */
47808c2ecf20Sopenharmony_cistatic int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap,
47818c2ecf20Sopenharmony_ci				struct nfs_fsinfo *fsinfo)
47828c2ecf20Sopenharmony_ci{
47838c2ecf20Sopenharmony_ci	int status = 0;
47848c2ecf20Sopenharmony_ci
47858c2ecf20Sopenharmony_ci	dprintk("%s: bitmap is %x\n", __func__, bitmap[1]);
47868c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U)))
47878c2ecf20Sopenharmony_ci		return -EIO;
47888c2ecf20Sopenharmony_ci	if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) {
47898c2ecf20Sopenharmony_ci		status = decode_pnfs_layout_types(xdr, fsinfo);
47908c2ecf20Sopenharmony_ci		bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES;
47918c2ecf20Sopenharmony_ci	}
47928c2ecf20Sopenharmony_ci	return status;
47938c2ecf20Sopenharmony_ci}
47948c2ecf20Sopenharmony_ci
47958c2ecf20Sopenharmony_ci/*
47968c2ecf20Sopenharmony_ci * The prefered block size for layout directed io
47978c2ecf20Sopenharmony_ci */
47988c2ecf20Sopenharmony_cistatic int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap,
47998c2ecf20Sopenharmony_ci				      uint32_t *res)
48008c2ecf20Sopenharmony_ci{
48018c2ecf20Sopenharmony_ci	__be32 *p;
48028c2ecf20Sopenharmony_ci
48038c2ecf20Sopenharmony_ci	dprintk("%s: bitmap is %x\n", __func__, bitmap[2]);
48048c2ecf20Sopenharmony_ci	*res = 0;
48058c2ecf20Sopenharmony_ci	if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) {
48068c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
48078c2ecf20Sopenharmony_ci		if (unlikely(!p))
48088c2ecf20Sopenharmony_ci			return -EIO;
48098c2ecf20Sopenharmony_ci		*res = be32_to_cpup(p);
48108c2ecf20Sopenharmony_ci		bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE;
48118c2ecf20Sopenharmony_ci	}
48128c2ecf20Sopenharmony_ci	return 0;
48138c2ecf20Sopenharmony_ci}
48148c2ecf20Sopenharmony_ci
48158c2ecf20Sopenharmony_ci/*
48168c2ecf20Sopenharmony_ci * The granularity of a CLONE operation.
48178c2ecf20Sopenharmony_ci */
48188c2ecf20Sopenharmony_cistatic int decode_attr_clone_blksize(struct xdr_stream *xdr, uint32_t *bitmap,
48198c2ecf20Sopenharmony_ci				     uint32_t *res)
48208c2ecf20Sopenharmony_ci{
48218c2ecf20Sopenharmony_ci	__be32 *p;
48228c2ecf20Sopenharmony_ci
48238c2ecf20Sopenharmony_ci	dprintk("%s: bitmap is %x\n", __func__, bitmap[2]);
48248c2ecf20Sopenharmony_ci	*res = 0;
48258c2ecf20Sopenharmony_ci	if (bitmap[2] & FATTR4_WORD2_CLONE_BLKSIZE) {
48268c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
48278c2ecf20Sopenharmony_ci		if (unlikely(!p))
48288c2ecf20Sopenharmony_ci			return -EIO;
48298c2ecf20Sopenharmony_ci		*res = be32_to_cpup(p);
48308c2ecf20Sopenharmony_ci		bitmap[2] &= ~FATTR4_WORD2_CLONE_BLKSIZE;
48318c2ecf20Sopenharmony_ci	}
48328c2ecf20Sopenharmony_ci	return 0;
48338c2ecf20Sopenharmony_ci}
48348c2ecf20Sopenharmony_ci
48358c2ecf20Sopenharmony_cistatic int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
48368c2ecf20Sopenharmony_ci{
48378c2ecf20Sopenharmony_ci	unsigned int savep;
48388c2ecf20Sopenharmony_ci	uint32_t attrlen, bitmap[3];
48398c2ecf20Sopenharmony_ci	int status;
48408c2ecf20Sopenharmony_ci
48418c2ecf20Sopenharmony_ci	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
48428c2ecf20Sopenharmony_ci		goto xdr_error;
48438c2ecf20Sopenharmony_ci	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
48448c2ecf20Sopenharmony_ci		goto xdr_error;
48458c2ecf20Sopenharmony_ci	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
48468c2ecf20Sopenharmony_ci		goto xdr_error;
48478c2ecf20Sopenharmony_ci
48488c2ecf20Sopenharmony_ci	fsinfo->rtmult = fsinfo->wtmult = 512;	/* ??? */
48498c2ecf20Sopenharmony_ci
48508c2ecf20Sopenharmony_ci	if ((status = decode_attr_lease_time(xdr, bitmap, &fsinfo->lease_time)) != 0)
48518c2ecf20Sopenharmony_ci		goto xdr_error;
48528c2ecf20Sopenharmony_ci	if ((status = decode_attr_maxfilesize(xdr, bitmap, &fsinfo->maxfilesize)) != 0)
48538c2ecf20Sopenharmony_ci		goto xdr_error;
48548c2ecf20Sopenharmony_ci	if ((status = decode_attr_maxread(xdr, bitmap, &fsinfo->rtmax)) != 0)
48558c2ecf20Sopenharmony_ci		goto xdr_error;
48568c2ecf20Sopenharmony_ci	fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax;
48578c2ecf20Sopenharmony_ci	if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0)
48588c2ecf20Sopenharmony_ci		goto xdr_error;
48598c2ecf20Sopenharmony_ci	fsinfo->wtpref = fsinfo->wtmax;
48608c2ecf20Sopenharmony_ci
48618c2ecf20Sopenharmony_ci	status = -EIO;
48628c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0]))
48638c2ecf20Sopenharmony_ci		goto xdr_error;
48648c2ecf20Sopenharmony_ci
48658c2ecf20Sopenharmony_ci	status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta);
48668c2ecf20Sopenharmony_ci	if (status != 0)
48678c2ecf20Sopenharmony_ci		goto xdr_error;
48688c2ecf20Sopenharmony_ci	status = decode_attr_pnfstype(xdr, bitmap, fsinfo);
48698c2ecf20Sopenharmony_ci	if (status != 0)
48708c2ecf20Sopenharmony_ci		goto xdr_error;
48718c2ecf20Sopenharmony_ci
48728c2ecf20Sopenharmony_ci	status = -EIO;
48738c2ecf20Sopenharmony_ci	if (unlikely(bitmap[1]))
48748c2ecf20Sopenharmony_ci		goto xdr_error;
48758c2ecf20Sopenharmony_ci
48768c2ecf20Sopenharmony_ci	status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize);
48778c2ecf20Sopenharmony_ci	if (status)
48788c2ecf20Sopenharmony_ci		goto xdr_error;
48798c2ecf20Sopenharmony_ci	status = decode_attr_clone_blksize(xdr, bitmap, &fsinfo->clone_blksize);
48808c2ecf20Sopenharmony_ci	if (status)
48818c2ecf20Sopenharmony_ci		goto xdr_error;
48828c2ecf20Sopenharmony_ci
48838c2ecf20Sopenharmony_ci	status = decode_attr_xattrsupport(xdr, bitmap,
48848c2ecf20Sopenharmony_ci					  &fsinfo->xattr_support);
48858c2ecf20Sopenharmony_ci	if (status)
48868c2ecf20Sopenharmony_ci		goto xdr_error;
48878c2ecf20Sopenharmony_ci
48888c2ecf20Sopenharmony_ci	status = verify_attr_len(xdr, savep, attrlen);
48898c2ecf20Sopenharmony_cixdr_error:
48908c2ecf20Sopenharmony_ci	dprintk("%s: xdr returned %d!\n", __func__, -status);
48918c2ecf20Sopenharmony_ci	return status;
48928c2ecf20Sopenharmony_ci}
48938c2ecf20Sopenharmony_ci
48948c2ecf20Sopenharmony_cistatic int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
48958c2ecf20Sopenharmony_ci{
48968c2ecf20Sopenharmony_ci	__be32 *p;
48978c2ecf20Sopenharmony_ci	uint32_t len;
48988c2ecf20Sopenharmony_ci	int status;
48998c2ecf20Sopenharmony_ci
49008c2ecf20Sopenharmony_ci	/* Zero handle first to allow comparisons */
49018c2ecf20Sopenharmony_ci	memset(fh, 0, sizeof(*fh));
49028c2ecf20Sopenharmony_ci
49038c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_GETFH);
49048c2ecf20Sopenharmony_ci	if (status)
49058c2ecf20Sopenharmony_ci		return status;
49068c2ecf20Sopenharmony_ci
49078c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
49088c2ecf20Sopenharmony_ci	if (unlikely(!p))
49098c2ecf20Sopenharmony_ci		return -EIO;
49108c2ecf20Sopenharmony_ci	len = be32_to_cpup(p);
49118c2ecf20Sopenharmony_ci	if (len > NFS4_FHSIZE)
49128c2ecf20Sopenharmony_ci		return -EIO;
49138c2ecf20Sopenharmony_ci	fh->size = len;
49148c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, len);
49158c2ecf20Sopenharmony_ci	if (unlikely(!p))
49168c2ecf20Sopenharmony_ci		return -EIO;
49178c2ecf20Sopenharmony_ci	memcpy(fh->data, p, len);
49188c2ecf20Sopenharmony_ci	return 0;
49198c2ecf20Sopenharmony_ci}
49208c2ecf20Sopenharmony_ci
49218c2ecf20Sopenharmony_cistatic int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
49228c2ecf20Sopenharmony_ci{
49238c2ecf20Sopenharmony_ci	int status;
49248c2ecf20Sopenharmony_ci
49258c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_LINK);
49268c2ecf20Sopenharmony_ci	if (status)
49278c2ecf20Sopenharmony_ci		return status;
49288c2ecf20Sopenharmony_ci	return decode_change_info(xdr, cinfo);
49298c2ecf20Sopenharmony_ci}
49308c2ecf20Sopenharmony_ci
49318c2ecf20Sopenharmony_ci/*
49328c2ecf20Sopenharmony_ci * We create the owner, so we know a proper owner.id length is 4.
49338c2ecf20Sopenharmony_ci */
49348c2ecf20Sopenharmony_cistatic int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
49358c2ecf20Sopenharmony_ci{
49368c2ecf20Sopenharmony_ci	uint64_t offset, length, clientid;
49378c2ecf20Sopenharmony_ci	__be32 *p;
49388c2ecf20Sopenharmony_ci	uint32_t namelen, type;
49398c2ecf20Sopenharmony_ci
49408c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 32); /* read 32 bytes */
49418c2ecf20Sopenharmony_ci	if (unlikely(!p))
49428c2ecf20Sopenharmony_ci		return -EIO;
49438c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &offset); /* read 2 8-byte long words */
49448c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &length);
49458c2ecf20Sopenharmony_ci	type = be32_to_cpup(p++); /* 4 byte read */
49468c2ecf20Sopenharmony_ci	if (fl != NULL) { /* manipulate file lock */
49478c2ecf20Sopenharmony_ci		fl->fl_start = (loff_t)offset;
49488c2ecf20Sopenharmony_ci		fl->fl_end = fl->fl_start + (loff_t)length - 1;
49498c2ecf20Sopenharmony_ci		if (length == ~(uint64_t)0)
49508c2ecf20Sopenharmony_ci			fl->fl_end = OFFSET_MAX;
49518c2ecf20Sopenharmony_ci		fl->fl_type = F_WRLCK;
49528c2ecf20Sopenharmony_ci		if (type & 1)
49538c2ecf20Sopenharmony_ci			fl->fl_type = F_RDLCK;
49548c2ecf20Sopenharmony_ci		fl->fl_pid = 0;
49558c2ecf20Sopenharmony_ci	}
49568c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &clientid); /* read 8 bytes */
49578c2ecf20Sopenharmony_ci	namelen = be32_to_cpup(p); /* read 4 bytes */  /* have read all 32 bytes now */
49588c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, namelen); /* variable size field */
49598c2ecf20Sopenharmony_ci	if (likely(!p))
49608c2ecf20Sopenharmony_ci		return -EIO;
49618c2ecf20Sopenharmony_ci	return -NFS4ERR_DENIED;
49628c2ecf20Sopenharmony_ci}
49638c2ecf20Sopenharmony_ci
49648c2ecf20Sopenharmony_cistatic int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
49658c2ecf20Sopenharmony_ci{
49668c2ecf20Sopenharmony_ci	int status;
49678c2ecf20Sopenharmony_ci
49688c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_LOCK);
49698c2ecf20Sopenharmony_ci	if (status == -EIO)
49708c2ecf20Sopenharmony_ci		goto out;
49718c2ecf20Sopenharmony_ci	if (status == 0) {
49728c2ecf20Sopenharmony_ci		status = decode_lock_stateid(xdr, &res->stateid);
49738c2ecf20Sopenharmony_ci		if (unlikely(status))
49748c2ecf20Sopenharmony_ci			goto out;
49758c2ecf20Sopenharmony_ci	} else if (status == -NFS4ERR_DENIED)
49768c2ecf20Sopenharmony_ci		status = decode_lock_denied(xdr, NULL);
49778c2ecf20Sopenharmony_ci	if (res->open_seqid != NULL)
49788c2ecf20Sopenharmony_ci		nfs_increment_open_seqid(status, res->open_seqid);
49798c2ecf20Sopenharmony_ci	nfs_increment_lock_seqid(status, res->lock_seqid);
49808c2ecf20Sopenharmony_ciout:
49818c2ecf20Sopenharmony_ci	return status;
49828c2ecf20Sopenharmony_ci}
49838c2ecf20Sopenharmony_ci
49848c2ecf20Sopenharmony_cistatic int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res)
49858c2ecf20Sopenharmony_ci{
49868c2ecf20Sopenharmony_ci	int status;
49878c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_LOCKT);
49888c2ecf20Sopenharmony_ci	if (status == -NFS4ERR_DENIED)
49898c2ecf20Sopenharmony_ci		return decode_lock_denied(xdr, res->denied);
49908c2ecf20Sopenharmony_ci	return status;
49918c2ecf20Sopenharmony_ci}
49928c2ecf20Sopenharmony_ci
49938c2ecf20Sopenharmony_cistatic int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
49948c2ecf20Sopenharmony_ci{
49958c2ecf20Sopenharmony_ci	int status;
49968c2ecf20Sopenharmony_ci
49978c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_LOCKU);
49988c2ecf20Sopenharmony_ci	if (status != -EIO)
49998c2ecf20Sopenharmony_ci		nfs_increment_lock_seqid(status, res->seqid);
50008c2ecf20Sopenharmony_ci	if (status == 0)
50018c2ecf20Sopenharmony_ci		status = decode_lock_stateid(xdr, &res->stateid);
50028c2ecf20Sopenharmony_ci	return status;
50038c2ecf20Sopenharmony_ci}
50048c2ecf20Sopenharmony_ci
50058c2ecf20Sopenharmony_cistatic int decode_release_lockowner(struct xdr_stream *xdr)
50068c2ecf20Sopenharmony_ci{
50078c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_RELEASE_LOCKOWNER);
50088c2ecf20Sopenharmony_ci}
50098c2ecf20Sopenharmony_ci
50108c2ecf20Sopenharmony_cistatic int decode_lookup(struct xdr_stream *xdr)
50118c2ecf20Sopenharmony_ci{
50128c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_LOOKUP);
50138c2ecf20Sopenharmony_ci}
50148c2ecf20Sopenharmony_ci
50158c2ecf20Sopenharmony_cistatic int decode_lookupp(struct xdr_stream *xdr)
50168c2ecf20Sopenharmony_ci{
50178c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_LOOKUPP);
50188c2ecf20Sopenharmony_ci}
50198c2ecf20Sopenharmony_ci
50208c2ecf20Sopenharmony_ci/* This is too sick! */
50218c2ecf20Sopenharmony_cistatic int decode_space_limit(struct xdr_stream *xdr,
50228c2ecf20Sopenharmony_ci		unsigned long *pagemod_limit)
50238c2ecf20Sopenharmony_ci{
50248c2ecf20Sopenharmony_ci	__be32 *p;
50258c2ecf20Sopenharmony_ci	uint32_t limit_type, nblocks, blocksize;
50268c2ecf20Sopenharmony_ci	u64 maxsize = 0;
50278c2ecf20Sopenharmony_ci
50288c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 12);
50298c2ecf20Sopenharmony_ci	if (unlikely(!p))
50308c2ecf20Sopenharmony_ci		return -EIO;
50318c2ecf20Sopenharmony_ci	limit_type = be32_to_cpup(p++);
50328c2ecf20Sopenharmony_ci	switch (limit_type) {
50338c2ecf20Sopenharmony_ci	case NFS4_LIMIT_SIZE:
50348c2ecf20Sopenharmony_ci		xdr_decode_hyper(p, &maxsize);
50358c2ecf20Sopenharmony_ci		break;
50368c2ecf20Sopenharmony_ci	case NFS4_LIMIT_BLOCKS:
50378c2ecf20Sopenharmony_ci		nblocks = be32_to_cpup(p++);
50388c2ecf20Sopenharmony_ci		blocksize = be32_to_cpup(p);
50398c2ecf20Sopenharmony_ci		maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
50408c2ecf20Sopenharmony_ci	}
50418c2ecf20Sopenharmony_ci	maxsize >>= PAGE_SHIFT;
50428c2ecf20Sopenharmony_ci	*pagemod_limit = min_t(u64, maxsize, ULONG_MAX);
50438c2ecf20Sopenharmony_ci	return 0;
50448c2ecf20Sopenharmony_ci}
50458c2ecf20Sopenharmony_ci
50468c2ecf20Sopenharmony_cistatic int decode_rw_delegation(struct xdr_stream *xdr,
50478c2ecf20Sopenharmony_ci		uint32_t delegation_type,
50488c2ecf20Sopenharmony_ci		struct nfs_openres *res)
50498c2ecf20Sopenharmony_ci{
50508c2ecf20Sopenharmony_ci	__be32 *p;
50518c2ecf20Sopenharmony_ci	int status;
50528c2ecf20Sopenharmony_ci
50538c2ecf20Sopenharmony_ci	status = decode_delegation_stateid(xdr, &res->delegation);
50548c2ecf20Sopenharmony_ci	if (unlikely(status))
50558c2ecf20Sopenharmony_ci		return status;
50568c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
50578c2ecf20Sopenharmony_ci	if (unlikely(!p))
50588c2ecf20Sopenharmony_ci		return -EIO;
50598c2ecf20Sopenharmony_ci	res->do_recall = be32_to_cpup(p);
50608c2ecf20Sopenharmony_ci
50618c2ecf20Sopenharmony_ci	switch (delegation_type) {
50628c2ecf20Sopenharmony_ci	case NFS4_OPEN_DELEGATE_READ:
50638c2ecf20Sopenharmony_ci		res->delegation_type = FMODE_READ;
50648c2ecf20Sopenharmony_ci		break;
50658c2ecf20Sopenharmony_ci	case NFS4_OPEN_DELEGATE_WRITE:
50668c2ecf20Sopenharmony_ci		res->delegation_type = FMODE_WRITE|FMODE_READ;
50678c2ecf20Sopenharmony_ci		if (decode_space_limit(xdr, &res->pagemod_limit) < 0)
50688c2ecf20Sopenharmony_ci				return -EIO;
50698c2ecf20Sopenharmony_ci	}
50708c2ecf20Sopenharmony_ci	return decode_ace(xdr, NULL);
50718c2ecf20Sopenharmony_ci}
50728c2ecf20Sopenharmony_ci
50738c2ecf20Sopenharmony_cistatic int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
50748c2ecf20Sopenharmony_ci{
50758c2ecf20Sopenharmony_ci	__be32 *p;
50768c2ecf20Sopenharmony_ci	uint32_t why_no_delegation;
50778c2ecf20Sopenharmony_ci
50788c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
50798c2ecf20Sopenharmony_ci	if (unlikely(!p))
50808c2ecf20Sopenharmony_ci		return -EIO;
50818c2ecf20Sopenharmony_ci	why_no_delegation = be32_to_cpup(p);
50828c2ecf20Sopenharmony_ci	switch (why_no_delegation) {
50838c2ecf20Sopenharmony_ci		case WND4_CONTENTION:
50848c2ecf20Sopenharmony_ci		case WND4_RESOURCE:
50858c2ecf20Sopenharmony_ci			xdr_inline_decode(xdr, 4);
50868c2ecf20Sopenharmony_ci			/* Ignore for now */
50878c2ecf20Sopenharmony_ci	}
50888c2ecf20Sopenharmony_ci	return 0;
50898c2ecf20Sopenharmony_ci}
50908c2ecf20Sopenharmony_ci
50918c2ecf20Sopenharmony_cistatic int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
50928c2ecf20Sopenharmony_ci{
50938c2ecf20Sopenharmony_ci	__be32 *p;
50948c2ecf20Sopenharmony_ci	uint32_t delegation_type;
50958c2ecf20Sopenharmony_ci
50968c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
50978c2ecf20Sopenharmony_ci	if (unlikely(!p))
50988c2ecf20Sopenharmony_ci		return -EIO;
50998c2ecf20Sopenharmony_ci	delegation_type = be32_to_cpup(p);
51008c2ecf20Sopenharmony_ci	res->delegation_type = 0;
51018c2ecf20Sopenharmony_ci	switch (delegation_type) {
51028c2ecf20Sopenharmony_ci	case NFS4_OPEN_DELEGATE_NONE:
51038c2ecf20Sopenharmony_ci		return 0;
51048c2ecf20Sopenharmony_ci	case NFS4_OPEN_DELEGATE_READ:
51058c2ecf20Sopenharmony_ci	case NFS4_OPEN_DELEGATE_WRITE:
51068c2ecf20Sopenharmony_ci		return decode_rw_delegation(xdr, delegation_type, res);
51078c2ecf20Sopenharmony_ci	case NFS4_OPEN_DELEGATE_NONE_EXT:
51088c2ecf20Sopenharmony_ci		return decode_no_delegation(xdr, res);
51098c2ecf20Sopenharmony_ci	}
51108c2ecf20Sopenharmony_ci	return -EIO;
51118c2ecf20Sopenharmony_ci}
51128c2ecf20Sopenharmony_ci
51138c2ecf20Sopenharmony_cistatic int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
51148c2ecf20Sopenharmony_ci{
51158c2ecf20Sopenharmony_ci	__be32 *p;
51168c2ecf20Sopenharmony_ci	uint32_t savewords, bmlen, i;
51178c2ecf20Sopenharmony_ci	int status;
51188c2ecf20Sopenharmony_ci
51198c2ecf20Sopenharmony_ci	if (!__decode_op_hdr(xdr, OP_OPEN, &status))
51208c2ecf20Sopenharmony_ci		return status;
51218c2ecf20Sopenharmony_ci	nfs_increment_open_seqid(status, res->seqid);
51228c2ecf20Sopenharmony_ci	if (status)
51238c2ecf20Sopenharmony_ci		return status;
51248c2ecf20Sopenharmony_ci	status = decode_open_stateid(xdr, &res->stateid);
51258c2ecf20Sopenharmony_ci	if (unlikely(status))
51268c2ecf20Sopenharmony_ci		return status;
51278c2ecf20Sopenharmony_ci
51288c2ecf20Sopenharmony_ci	decode_change_info(xdr, &res->cinfo);
51298c2ecf20Sopenharmony_ci
51308c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
51318c2ecf20Sopenharmony_ci	if (unlikely(!p))
51328c2ecf20Sopenharmony_ci		return -EIO;
51338c2ecf20Sopenharmony_ci	res->rflags = be32_to_cpup(p++);
51348c2ecf20Sopenharmony_ci	bmlen = be32_to_cpup(p);
51358c2ecf20Sopenharmony_ci	if (bmlen > 10)
51368c2ecf20Sopenharmony_ci		goto xdr_error;
51378c2ecf20Sopenharmony_ci
51388c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, bmlen << 2);
51398c2ecf20Sopenharmony_ci	if (unlikely(!p))
51408c2ecf20Sopenharmony_ci		return -EIO;
51418c2ecf20Sopenharmony_ci	savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE);
51428c2ecf20Sopenharmony_ci	for (i = 0; i < savewords; ++i)
51438c2ecf20Sopenharmony_ci		res->attrset[i] = be32_to_cpup(p++);
51448c2ecf20Sopenharmony_ci	for (; i < NFS4_BITMAP_SIZE; i++)
51458c2ecf20Sopenharmony_ci		res->attrset[i] = 0;
51468c2ecf20Sopenharmony_ci
51478c2ecf20Sopenharmony_ci	return decode_delegation(xdr, res);
51488c2ecf20Sopenharmony_cixdr_error:
51498c2ecf20Sopenharmony_ci	dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen);
51508c2ecf20Sopenharmony_ci	return -EIO;
51518c2ecf20Sopenharmony_ci}
51528c2ecf20Sopenharmony_ci
51538c2ecf20Sopenharmony_cistatic int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res)
51548c2ecf20Sopenharmony_ci{
51558c2ecf20Sopenharmony_ci	int status;
51568c2ecf20Sopenharmony_ci
51578c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
51588c2ecf20Sopenharmony_ci	if (status != -EIO)
51598c2ecf20Sopenharmony_ci		nfs_increment_open_seqid(status, res->seqid);
51608c2ecf20Sopenharmony_ci	if (!status)
51618c2ecf20Sopenharmony_ci		status = decode_open_stateid(xdr, &res->stateid);
51628c2ecf20Sopenharmony_ci	return status;
51638c2ecf20Sopenharmony_ci}
51648c2ecf20Sopenharmony_ci
51658c2ecf20Sopenharmony_cistatic int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res)
51668c2ecf20Sopenharmony_ci{
51678c2ecf20Sopenharmony_ci	int status;
51688c2ecf20Sopenharmony_ci
51698c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE);
51708c2ecf20Sopenharmony_ci	if (status != -EIO)
51718c2ecf20Sopenharmony_ci		nfs_increment_open_seqid(status, res->seqid);
51728c2ecf20Sopenharmony_ci	if (!status)
51738c2ecf20Sopenharmony_ci		status = decode_open_stateid(xdr, &res->stateid);
51748c2ecf20Sopenharmony_ci	return status;
51758c2ecf20Sopenharmony_ci}
51768c2ecf20Sopenharmony_ci
51778c2ecf20Sopenharmony_cistatic int decode_putfh(struct xdr_stream *xdr)
51788c2ecf20Sopenharmony_ci{
51798c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_PUTFH);
51808c2ecf20Sopenharmony_ci}
51818c2ecf20Sopenharmony_ci
51828c2ecf20Sopenharmony_cistatic int decode_putrootfh(struct xdr_stream *xdr)
51838c2ecf20Sopenharmony_ci{
51848c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_PUTROOTFH);
51858c2ecf20Sopenharmony_ci}
51868c2ecf20Sopenharmony_ci
51878c2ecf20Sopenharmony_cistatic int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req,
51888c2ecf20Sopenharmony_ci		       struct nfs_pgio_res *res)
51898c2ecf20Sopenharmony_ci{
51908c2ecf20Sopenharmony_ci	__be32 *p;
51918c2ecf20Sopenharmony_ci	uint32_t count, eof, recvd;
51928c2ecf20Sopenharmony_ci	int status;
51938c2ecf20Sopenharmony_ci
51948c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_READ);
51958c2ecf20Sopenharmony_ci	if (status)
51968c2ecf20Sopenharmony_ci		return status;
51978c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
51988c2ecf20Sopenharmony_ci	if (unlikely(!p))
51998c2ecf20Sopenharmony_ci		return -EIO;
52008c2ecf20Sopenharmony_ci	eof = be32_to_cpup(p++);
52018c2ecf20Sopenharmony_ci	count = be32_to_cpup(p);
52028c2ecf20Sopenharmony_ci	recvd = xdr_read_pages(xdr, count);
52038c2ecf20Sopenharmony_ci	if (count > recvd) {
52048c2ecf20Sopenharmony_ci		dprintk("NFS: server cheating in read reply: "
52058c2ecf20Sopenharmony_ci				"count %u > recvd %u\n", count, recvd);
52068c2ecf20Sopenharmony_ci		count = recvd;
52078c2ecf20Sopenharmony_ci		eof = 0;
52088c2ecf20Sopenharmony_ci	}
52098c2ecf20Sopenharmony_ci	res->eof = eof;
52108c2ecf20Sopenharmony_ci	res->count = count;
52118c2ecf20Sopenharmony_ci	return 0;
52128c2ecf20Sopenharmony_ci}
52138c2ecf20Sopenharmony_ci
52148c2ecf20Sopenharmony_cistatic int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir)
52158c2ecf20Sopenharmony_ci{
52168c2ecf20Sopenharmony_ci	int		status;
52178c2ecf20Sopenharmony_ci	__be32		verf[2];
52188c2ecf20Sopenharmony_ci
52198c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_READDIR);
52208c2ecf20Sopenharmony_ci	if (!status)
52218c2ecf20Sopenharmony_ci		status = decode_verifier(xdr, readdir->verifier.data);
52228c2ecf20Sopenharmony_ci	if (unlikely(status))
52238c2ecf20Sopenharmony_ci		return status;
52248c2ecf20Sopenharmony_ci	memcpy(verf, readdir->verifier.data, sizeof(verf));
52258c2ecf20Sopenharmony_ci	dprintk("%s: verifier = %08x:%08x\n",
52268c2ecf20Sopenharmony_ci			__func__, verf[0], verf[1]);
52278c2ecf20Sopenharmony_ci	return xdr_read_pages(xdr, xdr->buf->page_len);
52288c2ecf20Sopenharmony_ci}
52298c2ecf20Sopenharmony_ci
52308c2ecf20Sopenharmony_cistatic int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
52318c2ecf20Sopenharmony_ci{
52328c2ecf20Sopenharmony_ci	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
52338c2ecf20Sopenharmony_ci	u32 len, recvd;
52348c2ecf20Sopenharmony_ci	__be32 *p;
52358c2ecf20Sopenharmony_ci	int status;
52368c2ecf20Sopenharmony_ci
52378c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_READLINK);
52388c2ecf20Sopenharmony_ci	if (status)
52398c2ecf20Sopenharmony_ci		return status;
52408c2ecf20Sopenharmony_ci
52418c2ecf20Sopenharmony_ci	/* Convert length of symlink */
52428c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
52438c2ecf20Sopenharmony_ci	if (unlikely(!p))
52448c2ecf20Sopenharmony_ci		return -EIO;
52458c2ecf20Sopenharmony_ci	len = be32_to_cpup(p);
52468c2ecf20Sopenharmony_ci	if (len >= rcvbuf->page_len || len <= 0) {
52478c2ecf20Sopenharmony_ci		dprintk("nfs: server returned giant symlink!\n");
52488c2ecf20Sopenharmony_ci		return -ENAMETOOLONG;
52498c2ecf20Sopenharmony_ci	}
52508c2ecf20Sopenharmony_ci	recvd = xdr_read_pages(xdr, len);
52518c2ecf20Sopenharmony_ci	if (recvd < len) {
52528c2ecf20Sopenharmony_ci		dprintk("NFS: server cheating in readlink reply: "
52538c2ecf20Sopenharmony_ci				"count %u > recvd %u\n", len, recvd);
52548c2ecf20Sopenharmony_ci		return -EIO;
52558c2ecf20Sopenharmony_ci	}
52568c2ecf20Sopenharmony_ci	/*
52578c2ecf20Sopenharmony_ci	 * The XDR encode routine has set things up so that
52588c2ecf20Sopenharmony_ci	 * the link text will be copied directly into the
52598c2ecf20Sopenharmony_ci	 * buffer.  We just have to do overflow-checking,
52608c2ecf20Sopenharmony_ci	 * and null-terminate the text (the VFS expects
52618c2ecf20Sopenharmony_ci	 * null-termination).
52628c2ecf20Sopenharmony_ci	 */
52638c2ecf20Sopenharmony_ci	xdr_terminate_string(rcvbuf, len);
52648c2ecf20Sopenharmony_ci	return 0;
52658c2ecf20Sopenharmony_ci}
52668c2ecf20Sopenharmony_ci
52678c2ecf20Sopenharmony_cistatic int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
52688c2ecf20Sopenharmony_ci{
52698c2ecf20Sopenharmony_ci	int status;
52708c2ecf20Sopenharmony_ci
52718c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_REMOVE);
52728c2ecf20Sopenharmony_ci	if (status)
52738c2ecf20Sopenharmony_ci		goto out;
52748c2ecf20Sopenharmony_ci	status = decode_change_info(xdr, cinfo);
52758c2ecf20Sopenharmony_ciout:
52768c2ecf20Sopenharmony_ci	return status;
52778c2ecf20Sopenharmony_ci}
52788c2ecf20Sopenharmony_ci
52798c2ecf20Sopenharmony_cistatic int decode_rename(struct xdr_stream *xdr, struct nfs4_change_info *old_cinfo,
52808c2ecf20Sopenharmony_ci	      struct nfs4_change_info *new_cinfo)
52818c2ecf20Sopenharmony_ci{
52828c2ecf20Sopenharmony_ci	int status;
52838c2ecf20Sopenharmony_ci
52848c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_RENAME);
52858c2ecf20Sopenharmony_ci	if (status)
52868c2ecf20Sopenharmony_ci		goto out;
52878c2ecf20Sopenharmony_ci	if ((status = decode_change_info(xdr, old_cinfo)))
52888c2ecf20Sopenharmony_ci		goto out;
52898c2ecf20Sopenharmony_ci	status = decode_change_info(xdr, new_cinfo);
52908c2ecf20Sopenharmony_ciout:
52918c2ecf20Sopenharmony_ci	return status;
52928c2ecf20Sopenharmony_ci}
52938c2ecf20Sopenharmony_ci
52948c2ecf20Sopenharmony_cistatic int decode_renew(struct xdr_stream *xdr)
52958c2ecf20Sopenharmony_ci{
52968c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_RENEW);
52978c2ecf20Sopenharmony_ci}
52988c2ecf20Sopenharmony_ci
52998c2ecf20Sopenharmony_cistatic int
53008c2ecf20Sopenharmony_cidecode_restorefh(struct xdr_stream *xdr)
53018c2ecf20Sopenharmony_ci{
53028c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_RESTOREFH);
53038c2ecf20Sopenharmony_ci}
53048c2ecf20Sopenharmony_ci
53058c2ecf20Sopenharmony_cistatic int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
53068c2ecf20Sopenharmony_ci			 struct nfs_getaclres *res)
53078c2ecf20Sopenharmony_ci{
53088c2ecf20Sopenharmony_ci	unsigned int savep;
53098c2ecf20Sopenharmony_ci	uint32_t attrlen,
53108c2ecf20Sopenharmony_ci		 bitmap[3] = {0};
53118c2ecf20Sopenharmony_ci	int status;
53128c2ecf20Sopenharmony_ci
53138c2ecf20Sopenharmony_ci	res->acl_len = 0;
53148c2ecf20Sopenharmony_ci	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
53158c2ecf20Sopenharmony_ci		goto out;
53168c2ecf20Sopenharmony_ci
53178c2ecf20Sopenharmony_ci	xdr_enter_page(xdr, xdr->buf->page_len);
53188c2ecf20Sopenharmony_ci
53198c2ecf20Sopenharmony_ci	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
53208c2ecf20Sopenharmony_ci		goto out;
53218c2ecf20Sopenharmony_ci	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
53228c2ecf20Sopenharmony_ci		goto out;
53238c2ecf20Sopenharmony_ci
53248c2ecf20Sopenharmony_ci	if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
53258c2ecf20Sopenharmony_ci		return -EIO;
53268c2ecf20Sopenharmony_ci	if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
53278c2ecf20Sopenharmony_ci
53288c2ecf20Sopenharmony_ci		/* The bitmap (xdr len + bitmaps) and the attr xdr len words
53298c2ecf20Sopenharmony_ci		 * are stored with the acl data to handle the problem of
53308c2ecf20Sopenharmony_ci		 * variable length bitmaps.*/
53318c2ecf20Sopenharmony_ci		res->acl_data_offset = xdr_page_pos(xdr);
53328c2ecf20Sopenharmony_ci		res->acl_len = attrlen;
53338c2ecf20Sopenharmony_ci
53348c2ecf20Sopenharmony_ci		/* Check for receive buffer overflow */
53358c2ecf20Sopenharmony_ci		if (res->acl_len > (xdr->nwords << 2) ||
53368c2ecf20Sopenharmony_ci		    res->acl_len + res->acl_data_offset > xdr->buf->page_len) {
53378c2ecf20Sopenharmony_ci			res->acl_flags |= NFS4_ACL_TRUNC;
53388c2ecf20Sopenharmony_ci			dprintk("NFS: acl reply: attrlen %u > page_len %u\n",
53398c2ecf20Sopenharmony_ci					attrlen, xdr->nwords << 2);
53408c2ecf20Sopenharmony_ci		}
53418c2ecf20Sopenharmony_ci	} else
53428c2ecf20Sopenharmony_ci		status = -EOPNOTSUPP;
53438c2ecf20Sopenharmony_ci
53448c2ecf20Sopenharmony_ciout:
53458c2ecf20Sopenharmony_ci	return status;
53468c2ecf20Sopenharmony_ci}
53478c2ecf20Sopenharmony_ci
53488c2ecf20Sopenharmony_cistatic int
53498c2ecf20Sopenharmony_cidecode_savefh(struct xdr_stream *xdr)
53508c2ecf20Sopenharmony_ci{
53518c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_SAVEFH);
53528c2ecf20Sopenharmony_ci}
53538c2ecf20Sopenharmony_ci
53548c2ecf20Sopenharmony_cistatic int decode_setattr(struct xdr_stream *xdr)
53558c2ecf20Sopenharmony_ci{
53568c2ecf20Sopenharmony_ci	int status;
53578c2ecf20Sopenharmony_ci
53588c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_SETATTR);
53598c2ecf20Sopenharmony_ci	if (status)
53608c2ecf20Sopenharmony_ci		return status;
53618c2ecf20Sopenharmony_ci	if (decode_bitmap4(xdr, NULL, 0) >= 0)
53628c2ecf20Sopenharmony_ci		return 0;
53638c2ecf20Sopenharmony_ci	return -EIO;
53648c2ecf20Sopenharmony_ci}
53658c2ecf20Sopenharmony_ci
53668c2ecf20Sopenharmony_cistatic int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_res *res)
53678c2ecf20Sopenharmony_ci{
53688c2ecf20Sopenharmony_ci	__be32 *p;
53698c2ecf20Sopenharmony_ci	uint32_t opnum;
53708c2ecf20Sopenharmony_ci	int32_t nfserr;
53718c2ecf20Sopenharmony_ci
53728c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
53738c2ecf20Sopenharmony_ci	if (unlikely(!p))
53748c2ecf20Sopenharmony_ci		return -EIO;
53758c2ecf20Sopenharmony_ci	opnum = be32_to_cpup(p++);
53768c2ecf20Sopenharmony_ci	if (opnum != OP_SETCLIENTID) {
53778c2ecf20Sopenharmony_ci		dprintk("nfs: decode_setclientid: Server returned operation"
53788c2ecf20Sopenharmony_ci			" %d\n", opnum);
53798c2ecf20Sopenharmony_ci		return -EIO;
53808c2ecf20Sopenharmony_ci	}
53818c2ecf20Sopenharmony_ci	nfserr = be32_to_cpup(p);
53828c2ecf20Sopenharmony_ci	if (nfserr == NFS_OK) {
53838c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE);
53848c2ecf20Sopenharmony_ci		if (unlikely(!p))
53858c2ecf20Sopenharmony_ci			return -EIO;
53868c2ecf20Sopenharmony_ci		p = xdr_decode_hyper(p, &res->clientid);
53878c2ecf20Sopenharmony_ci		memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE);
53888c2ecf20Sopenharmony_ci	} else if (nfserr == NFSERR_CLID_INUSE) {
53898c2ecf20Sopenharmony_ci		uint32_t len;
53908c2ecf20Sopenharmony_ci
53918c2ecf20Sopenharmony_ci		/* skip netid string */
53928c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
53938c2ecf20Sopenharmony_ci		if (unlikely(!p))
53948c2ecf20Sopenharmony_ci			return -EIO;
53958c2ecf20Sopenharmony_ci		len = be32_to_cpup(p);
53968c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, len);
53978c2ecf20Sopenharmony_ci		if (unlikely(!p))
53988c2ecf20Sopenharmony_ci			return -EIO;
53998c2ecf20Sopenharmony_ci
54008c2ecf20Sopenharmony_ci		/* skip uaddr string */
54018c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
54028c2ecf20Sopenharmony_ci		if (unlikely(!p))
54038c2ecf20Sopenharmony_ci			return -EIO;
54048c2ecf20Sopenharmony_ci		len = be32_to_cpup(p);
54058c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, len);
54068c2ecf20Sopenharmony_ci		if (unlikely(!p))
54078c2ecf20Sopenharmony_ci			return -EIO;
54088c2ecf20Sopenharmony_ci		return -NFSERR_CLID_INUSE;
54098c2ecf20Sopenharmony_ci	} else
54108c2ecf20Sopenharmony_ci		return nfs4_stat_to_errno(nfserr);
54118c2ecf20Sopenharmony_ci
54128c2ecf20Sopenharmony_ci	return 0;
54138c2ecf20Sopenharmony_ci}
54148c2ecf20Sopenharmony_ci
54158c2ecf20Sopenharmony_cistatic int decode_setclientid_confirm(struct xdr_stream *xdr)
54168c2ecf20Sopenharmony_ci{
54178c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_SETCLIENTID_CONFIRM);
54188c2ecf20Sopenharmony_ci}
54198c2ecf20Sopenharmony_ci
54208c2ecf20Sopenharmony_cistatic int decode_write(struct xdr_stream *xdr, struct nfs_pgio_res *res)
54218c2ecf20Sopenharmony_ci{
54228c2ecf20Sopenharmony_ci	__be32 *p;
54238c2ecf20Sopenharmony_ci	int status;
54248c2ecf20Sopenharmony_ci
54258c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_WRITE);
54268c2ecf20Sopenharmony_ci	if (status)
54278c2ecf20Sopenharmony_ci		return status;
54288c2ecf20Sopenharmony_ci
54298c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
54308c2ecf20Sopenharmony_ci	if (unlikely(!p))
54318c2ecf20Sopenharmony_ci		return -EIO;
54328c2ecf20Sopenharmony_ci	res->count = be32_to_cpup(p++);
54338c2ecf20Sopenharmony_ci	res->verf->committed = be32_to_cpup(p++);
54348c2ecf20Sopenharmony_ci	return decode_write_verifier(xdr, &res->verf->verifier);
54358c2ecf20Sopenharmony_ci}
54368c2ecf20Sopenharmony_ci
54378c2ecf20Sopenharmony_cistatic int decode_delegreturn(struct xdr_stream *xdr)
54388c2ecf20Sopenharmony_ci{
54398c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_DELEGRETURN);
54408c2ecf20Sopenharmony_ci}
54418c2ecf20Sopenharmony_ci
54428c2ecf20Sopenharmony_cistatic int decode_secinfo_gss(struct xdr_stream *xdr,
54438c2ecf20Sopenharmony_ci			      struct nfs4_secinfo4 *flavor)
54448c2ecf20Sopenharmony_ci{
54458c2ecf20Sopenharmony_ci	u32 oid_len;
54468c2ecf20Sopenharmony_ci	__be32 *p;
54478c2ecf20Sopenharmony_ci
54488c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
54498c2ecf20Sopenharmony_ci	if (unlikely(!p))
54508c2ecf20Sopenharmony_ci		return -EIO;
54518c2ecf20Sopenharmony_ci	oid_len = be32_to_cpup(p);
54528c2ecf20Sopenharmony_ci	if (oid_len > GSS_OID_MAX_LEN)
54538c2ecf20Sopenharmony_ci		return -EINVAL;
54548c2ecf20Sopenharmony_ci
54558c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, oid_len);
54568c2ecf20Sopenharmony_ci	if (unlikely(!p))
54578c2ecf20Sopenharmony_ci		return -EIO;
54588c2ecf20Sopenharmony_ci	memcpy(flavor->flavor_info.oid.data, p, oid_len);
54598c2ecf20Sopenharmony_ci	flavor->flavor_info.oid.len = oid_len;
54608c2ecf20Sopenharmony_ci
54618c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
54628c2ecf20Sopenharmony_ci	if (unlikely(!p))
54638c2ecf20Sopenharmony_ci		return -EIO;
54648c2ecf20Sopenharmony_ci	flavor->flavor_info.qop = be32_to_cpup(p++);
54658c2ecf20Sopenharmony_ci	flavor->flavor_info.service = be32_to_cpup(p);
54668c2ecf20Sopenharmony_ci
54678c2ecf20Sopenharmony_ci	return 0;
54688c2ecf20Sopenharmony_ci}
54698c2ecf20Sopenharmony_ci
54708c2ecf20Sopenharmony_cistatic int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
54718c2ecf20Sopenharmony_ci{
54728c2ecf20Sopenharmony_ci	struct nfs4_secinfo4 *sec_flavor;
54738c2ecf20Sopenharmony_ci	unsigned int i, num_flavors;
54748c2ecf20Sopenharmony_ci	int status;
54758c2ecf20Sopenharmony_ci	__be32 *p;
54768c2ecf20Sopenharmony_ci
54778c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
54788c2ecf20Sopenharmony_ci	if (unlikely(!p))
54798c2ecf20Sopenharmony_ci		return -EIO;
54808c2ecf20Sopenharmony_ci
54818c2ecf20Sopenharmony_ci	res->flavors->num_flavors = 0;
54828c2ecf20Sopenharmony_ci	num_flavors = be32_to_cpup(p);
54838c2ecf20Sopenharmony_ci
54848c2ecf20Sopenharmony_ci	for (i = 0; i < num_flavors; i++) {
54858c2ecf20Sopenharmony_ci		sec_flavor = &res->flavors->flavors[i];
54868c2ecf20Sopenharmony_ci		if ((char *)&sec_flavor[1] - (char *)res->flavors > PAGE_SIZE)
54878c2ecf20Sopenharmony_ci			break;
54888c2ecf20Sopenharmony_ci
54898c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
54908c2ecf20Sopenharmony_ci		if (unlikely(!p))
54918c2ecf20Sopenharmony_ci			return -EIO;
54928c2ecf20Sopenharmony_ci		sec_flavor->flavor = be32_to_cpup(p);
54938c2ecf20Sopenharmony_ci
54948c2ecf20Sopenharmony_ci		if (sec_flavor->flavor == RPC_AUTH_GSS) {
54958c2ecf20Sopenharmony_ci			status = decode_secinfo_gss(xdr, sec_flavor);
54968c2ecf20Sopenharmony_ci			if (status)
54978c2ecf20Sopenharmony_ci				goto out;
54988c2ecf20Sopenharmony_ci		}
54998c2ecf20Sopenharmony_ci		res->flavors->num_flavors++;
55008c2ecf20Sopenharmony_ci	}
55018c2ecf20Sopenharmony_ci
55028c2ecf20Sopenharmony_ci	status = 0;
55038c2ecf20Sopenharmony_ciout:
55048c2ecf20Sopenharmony_ci	return status;
55058c2ecf20Sopenharmony_ci}
55068c2ecf20Sopenharmony_ci
55078c2ecf20Sopenharmony_cistatic int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
55088c2ecf20Sopenharmony_ci{
55098c2ecf20Sopenharmony_ci	int status = decode_op_hdr(xdr, OP_SECINFO);
55108c2ecf20Sopenharmony_ci	if (status)
55118c2ecf20Sopenharmony_ci		return status;
55128c2ecf20Sopenharmony_ci	return decode_secinfo_common(xdr, res);
55138c2ecf20Sopenharmony_ci}
55148c2ecf20Sopenharmony_ci
55158c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
55168c2ecf20Sopenharmony_cistatic int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
55178c2ecf20Sopenharmony_ci{
55188c2ecf20Sopenharmony_ci	int status = decode_op_hdr(xdr, OP_SECINFO_NO_NAME);
55198c2ecf20Sopenharmony_ci	if (status)
55208c2ecf20Sopenharmony_ci		return status;
55218c2ecf20Sopenharmony_ci	return decode_secinfo_common(xdr, res);
55228c2ecf20Sopenharmony_ci}
55238c2ecf20Sopenharmony_ci
55248c2ecf20Sopenharmony_cistatic int decode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map)
55258c2ecf20Sopenharmony_ci{
55268c2ecf20Sopenharmony_ci	__be32 *p;
55278c2ecf20Sopenharmony_ci	uint32_t bitmap_words;
55288c2ecf20Sopenharmony_ci	unsigned int i;
55298c2ecf20Sopenharmony_ci
55308c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
55318c2ecf20Sopenharmony_ci	if (!p)
55328c2ecf20Sopenharmony_ci		return -EIO;
55338c2ecf20Sopenharmony_ci	bitmap_words = be32_to_cpup(p++);
55348c2ecf20Sopenharmony_ci	if (bitmap_words > NFS4_OP_MAP_NUM_WORDS)
55358c2ecf20Sopenharmony_ci		return -EIO;
55368c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4 * bitmap_words);
55378c2ecf20Sopenharmony_ci	for (i = 0; i < bitmap_words; i++)
55388c2ecf20Sopenharmony_ci		op_map->u.words[i] = be32_to_cpup(p++);
55398c2ecf20Sopenharmony_ci
55408c2ecf20Sopenharmony_ci	return 0;
55418c2ecf20Sopenharmony_ci}
55428c2ecf20Sopenharmony_ci
55438c2ecf20Sopenharmony_cistatic int decode_exchange_id(struct xdr_stream *xdr,
55448c2ecf20Sopenharmony_ci			      struct nfs41_exchange_id_res *res)
55458c2ecf20Sopenharmony_ci{
55468c2ecf20Sopenharmony_ci	__be32 *p;
55478c2ecf20Sopenharmony_ci	uint32_t dummy;
55488c2ecf20Sopenharmony_ci	char *dummy_str;
55498c2ecf20Sopenharmony_ci	int status;
55508c2ecf20Sopenharmony_ci	uint32_t impl_id_count;
55518c2ecf20Sopenharmony_ci
55528c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
55538c2ecf20Sopenharmony_ci	if (status)
55548c2ecf20Sopenharmony_ci		return status;
55558c2ecf20Sopenharmony_ci
55568c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
55578c2ecf20Sopenharmony_ci	if (unlikely(!p))
55588c2ecf20Sopenharmony_ci		return -EIO;
55598c2ecf20Sopenharmony_ci	xdr_decode_hyper(p, &res->clientid);
55608c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 12);
55618c2ecf20Sopenharmony_ci	if (unlikely(!p))
55628c2ecf20Sopenharmony_ci		return -EIO;
55638c2ecf20Sopenharmony_ci	res->seqid = be32_to_cpup(p++);
55648c2ecf20Sopenharmony_ci	res->flags = be32_to_cpup(p++);
55658c2ecf20Sopenharmony_ci
55668c2ecf20Sopenharmony_ci	res->state_protect.how = be32_to_cpup(p);
55678c2ecf20Sopenharmony_ci	switch (res->state_protect.how) {
55688c2ecf20Sopenharmony_ci	case SP4_NONE:
55698c2ecf20Sopenharmony_ci		break;
55708c2ecf20Sopenharmony_ci	case SP4_MACH_CRED:
55718c2ecf20Sopenharmony_ci		status = decode_op_map(xdr, &res->state_protect.enforce);
55728c2ecf20Sopenharmony_ci		if (status)
55738c2ecf20Sopenharmony_ci			return status;
55748c2ecf20Sopenharmony_ci		status = decode_op_map(xdr, &res->state_protect.allow);
55758c2ecf20Sopenharmony_ci		if (status)
55768c2ecf20Sopenharmony_ci			return status;
55778c2ecf20Sopenharmony_ci		break;
55788c2ecf20Sopenharmony_ci	default:
55798c2ecf20Sopenharmony_ci		WARN_ON_ONCE(1);
55808c2ecf20Sopenharmony_ci		return -EIO;
55818c2ecf20Sopenharmony_ci	}
55828c2ecf20Sopenharmony_ci
55838c2ecf20Sopenharmony_ci	/* server_owner4.so_minor_id */
55848c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
55858c2ecf20Sopenharmony_ci	if (unlikely(!p))
55868c2ecf20Sopenharmony_ci		return -EIO;
55878c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &res->server_owner->minor_id);
55888c2ecf20Sopenharmony_ci
55898c2ecf20Sopenharmony_ci	/* server_owner4.so_major_id */
55908c2ecf20Sopenharmony_ci	status = decode_opaque_inline(xdr, &dummy, &dummy_str);
55918c2ecf20Sopenharmony_ci	if (unlikely(status))
55928c2ecf20Sopenharmony_ci		return status;
55938c2ecf20Sopenharmony_ci	memcpy(res->server_owner->major_id, dummy_str, dummy);
55948c2ecf20Sopenharmony_ci	res->server_owner->major_id_sz = dummy;
55958c2ecf20Sopenharmony_ci
55968c2ecf20Sopenharmony_ci	/* server_scope4 */
55978c2ecf20Sopenharmony_ci	status = decode_opaque_inline(xdr, &dummy, &dummy_str);
55988c2ecf20Sopenharmony_ci	if (unlikely(status))
55998c2ecf20Sopenharmony_ci		return status;
56008c2ecf20Sopenharmony_ci	memcpy(res->server_scope->server_scope, dummy_str, dummy);
56018c2ecf20Sopenharmony_ci	res->server_scope->server_scope_sz = dummy;
56028c2ecf20Sopenharmony_ci
56038c2ecf20Sopenharmony_ci	/* Implementation Id */
56048c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
56058c2ecf20Sopenharmony_ci	if (unlikely(!p))
56068c2ecf20Sopenharmony_ci		return -EIO;
56078c2ecf20Sopenharmony_ci	impl_id_count = be32_to_cpup(p++);
56088c2ecf20Sopenharmony_ci
56098c2ecf20Sopenharmony_ci	if (impl_id_count) {
56108c2ecf20Sopenharmony_ci		/* nii_domain */
56118c2ecf20Sopenharmony_ci		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
56128c2ecf20Sopenharmony_ci		if (unlikely(status))
56138c2ecf20Sopenharmony_ci			return status;
56148c2ecf20Sopenharmony_ci		memcpy(res->impl_id->domain, dummy_str, dummy);
56158c2ecf20Sopenharmony_ci
56168c2ecf20Sopenharmony_ci		/* nii_name */
56178c2ecf20Sopenharmony_ci		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
56188c2ecf20Sopenharmony_ci		if (unlikely(status))
56198c2ecf20Sopenharmony_ci			return status;
56208c2ecf20Sopenharmony_ci		memcpy(res->impl_id->name, dummy_str, dummy);
56218c2ecf20Sopenharmony_ci
56228c2ecf20Sopenharmony_ci		/* nii_date */
56238c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 12);
56248c2ecf20Sopenharmony_ci		if (unlikely(!p))
56258c2ecf20Sopenharmony_ci			return -EIO;
56268c2ecf20Sopenharmony_ci		p = xdr_decode_hyper(p, &res->impl_id->date.seconds);
56278c2ecf20Sopenharmony_ci		res->impl_id->date.nseconds = be32_to_cpup(p);
56288c2ecf20Sopenharmony_ci
56298c2ecf20Sopenharmony_ci		/* if there's more than one entry, ignore the rest */
56308c2ecf20Sopenharmony_ci	}
56318c2ecf20Sopenharmony_ci	return 0;
56328c2ecf20Sopenharmony_ci}
56338c2ecf20Sopenharmony_ci
56348c2ecf20Sopenharmony_cistatic int decode_chan_attrs(struct xdr_stream *xdr,
56358c2ecf20Sopenharmony_ci			     struct nfs4_channel_attrs *attrs)
56368c2ecf20Sopenharmony_ci{
56378c2ecf20Sopenharmony_ci	__be32 *p;
56388c2ecf20Sopenharmony_ci	u32 nr_attrs, val;
56398c2ecf20Sopenharmony_ci
56408c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 28);
56418c2ecf20Sopenharmony_ci	if (unlikely(!p))
56428c2ecf20Sopenharmony_ci		return -EIO;
56438c2ecf20Sopenharmony_ci	val = be32_to_cpup(p++);	/* headerpadsz */
56448c2ecf20Sopenharmony_ci	if (val)
56458c2ecf20Sopenharmony_ci		return -EINVAL;		/* no support for header padding yet */
56468c2ecf20Sopenharmony_ci	attrs->max_rqst_sz = be32_to_cpup(p++);
56478c2ecf20Sopenharmony_ci	attrs->max_resp_sz = be32_to_cpup(p++);
56488c2ecf20Sopenharmony_ci	attrs->max_resp_sz_cached = be32_to_cpup(p++);
56498c2ecf20Sopenharmony_ci	attrs->max_ops = be32_to_cpup(p++);
56508c2ecf20Sopenharmony_ci	attrs->max_reqs = be32_to_cpup(p++);
56518c2ecf20Sopenharmony_ci	nr_attrs = be32_to_cpup(p);
56528c2ecf20Sopenharmony_ci	if (unlikely(nr_attrs > 1)) {
56538c2ecf20Sopenharmony_ci		printk(KERN_WARNING "NFS: %s: Invalid rdma channel attrs "
56548c2ecf20Sopenharmony_ci			"count %u\n", __func__, nr_attrs);
56558c2ecf20Sopenharmony_ci		return -EINVAL;
56568c2ecf20Sopenharmony_ci	}
56578c2ecf20Sopenharmony_ci	if (nr_attrs == 1) {
56588c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */
56598c2ecf20Sopenharmony_ci		if (unlikely(!p))
56608c2ecf20Sopenharmony_ci			return -EIO;
56618c2ecf20Sopenharmony_ci	}
56628c2ecf20Sopenharmony_ci	return 0;
56638c2ecf20Sopenharmony_ci}
56648c2ecf20Sopenharmony_ci
56658c2ecf20Sopenharmony_cistatic int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid)
56668c2ecf20Sopenharmony_ci{
56678c2ecf20Sopenharmony_ci	return decode_opaque_fixed(xdr, sid->data, NFS4_MAX_SESSIONID_LEN);
56688c2ecf20Sopenharmony_ci}
56698c2ecf20Sopenharmony_ci
56708c2ecf20Sopenharmony_cistatic int decode_bind_conn_to_session(struct xdr_stream *xdr,
56718c2ecf20Sopenharmony_ci				struct nfs41_bind_conn_to_session_res *res)
56728c2ecf20Sopenharmony_ci{
56738c2ecf20Sopenharmony_ci	__be32 *p;
56748c2ecf20Sopenharmony_ci	int status;
56758c2ecf20Sopenharmony_ci
56768c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION);
56778c2ecf20Sopenharmony_ci	if (!status)
56788c2ecf20Sopenharmony_ci		status = decode_sessionid(xdr, &res->sessionid);
56798c2ecf20Sopenharmony_ci	if (unlikely(status))
56808c2ecf20Sopenharmony_ci		return status;
56818c2ecf20Sopenharmony_ci
56828c2ecf20Sopenharmony_ci	/* dir flags, rdma mode bool */
56838c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
56848c2ecf20Sopenharmony_ci	if (unlikely(!p))
56858c2ecf20Sopenharmony_ci		return -EIO;
56868c2ecf20Sopenharmony_ci
56878c2ecf20Sopenharmony_ci	res->dir = be32_to_cpup(p++);
56888c2ecf20Sopenharmony_ci	if (res->dir == 0 || res->dir > NFS4_CDFS4_BOTH)
56898c2ecf20Sopenharmony_ci		return -EIO;
56908c2ecf20Sopenharmony_ci	if (be32_to_cpup(p) == 0)
56918c2ecf20Sopenharmony_ci		res->use_conn_in_rdma_mode = false;
56928c2ecf20Sopenharmony_ci	else
56938c2ecf20Sopenharmony_ci		res->use_conn_in_rdma_mode = true;
56948c2ecf20Sopenharmony_ci
56958c2ecf20Sopenharmony_ci	return 0;
56968c2ecf20Sopenharmony_ci}
56978c2ecf20Sopenharmony_ci
56988c2ecf20Sopenharmony_cistatic int decode_create_session(struct xdr_stream *xdr,
56998c2ecf20Sopenharmony_ci				 struct nfs41_create_session_res *res)
57008c2ecf20Sopenharmony_ci{
57018c2ecf20Sopenharmony_ci	__be32 *p;
57028c2ecf20Sopenharmony_ci	int status;
57038c2ecf20Sopenharmony_ci
57048c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_CREATE_SESSION);
57058c2ecf20Sopenharmony_ci	if (!status)
57068c2ecf20Sopenharmony_ci		status = decode_sessionid(xdr, &res->sessionid);
57078c2ecf20Sopenharmony_ci	if (unlikely(status))
57088c2ecf20Sopenharmony_ci		return status;
57098c2ecf20Sopenharmony_ci
57108c2ecf20Sopenharmony_ci	/* seqid, flags */
57118c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
57128c2ecf20Sopenharmony_ci	if (unlikely(!p))
57138c2ecf20Sopenharmony_ci		return -EIO;
57148c2ecf20Sopenharmony_ci	res->seqid = be32_to_cpup(p++);
57158c2ecf20Sopenharmony_ci	res->flags = be32_to_cpup(p);
57168c2ecf20Sopenharmony_ci
57178c2ecf20Sopenharmony_ci	/* Channel attributes */
57188c2ecf20Sopenharmony_ci	status = decode_chan_attrs(xdr, &res->fc_attrs);
57198c2ecf20Sopenharmony_ci	if (!status)
57208c2ecf20Sopenharmony_ci		status = decode_chan_attrs(xdr, &res->bc_attrs);
57218c2ecf20Sopenharmony_ci	return status;
57228c2ecf20Sopenharmony_ci}
57238c2ecf20Sopenharmony_ci
57248c2ecf20Sopenharmony_cistatic int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
57258c2ecf20Sopenharmony_ci{
57268c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_DESTROY_SESSION);
57278c2ecf20Sopenharmony_ci}
57288c2ecf20Sopenharmony_ci
57298c2ecf20Sopenharmony_cistatic int decode_destroy_clientid(struct xdr_stream *xdr, void *dummy)
57308c2ecf20Sopenharmony_ci{
57318c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_DESTROY_CLIENTID);
57328c2ecf20Sopenharmony_ci}
57338c2ecf20Sopenharmony_ci
57348c2ecf20Sopenharmony_cistatic int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy)
57358c2ecf20Sopenharmony_ci{
57368c2ecf20Sopenharmony_ci	return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE);
57378c2ecf20Sopenharmony_ci}
57388c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
57398c2ecf20Sopenharmony_ci
57408c2ecf20Sopenharmony_cistatic int decode_sequence(struct xdr_stream *xdr,
57418c2ecf20Sopenharmony_ci			   struct nfs4_sequence_res *res,
57428c2ecf20Sopenharmony_ci			   struct rpc_rqst *rqstp)
57438c2ecf20Sopenharmony_ci{
57448c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
57458c2ecf20Sopenharmony_ci	struct nfs4_session *session;
57468c2ecf20Sopenharmony_ci	struct nfs4_sessionid id;
57478c2ecf20Sopenharmony_ci	u32 dummy;
57488c2ecf20Sopenharmony_ci	int status;
57498c2ecf20Sopenharmony_ci	__be32 *p;
57508c2ecf20Sopenharmony_ci
57518c2ecf20Sopenharmony_ci	if (res->sr_slot == NULL)
57528c2ecf20Sopenharmony_ci		return 0;
57538c2ecf20Sopenharmony_ci	if (!res->sr_slot->table->session)
57548c2ecf20Sopenharmony_ci		return 0;
57558c2ecf20Sopenharmony_ci
57568c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_SEQUENCE);
57578c2ecf20Sopenharmony_ci	if (!status)
57588c2ecf20Sopenharmony_ci		status = decode_sessionid(xdr, &id);
57598c2ecf20Sopenharmony_ci	if (unlikely(status))
57608c2ecf20Sopenharmony_ci		goto out_err;
57618c2ecf20Sopenharmony_ci
57628c2ecf20Sopenharmony_ci	/*
57638c2ecf20Sopenharmony_ci	 * If the server returns different values for sessionID, slotID or
57648c2ecf20Sopenharmony_ci	 * sequence number, the server is looney tunes.
57658c2ecf20Sopenharmony_ci	 */
57668c2ecf20Sopenharmony_ci	status = -EREMOTEIO;
57678c2ecf20Sopenharmony_ci	session = res->sr_slot->table->session;
57688c2ecf20Sopenharmony_ci
57698c2ecf20Sopenharmony_ci	if (memcmp(id.data, session->sess_id.data,
57708c2ecf20Sopenharmony_ci		   NFS4_MAX_SESSIONID_LEN)) {
57718c2ecf20Sopenharmony_ci		dprintk("%s Invalid session id\n", __func__);
57728c2ecf20Sopenharmony_ci		goto out_err;
57738c2ecf20Sopenharmony_ci	}
57748c2ecf20Sopenharmony_ci
57758c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 20);
57768c2ecf20Sopenharmony_ci	if (unlikely(!p))
57778c2ecf20Sopenharmony_ci		goto out_overflow;
57788c2ecf20Sopenharmony_ci
57798c2ecf20Sopenharmony_ci	/* seqid */
57808c2ecf20Sopenharmony_ci	dummy = be32_to_cpup(p++);
57818c2ecf20Sopenharmony_ci	if (dummy != res->sr_slot->seq_nr) {
57828c2ecf20Sopenharmony_ci		dprintk("%s Invalid sequence number\n", __func__);
57838c2ecf20Sopenharmony_ci		goto out_err;
57848c2ecf20Sopenharmony_ci	}
57858c2ecf20Sopenharmony_ci	/* slot id */
57868c2ecf20Sopenharmony_ci	dummy = be32_to_cpup(p++);
57878c2ecf20Sopenharmony_ci	if (dummy != res->sr_slot->slot_nr) {
57888c2ecf20Sopenharmony_ci		dprintk("%s Invalid slot id\n", __func__);
57898c2ecf20Sopenharmony_ci		goto out_err;
57908c2ecf20Sopenharmony_ci	}
57918c2ecf20Sopenharmony_ci	/* highest slot id */
57928c2ecf20Sopenharmony_ci	res->sr_highest_slotid = be32_to_cpup(p++);
57938c2ecf20Sopenharmony_ci	/* target highest slot id */
57948c2ecf20Sopenharmony_ci	res->sr_target_highest_slotid = be32_to_cpup(p++);
57958c2ecf20Sopenharmony_ci	/* result flags */
57968c2ecf20Sopenharmony_ci	res->sr_status_flags = be32_to_cpup(p);
57978c2ecf20Sopenharmony_ci	status = 0;
57988c2ecf20Sopenharmony_ciout_err:
57998c2ecf20Sopenharmony_ci	res->sr_status = status;
58008c2ecf20Sopenharmony_ci	return status;
58018c2ecf20Sopenharmony_ciout_overflow:
58028c2ecf20Sopenharmony_ci	status = -EIO;
58038c2ecf20Sopenharmony_ci	goto out_err;
58048c2ecf20Sopenharmony_ci#else  /* CONFIG_NFS_V4_1 */
58058c2ecf20Sopenharmony_ci	return 0;
58068c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
58078c2ecf20Sopenharmony_ci}
58088c2ecf20Sopenharmony_ci
58098c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
58108c2ecf20Sopenharmony_cistatic int decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
58118c2ecf20Sopenharmony_ci{
58128c2ecf20Sopenharmony_ci	stateid->type = NFS4_LAYOUT_STATEID_TYPE;
58138c2ecf20Sopenharmony_ci	return decode_stateid(xdr, stateid);
58148c2ecf20Sopenharmony_ci}
58158c2ecf20Sopenharmony_ci
58168c2ecf20Sopenharmony_cistatic int decode_getdeviceinfo(struct xdr_stream *xdr,
58178c2ecf20Sopenharmony_ci				struct nfs4_getdeviceinfo_res *res)
58188c2ecf20Sopenharmony_ci{
58198c2ecf20Sopenharmony_ci	struct pnfs_device *pdev = res->pdev;
58208c2ecf20Sopenharmony_ci	__be32 *p;
58218c2ecf20Sopenharmony_ci	uint32_t len, type;
58228c2ecf20Sopenharmony_ci	int status;
58238c2ecf20Sopenharmony_ci
58248c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_GETDEVICEINFO);
58258c2ecf20Sopenharmony_ci	if (status) {
58268c2ecf20Sopenharmony_ci		if (status == -ETOOSMALL) {
58278c2ecf20Sopenharmony_ci			p = xdr_inline_decode(xdr, 4);
58288c2ecf20Sopenharmony_ci			if (unlikely(!p))
58298c2ecf20Sopenharmony_ci				return -EIO;
58308c2ecf20Sopenharmony_ci			pdev->mincount = be32_to_cpup(p);
58318c2ecf20Sopenharmony_ci			dprintk("%s: Min count too small. mincnt = %u\n",
58328c2ecf20Sopenharmony_ci				__func__, pdev->mincount);
58338c2ecf20Sopenharmony_ci		}
58348c2ecf20Sopenharmony_ci		return status;
58358c2ecf20Sopenharmony_ci	}
58368c2ecf20Sopenharmony_ci
58378c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 8);
58388c2ecf20Sopenharmony_ci	if (unlikely(!p))
58398c2ecf20Sopenharmony_ci		return -EIO;
58408c2ecf20Sopenharmony_ci	type = be32_to_cpup(p++);
58418c2ecf20Sopenharmony_ci	if (type != pdev->layout_type) {
58428c2ecf20Sopenharmony_ci		dprintk("%s: layout mismatch req: %u pdev: %u\n",
58438c2ecf20Sopenharmony_ci			__func__, pdev->layout_type, type);
58448c2ecf20Sopenharmony_ci		return -EINVAL;
58458c2ecf20Sopenharmony_ci	}
58468c2ecf20Sopenharmony_ci	/*
58478c2ecf20Sopenharmony_ci	 * Get the length of the opaque device_addr4. xdr_read_pages places
58488c2ecf20Sopenharmony_ci	 * the opaque device_addr4 in the xdr_buf->pages (pnfs_device->pages)
58498c2ecf20Sopenharmony_ci	 * and places the remaining xdr data in xdr_buf->tail
58508c2ecf20Sopenharmony_ci	 */
58518c2ecf20Sopenharmony_ci	pdev->mincount = be32_to_cpup(p);
58528c2ecf20Sopenharmony_ci	if (xdr_read_pages(xdr, pdev->mincount) != pdev->mincount)
58538c2ecf20Sopenharmony_ci		return -EIO;
58548c2ecf20Sopenharmony_ci
58558c2ecf20Sopenharmony_ci	/* Parse notification bitmap, verifying that it is zero. */
58568c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
58578c2ecf20Sopenharmony_ci	if (unlikely(!p))
58588c2ecf20Sopenharmony_ci		return -EIO;
58598c2ecf20Sopenharmony_ci	len = be32_to_cpup(p);
58608c2ecf20Sopenharmony_ci	if (len) {
58618c2ecf20Sopenharmony_ci		uint32_t i;
58628c2ecf20Sopenharmony_ci
58638c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4 * len);
58648c2ecf20Sopenharmony_ci		if (unlikely(!p))
58658c2ecf20Sopenharmony_ci			return -EIO;
58668c2ecf20Sopenharmony_ci
58678c2ecf20Sopenharmony_ci		res->notification = be32_to_cpup(p++);
58688c2ecf20Sopenharmony_ci		for (i = 1; i < len; i++) {
58698c2ecf20Sopenharmony_ci			if (be32_to_cpup(p++)) {
58708c2ecf20Sopenharmony_ci				dprintk("%s: unsupported notification\n",
58718c2ecf20Sopenharmony_ci					__func__);
58728c2ecf20Sopenharmony_ci				return -EIO;
58738c2ecf20Sopenharmony_ci			}
58748c2ecf20Sopenharmony_ci		}
58758c2ecf20Sopenharmony_ci	}
58768c2ecf20Sopenharmony_ci	return 0;
58778c2ecf20Sopenharmony_ci}
58788c2ecf20Sopenharmony_ci
58798c2ecf20Sopenharmony_cistatic int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
58808c2ecf20Sopenharmony_ci			    struct nfs4_layoutget_res *res)
58818c2ecf20Sopenharmony_ci{
58828c2ecf20Sopenharmony_ci	__be32 *p;
58838c2ecf20Sopenharmony_ci	int status;
58848c2ecf20Sopenharmony_ci	u32 layout_count;
58858c2ecf20Sopenharmony_ci	u32 recvd;
58868c2ecf20Sopenharmony_ci
58878c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_LAYOUTGET);
58888c2ecf20Sopenharmony_ci	if (status)
58898c2ecf20Sopenharmony_ci		goto out;
58908c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
58918c2ecf20Sopenharmony_ci	if (unlikely(!p))
58928c2ecf20Sopenharmony_ci		goto out_overflow;
58938c2ecf20Sopenharmony_ci	res->return_on_close = be32_to_cpup(p);
58948c2ecf20Sopenharmony_ci	decode_layout_stateid(xdr, &res->stateid);
58958c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
58968c2ecf20Sopenharmony_ci	if (unlikely(!p))
58978c2ecf20Sopenharmony_ci		goto out_overflow;
58988c2ecf20Sopenharmony_ci	layout_count = be32_to_cpup(p);
58998c2ecf20Sopenharmony_ci	if (!layout_count) {
59008c2ecf20Sopenharmony_ci		dprintk("%s: server responded with empty layout array\n",
59018c2ecf20Sopenharmony_ci			__func__);
59028c2ecf20Sopenharmony_ci		status = -EINVAL;
59038c2ecf20Sopenharmony_ci		goto out;
59048c2ecf20Sopenharmony_ci	}
59058c2ecf20Sopenharmony_ci
59068c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 28);
59078c2ecf20Sopenharmony_ci	if (unlikely(!p))
59088c2ecf20Sopenharmony_ci		goto out_overflow;
59098c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &res->range.offset);
59108c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &res->range.length);
59118c2ecf20Sopenharmony_ci	res->range.iomode = be32_to_cpup(p++);
59128c2ecf20Sopenharmony_ci	res->type = be32_to_cpup(p++);
59138c2ecf20Sopenharmony_ci	res->layoutp->len = be32_to_cpup(p);
59148c2ecf20Sopenharmony_ci
59158c2ecf20Sopenharmony_ci	dprintk("%s roff:%lu rlen:%lu riomode:%d, lo_type:0x%x, lo.len:%d\n",
59168c2ecf20Sopenharmony_ci		__func__,
59178c2ecf20Sopenharmony_ci		(unsigned long)res->range.offset,
59188c2ecf20Sopenharmony_ci		(unsigned long)res->range.length,
59198c2ecf20Sopenharmony_ci		res->range.iomode,
59208c2ecf20Sopenharmony_ci		res->type,
59218c2ecf20Sopenharmony_ci		res->layoutp->len);
59228c2ecf20Sopenharmony_ci
59238c2ecf20Sopenharmony_ci	recvd = xdr_read_pages(xdr, res->layoutp->len);
59248c2ecf20Sopenharmony_ci	if (res->layoutp->len > recvd) {
59258c2ecf20Sopenharmony_ci		dprintk("NFS: server cheating in layoutget reply: "
59268c2ecf20Sopenharmony_ci				"layout len %u > recvd %u\n",
59278c2ecf20Sopenharmony_ci				res->layoutp->len, recvd);
59288c2ecf20Sopenharmony_ci		status = -EINVAL;
59298c2ecf20Sopenharmony_ci		goto out;
59308c2ecf20Sopenharmony_ci	}
59318c2ecf20Sopenharmony_ci
59328c2ecf20Sopenharmony_ci	if (layout_count > 1) {
59338c2ecf20Sopenharmony_ci		/* We only handle a length one array at the moment.  Any
59348c2ecf20Sopenharmony_ci		 * further entries are just ignored.  Note that this means
59358c2ecf20Sopenharmony_ci		 * the client may see a response that is less than the
59368c2ecf20Sopenharmony_ci		 * minimum it requested.
59378c2ecf20Sopenharmony_ci		 */
59388c2ecf20Sopenharmony_ci		dprintk("%s: server responded with %d layouts, dropping tail\n",
59398c2ecf20Sopenharmony_ci			__func__, layout_count);
59408c2ecf20Sopenharmony_ci	}
59418c2ecf20Sopenharmony_ci
59428c2ecf20Sopenharmony_ciout:
59438c2ecf20Sopenharmony_ci	res->status = status;
59448c2ecf20Sopenharmony_ci	return status;
59458c2ecf20Sopenharmony_ciout_overflow:
59468c2ecf20Sopenharmony_ci	status = -EIO;
59478c2ecf20Sopenharmony_ci	goto out;
59488c2ecf20Sopenharmony_ci}
59498c2ecf20Sopenharmony_ci
59508c2ecf20Sopenharmony_cistatic int decode_layoutreturn(struct xdr_stream *xdr,
59518c2ecf20Sopenharmony_ci			       struct nfs4_layoutreturn_res *res)
59528c2ecf20Sopenharmony_ci{
59538c2ecf20Sopenharmony_ci	__be32 *p;
59548c2ecf20Sopenharmony_ci	int status;
59558c2ecf20Sopenharmony_ci
59568c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_LAYOUTRETURN);
59578c2ecf20Sopenharmony_ci	if (status)
59588c2ecf20Sopenharmony_ci		return status;
59598c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
59608c2ecf20Sopenharmony_ci	if (unlikely(!p))
59618c2ecf20Sopenharmony_ci		return -EIO;
59628c2ecf20Sopenharmony_ci	res->lrs_present = be32_to_cpup(p);
59638c2ecf20Sopenharmony_ci	if (res->lrs_present)
59648c2ecf20Sopenharmony_ci		status = decode_layout_stateid(xdr, &res->stateid);
59658c2ecf20Sopenharmony_ci	else
59668c2ecf20Sopenharmony_ci		nfs4_stateid_copy(&res->stateid, &invalid_stateid);
59678c2ecf20Sopenharmony_ci	return status;
59688c2ecf20Sopenharmony_ci}
59698c2ecf20Sopenharmony_ci
59708c2ecf20Sopenharmony_cistatic int decode_layoutcommit(struct xdr_stream *xdr,
59718c2ecf20Sopenharmony_ci			       struct rpc_rqst *req,
59728c2ecf20Sopenharmony_ci			       struct nfs4_layoutcommit_res *res)
59738c2ecf20Sopenharmony_ci{
59748c2ecf20Sopenharmony_ci	__be32 *p;
59758c2ecf20Sopenharmony_ci	__u32 sizechanged;
59768c2ecf20Sopenharmony_ci	int status;
59778c2ecf20Sopenharmony_ci
59788c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT);
59798c2ecf20Sopenharmony_ci	res->status = status;
59808c2ecf20Sopenharmony_ci	if (status)
59818c2ecf20Sopenharmony_ci		return status;
59828c2ecf20Sopenharmony_ci
59838c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
59848c2ecf20Sopenharmony_ci	if (unlikely(!p))
59858c2ecf20Sopenharmony_ci		return -EIO;
59868c2ecf20Sopenharmony_ci	sizechanged = be32_to_cpup(p);
59878c2ecf20Sopenharmony_ci
59888c2ecf20Sopenharmony_ci	if (sizechanged) {
59898c2ecf20Sopenharmony_ci		/* throw away new size */
59908c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 8);
59918c2ecf20Sopenharmony_ci		if (unlikely(!p))
59928c2ecf20Sopenharmony_ci			return -EIO;
59938c2ecf20Sopenharmony_ci	}
59948c2ecf20Sopenharmony_ci	return 0;
59958c2ecf20Sopenharmony_ci}
59968c2ecf20Sopenharmony_ci
59978c2ecf20Sopenharmony_cistatic int decode_test_stateid(struct xdr_stream *xdr,
59988c2ecf20Sopenharmony_ci			       struct nfs41_test_stateid_res *res)
59998c2ecf20Sopenharmony_ci{
60008c2ecf20Sopenharmony_ci	__be32 *p;
60018c2ecf20Sopenharmony_ci	int status;
60028c2ecf20Sopenharmony_ci	int num_res;
60038c2ecf20Sopenharmony_ci
60048c2ecf20Sopenharmony_ci	status = decode_op_hdr(xdr, OP_TEST_STATEID);
60058c2ecf20Sopenharmony_ci	if (status)
60068c2ecf20Sopenharmony_ci		return status;
60078c2ecf20Sopenharmony_ci
60088c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
60098c2ecf20Sopenharmony_ci	if (unlikely(!p))
60108c2ecf20Sopenharmony_ci		return -EIO;
60118c2ecf20Sopenharmony_ci	num_res = be32_to_cpup(p++);
60128c2ecf20Sopenharmony_ci	if (num_res != 1)
60138c2ecf20Sopenharmony_ci		return -EIO;
60148c2ecf20Sopenharmony_ci
60158c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 4);
60168c2ecf20Sopenharmony_ci	if (unlikely(!p))
60178c2ecf20Sopenharmony_ci		return -EIO;
60188c2ecf20Sopenharmony_ci	res->status = be32_to_cpup(p++);
60198c2ecf20Sopenharmony_ci
60208c2ecf20Sopenharmony_ci	return status;
60218c2ecf20Sopenharmony_ci}
60228c2ecf20Sopenharmony_ci
60238c2ecf20Sopenharmony_cistatic int decode_free_stateid(struct xdr_stream *xdr,
60248c2ecf20Sopenharmony_ci			       struct nfs41_free_stateid_res *res)
60258c2ecf20Sopenharmony_ci{
60268c2ecf20Sopenharmony_ci	res->status = decode_op_hdr(xdr, OP_FREE_STATEID);
60278c2ecf20Sopenharmony_ci	return res->status;
60288c2ecf20Sopenharmony_ci}
60298c2ecf20Sopenharmony_ci#else
60308c2ecf20Sopenharmony_cistatic inline
60318c2ecf20Sopenharmony_ciint decode_layoutreturn(struct xdr_stream *xdr,
60328c2ecf20Sopenharmony_ci			       struct nfs4_layoutreturn_res *res)
60338c2ecf20Sopenharmony_ci{
60348c2ecf20Sopenharmony_ci	return 0;
60358c2ecf20Sopenharmony_ci}
60368c2ecf20Sopenharmony_ci
60378c2ecf20Sopenharmony_cistatic int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
60388c2ecf20Sopenharmony_ci			    struct nfs4_layoutget_res *res)
60398c2ecf20Sopenharmony_ci{
60408c2ecf20Sopenharmony_ci	return 0;
60418c2ecf20Sopenharmony_ci}
60428c2ecf20Sopenharmony_ci
60438c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
60448c2ecf20Sopenharmony_ci
60458c2ecf20Sopenharmony_ci/*
60468c2ecf20Sopenharmony_ci * END OF "GENERIC" DECODE ROUTINES.
60478c2ecf20Sopenharmony_ci */
60488c2ecf20Sopenharmony_ci
60498c2ecf20Sopenharmony_ci/*
60508c2ecf20Sopenharmony_ci * Decode OPEN_DOWNGRADE response
60518c2ecf20Sopenharmony_ci */
60528c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp,
60538c2ecf20Sopenharmony_ci				       struct xdr_stream *xdr,
60548c2ecf20Sopenharmony_ci				       void *data)
60558c2ecf20Sopenharmony_ci{
60568c2ecf20Sopenharmony_ci	struct nfs_closeres *res = data;
60578c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
60588c2ecf20Sopenharmony_ci	int status;
60598c2ecf20Sopenharmony_ci
60608c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
60618c2ecf20Sopenharmony_ci	if (status)
60628c2ecf20Sopenharmony_ci		goto out;
60638c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
60648c2ecf20Sopenharmony_ci	if (status)
60658c2ecf20Sopenharmony_ci		goto out;
60668c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
60678c2ecf20Sopenharmony_ci	if (status)
60688c2ecf20Sopenharmony_ci		goto out;
60698c2ecf20Sopenharmony_ci	if (res->lr_res) {
60708c2ecf20Sopenharmony_ci		status = decode_layoutreturn(xdr, res->lr_res);
60718c2ecf20Sopenharmony_ci		res->lr_ret = status;
60728c2ecf20Sopenharmony_ci		if (status)
60738c2ecf20Sopenharmony_ci			goto out;
60748c2ecf20Sopenharmony_ci	}
60758c2ecf20Sopenharmony_ci	status = decode_open_downgrade(xdr, res);
60768c2ecf20Sopenharmony_ciout:
60778c2ecf20Sopenharmony_ci	return status;
60788c2ecf20Sopenharmony_ci}
60798c2ecf20Sopenharmony_ci
60808c2ecf20Sopenharmony_ci/*
60818c2ecf20Sopenharmony_ci * Decode ACCESS response
60828c2ecf20Sopenharmony_ci */
60838c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
60848c2ecf20Sopenharmony_ci			       void *data)
60858c2ecf20Sopenharmony_ci{
60868c2ecf20Sopenharmony_ci	struct nfs4_accessres *res = data;
60878c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
60888c2ecf20Sopenharmony_ci	int status;
60898c2ecf20Sopenharmony_ci
60908c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
60918c2ecf20Sopenharmony_ci	if (status)
60928c2ecf20Sopenharmony_ci		goto out;
60938c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
60948c2ecf20Sopenharmony_ci	if (status)
60958c2ecf20Sopenharmony_ci		goto out;
60968c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
60978c2ecf20Sopenharmony_ci	if (status != 0)
60988c2ecf20Sopenharmony_ci		goto out;
60998c2ecf20Sopenharmony_ci	status = decode_access(xdr, &res->supported, &res->access);
61008c2ecf20Sopenharmony_ci	if (status != 0)
61018c2ecf20Sopenharmony_ci		goto out;
61028c2ecf20Sopenharmony_ci	if (res->fattr)
61038c2ecf20Sopenharmony_ci		decode_getfattr(xdr, res->fattr, res->server);
61048c2ecf20Sopenharmony_ciout:
61058c2ecf20Sopenharmony_ci	return status;
61068c2ecf20Sopenharmony_ci}
61078c2ecf20Sopenharmony_ci
61088c2ecf20Sopenharmony_ci/*
61098c2ecf20Sopenharmony_ci * Decode LOOKUP response
61108c2ecf20Sopenharmony_ci */
61118c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
61128c2ecf20Sopenharmony_ci			       void *data)
61138c2ecf20Sopenharmony_ci{
61148c2ecf20Sopenharmony_ci	struct nfs4_lookup_res *res = data;
61158c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
61168c2ecf20Sopenharmony_ci	int status;
61178c2ecf20Sopenharmony_ci
61188c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
61198c2ecf20Sopenharmony_ci	if (status)
61208c2ecf20Sopenharmony_ci		goto out;
61218c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
61228c2ecf20Sopenharmony_ci	if (status)
61238c2ecf20Sopenharmony_ci		goto out;
61248c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
61258c2ecf20Sopenharmony_ci	if (status)
61268c2ecf20Sopenharmony_ci		goto out;
61278c2ecf20Sopenharmony_ci	status = decode_lookup(xdr);
61288c2ecf20Sopenharmony_ci	if (status)
61298c2ecf20Sopenharmony_ci		goto out;
61308c2ecf20Sopenharmony_ci	status = decode_getfh(xdr, res->fh);
61318c2ecf20Sopenharmony_ci	if (status)
61328c2ecf20Sopenharmony_ci		goto out;
61338c2ecf20Sopenharmony_ci	status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
61348c2ecf20Sopenharmony_ciout:
61358c2ecf20Sopenharmony_ci	return status;
61368c2ecf20Sopenharmony_ci}
61378c2ecf20Sopenharmony_ci
61388c2ecf20Sopenharmony_ci/*
61398c2ecf20Sopenharmony_ci * Decode LOOKUPP response
61408c2ecf20Sopenharmony_ci */
61418c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
61428c2ecf20Sopenharmony_ci		void *data)
61438c2ecf20Sopenharmony_ci{
61448c2ecf20Sopenharmony_ci	struct nfs4_lookupp_res *res = data;
61458c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
61468c2ecf20Sopenharmony_ci	int status;
61478c2ecf20Sopenharmony_ci
61488c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
61498c2ecf20Sopenharmony_ci	if (status)
61508c2ecf20Sopenharmony_ci		goto out;
61518c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
61528c2ecf20Sopenharmony_ci	if (status)
61538c2ecf20Sopenharmony_ci		goto out;
61548c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
61558c2ecf20Sopenharmony_ci	if (status)
61568c2ecf20Sopenharmony_ci		goto out;
61578c2ecf20Sopenharmony_ci	status = decode_lookupp(xdr);
61588c2ecf20Sopenharmony_ci	if (status)
61598c2ecf20Sopenharmony_ci		goto out;
61608c2ecf20Sopenharmony_ci	status = decode_getfh(xdr, res->fh);
61618c2ecf20Sopenharmony_ci	if (status)
61628c2ecf20Sopenharmony_ci		goto out;
61638c2ecf20Sopenharmony_ci	status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
61648c2ecf20Sopenharmony_ciout:
61658c2ecf20Sopenharmony_ci	return status;
61668c2ecf20Sopenharmony_ci}
61678c2ecf20Sopenharmony_ci
61688c2ecf20Sopenharmony_ci/*
61698c2ecf20Sopenharmony_ci * Decode LOOKUP_ROOT response
61708c2ecf20Sopenharmony_ci */
61718c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
61728c2ecf20Sopenharmony_ci				    struct xdr_stream *xdr,
61738c2ecf20Sopenharmony_ci				    void *data)
61748c2ecf20Sopenharmony_ci{
61758c2ecf20Sopenharmony_ci	struct nfs4_lookup_res *res = data;
61768c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
61778c2ecf20Sopenharmony_ci	int status;
61788c2ecf20Sopenharmony_ci
61798c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
61808c2ecf20Sopenharmony_ci	if (status)
61818c2ecf20Sopenharmony_ci		goto out;
61828c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
61838c2ecf20Sopenharmony_ci	if (status)
61848c2ecf20Sopenharmony_ci		goto out;
61858c2ecf20Sopenharmony_ci	status = decode_putrootfh(xdr);
61868c2ecf20Sopenharmony_ci	if (status)
61878c2ecf20Sopenharmony_ci		goto out;
61888c2ecf20Sopenharmony_ci	status = decode_getfh(xdr, res->fh);
61898c2ecf20Sopenharmony_ci	if (status == 0)
61908c2ecf20Sopenharmony_ci		status = decode_getfattr_label(xdr, res->fattr,
61918c2ecf20Sopenharmony_ci						res->label, res->server);
61928c2ecf20Sopenharmony_ciout:
61938c2ecf20Sopenharmony_ci	return status;
61948c2ecf20Sopenharmony_ci}
61958c2ecf20Sopenharmony_ci
61968c2ecf20Sopenharmony_ci/*
61978c2ecf20Sopenharmony_ci * Decode REMOVE response
61988c2ecf20Sopenharmony_ci */
61998c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
62008c2ecf20Sopenharmony_ci			       void *data)
62018c2ecf20Sopenharmony_ci{
62028c2ecf20Sopenharmony_ci	struct nfs_removeres *res = data;
62038c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
62048c2ecf20Sopenharmony_ci	int status;
62058c2ecf20Sopenharmony_ci
62068c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
62078c2ecf20Sopenharmony_ci	if (status)
62088c2ecf20Sopenharmony_ci		goto out;
62098c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
62108c2ecf20Sopenharmony_ci	if (status)
62118c2ecf20Sopenharmony_ci		goto out;
62128c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
62138c2ecf20Sopenharmony_ci	if (status)
62148c2ecf20Sopenharmony_ci		goto out;
62158c2ecf20Sopenharmony_ci	status = decode_remove(xdr, &res->cinfo);
62168c2ecf20Sopenharmony_ciout:
62178c2ecf20Sopenharmony_ci	return status;
62188c2ecf20Sopenharmony_ci}
62198c2ecf20Sopenharmony_ci
62208c2ecf20Sopenharmony_ci/*
62218c2ecf20Sopenharmony_ci * Decode RENAME response
62228c2ecf20Sopenharmony_ci */
62238c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
62248c2ecf20Sopenharmony_ci			       void *data)
62258c2ecf20Sopenharmony_ci{
62268c2ecf20Sopenharmony_ci	struct nfs_renameres *res = data;
62278c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
62288c2ecf20Sopenharmony_ci	int status;
62298c2ecf20Sopenharmony_ci
62308c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
62318c2ecf20Sopenharmony_ci	if (status)
62328c2ecf20Sopenharmony_ci		goto out;
62338c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
62348c2ecf20Sopenharmony_ci	if (status)
62358c2ecf20Sopenharmony_ci		goto out;
62368c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
62378c2ecf20Sopenharmony_ci	if (status)
62388c2ecf20Sopenharmony_ci		goto out;
62398c2ecf20Sopenharmony_ci	status = decode_savefh(xdr);
62408c2ecf20Sopenharmony_ci	if (status)
62418c2ecf20Sopenharmony_ci		goto out;
62428c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
62438c2ecf20Sopenharmony_ci	if (status)
62448c2ecf20Sopenharmony_ci		goto out;
62458c2ecf20Sopenharmony_ci	status = decode_rename(xdr, &res->old_cinfo, &res->new_cinfo);
62468c2ecf20Sopenharmony_ciout:
62478c2ecf20Sopenharmony_ci	return status;
62488c2ecf20Sopenharmony_ci}
62498c2ecf20Sopenharmony_ci
62508c2ecf20Sopenharmony_ci/*
62518c2ecf20Sopenharmony_ci * Decode LINK response
62528c2ecf20Sopenharmony_ci */
62538c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
62548c2ecf20Sopenharmony_ci			     void *data)
62558c2ecf20Sopenharmony_ci{
62568c2ecf20Sopenharmony_ci	struct nfs4_link_res *res = data;
62578c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
62588c2ecf20Sopenharmony_ci	int status;
62598c2ecf20Sopenharmony_ci
62608c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
62618c2ecf20Sopenharmony_ci	if (status)
62628c2ecf20Sopenharmony_ci		goto out;
62638c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
62648c2ecf20Sopenharmony_ci	if (status)
62658c2ecf20Sopenharmony_ci		goto out;
62668c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
62678c2ecf20Sopenharmony_ci	if (status)
62688c2ecf20Sopenharmony_ci		goto out;
62698c2ecf20Sopenharmony_ci	status = decode_savefh(xdr);
62708c2ecf20Sopenharmony_ci	if (status)
62718c2ecf20Sopenharmony_ci		goto out;
62728c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
62738c2ecf20Sopenharmony_ci	if (status)
62748c2ecf20Sopenharmony_ci		goto out;
62758c2ecf20Sopenharmony_ci	status = decode_link(xdr, &res->cinfo);
62768c2ecf20Sopenharmony_ci	if (status)
62778c2ecf20Sopenharmony_ci		goto out;
62788c2ecf20Sopenharmony_ci	/*
62798c2ecf20Sopenharmony_ci	 * Note order: OP_LINK leaves the directory as the current
62808c2ecf20Sopenharmony_ci	 *             filehandle.
62818c2ecf20Sopenharmony_ci	 */
62828c2ecf20Sopenharmony_ci	status = decode_restorefh(xdr);
62838c2ecf20Sopenharmony_ci	if (status)
62848c2ecf20Sopenharmony_ci		goto out;
62858c2ecf20Sopenharmony_ci	decode_getfattr_label(xdr, res->fattr, res->label, res->server);
62868c2ecf20Sopenharmony_ciout:
62878c2ecf20Sopenharmony_ci	return status;
62888c2ecf20Sopenharmony_ci}
62898c2ecf20Sopenharmony_ci
62908c2ecf20Sopenharmony_ci/*
62918c2ecf20Sopenharmony_ci * Decode CREATE response
62928c2ecf20Sopenharmony_ci */
62938c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
62948c2ecf20Sopenharmony_ci			       void *data)
62958c2ecf20Sopenharmony_ci{
62968c2ecf20Sopenharmony_ci	struct nfs4_create_res *res = data;
62978c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
62988c2ecf20Sopenharmony_ci	int status;
62998c2ecf20Sopenharmony_ci
63008c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
63018c2ecf20Sopenharmony_ci	if (status)
63028c2ecf20Sopenharmony_ci		goto out;
63038c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
63048c2ecf20Sopenharmony_ci	if (status)
63058c2ecf20Sopenharmony_ci		goto out;
63068c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
63078c2ecf20Sopenharmony_ci	if (status)
63088c2ecf20Sopenharmony_ci		goto out;
63098c2ecf20Sopenharmony_ci	status = decode_create(xdr, &res->dir_cinfo);
63108c2ecf20Sopenharmony_ci	if (status)
63118c2ecf20Sopenharmony_ci		goto out;
63128c2ecf20Sopenharmony_ci	status = decode_getfh(xdr, res->fh);
63138c2ecf20Sopenharmony_ci	if (status)
63148c2ecf20Sopenharmony_ci		goto out;
63158c2ecf20Sopenharmony_ci	decode_getfattr_label(xdr, res->fattr, res->label, res->server);
63168c2ecf20Sopenharmony_ciout:
63178c2ecf20Sopenharmony_ci	return status;
63188c2ecf20Sopenharmony_ci}
63198c2ecf20Sopenharmony_ci
63208c2ecf20Sopenharmony_ci/*
63218c2ecf20Sopenharmony_ci * Decode SYMLINK response
63228c2ecf20Sopenharmony_ci */
63238c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
63248c2ecf20Sopenharmony_ci				void *res)
63258c2ecf20Sopenharmony_ci{
63268c2ecf20Sopenharmony_ci	return nfs4_xdr_dec_create(rqstp, xdr, res);
63278c2ecf20Sopenharmony_ci}
63288c2ecf20Sopenharmony_ci
63298c2ecf20Sopenharmony_ci/*
63308c2ecf20Sopenharmony_ci * Decode GETATTR response
63318c2ecf20Sopenharmony_ci */
63328c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
63338c2ecf20Sopenharmony_ci				void *data)
63348c2ecf20Sopenharmony_ci{
63358c2ecf20Sopenharmony_ci	struct nfs4_getattr_res *res = data;
63368c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
63378c2ecf20Sopenharmony_ci	int status;
63388c2ecf20Sopenharmony_ci
63398c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
63408c2ecf20Sopenharmony_ci	if (status)
63418c2ecf20Sopenharmony_ci		goto out;
63428c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
63438c2ecf20Sopenharmony_ci	if (status)
63448c2ecf20Sopenharmony_ci		goto out;
63458c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
63468c2ecf20Sopenharmony_ci	if (status)
63478c2ecf20Sopenharmony_ci		goto out;
63488c2ecf20Sopenharmony_ci	status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
63498c2ecf20Sopenharmony_ciout:
63508c2ecf20Sopenharmony_ci	return status;
63518c2ecf20Sopenharmony_ci}
63528c2ecf20Sopenharmony_ci
63538c2ecf20Sopenharmony_ci/*
63548c2ecf20Sopenharmony_ci * Encode an SETACL request
63558c2ecf20Sopenharmony_ci */
63568c2ecf20Sopenharmony_cistatic void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr,
63578c2ecf20Sopenharmony_ci				const void *data)
63588c2ecf20Sopenharmony_ci{
63598c2ecf20Sopenharmony_ci	const struct nfs_setaclargs *args = data;
63608c2ecf20Sopenharmony_ci	struct compound_hdr hdr = {
63618c2ecf20Sopenharmony_ci		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
63628c2ecf20Sopenharmony_ci	};
63638c2ecf20Sopenharmony_ci
63648c2ecf20Sopenharmony_ci	encode_compound_hdr(xdr, req, &hdr);
63658c2ecf20Sopenharmony_ci	encode_sequence(xdr, &args->seq_args, &hdr);
63668c2ecf20Sopenharmony_ci	encode_putfh(xdr, args->fh, &hdr);
63678c2ecf20Sopenharmony_ci	encode_setacl(xdr, args, &hdr);
63688c2ecf20Sopenharmony_ci	encode_nops(&hdr);
63698c2ecf20Sopenharmony_ci}
63708c2ecf20Sopenharmony_ci
63718c2ecf20Sopenharmony_ci/*
63728c2ecf20Sopenharmony_ci * Decode SETACL response
63738c2ecf20Sopenharmony_ci */
63748c2ecf20Sopenharmony_cistatic int
63758c2ecf20Sopenharmony_cinfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
63768c2ecf20Sopenharmony_ci		    void *data)
63778c2ecf20Sopenharmony_ci{
63788c2ecf20Sopenharmony_ci	struct nfs_setaclres *res = data;
63798c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
63808c2ecf20Sopenharmony_ci	int status;
63818c2ecf20Sopenharmony_ci
63828c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
63838c2ecf20Sopenharmony_ci	if (status)
63848c2ecf20Sopenharmony_ci		goto out;
63858c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
63868c2ecf20Sopenharmony_ci	if (status)
63878c2ecf20Sopenharmony_ci		goto out;
63888c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
63898c2ecf20Sopenharmony_ci	if (status)
63908c2ecf20Sopenharmony_ci		goto out;
63918c2ecf20Sopenharmony_ci	status = decode_setattr(xdr);
63928c2ecf20Sopenharmony_ciout:
63938c2ecf20Sopenharmony_ci	return status;
63948c2ecf20Sopenharmony_ci}
63958c2ecf20Sopenharmony_ci
63968c2ecf20Sopenharmony_ci/*
63978c2ecf20Sopenharmony_ci * Decode GETACL response
63988c2ecf20Sopenharmony_ci */
63998c2ecf20Sopenharmony_cistatic int
64008c2ecf20Sopenharmony_cinfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
64018c2ecf20Sopenharmony_ci		    void *data)
64028c2ecf20Sopenharmony_ci{
64038c2ecf20Sopenharmony_ci	struct nfs_getaclres *res = data;
64048c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
64058c2ecf20Sopenharmony_ci	int status;
64068c2ecf20Sopenharmony_ci
64078c2ecf20Sopenharmony_ci	if (res->acl_scratch != NULL) {
64088c2ecf20Sopenharmony_ci		void *p = page_address(res->acl_scratch);
64098c2ecf20Sopenharmony_ci		xdr_set_scratch_buffer(xdr, p, PAGE_SIZE);
64108c2ecf20Sopenharmony_ci	}
64118c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
64128c2ecf20Sopenharmony_ci	if (status)
64138c2ecf20Sopenharmony_ci		goto out;
64148c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
64158c2ecf20Sopenharmony_ci	if (status)
64168c2ecf20Sopenharmony_ci		goto out;
64178c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
64188c2ecf20Sopenharmony_ci	if (status)
64198c2ecf20Sopenharmony_ci		goto out;
64208c2ecf20Sopenharmony_ci	status = decode_getacl(xdr, rqstp, res);
64218c2ecf20Sopenharmony_ci
64228c2ecf20Sopenharmony_ciout:
64238c2ecf20Sopenharmony_ci	return status;
64248c2ecf20Sopenharmony_ci}
64258c2ecf20Sopenharmony_ci
64268c2ecf20Sopenharmony_ci/*
64278c2ecf20Sopenharmony_ci * Decode CLOSE response
64288c2ecf20Sopenharmony_ci */
64298c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
64308c2ecf20Sopenharmony_ci			      void *data)
64318c2ecf20Sopenharmony_ci{
64328c2ecf20Sopenharmony_ci	struct nfs_closeres *res = data;
64338c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
64348c2ecf20Sopenharmony_ci	int status;
64358c2ecf20Sopenharmony_ci
64368c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
64378c2ecf20Sopenharmony_ci	if (status)
64388c2ecf20Sopenharmony_ci		goto out;
64398c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
64408c2ecf20Sopenharmony_ci	if (status)
64418c2ecf20Sopenharmony_ci		goto out;
64428c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
64438c2ecf20Sopenharmony_ci	if (status)
64448c2ecf20Sopenharmony_ci		goto out;
64458c2ecf20Sopenharmony_ci	if (res->lr_res) {
64468c2ecf20Sopenharmony_ci		status = decode_layoutreturn(xdr, res->lr_res);
64478c2ecf20Sopenharmony_ci		res->lr_ret = status;
64488c2ecf20Sopenharmony_ci		if (status)
64498c2ecf20Sopenharmony_ci			goto out;
64508c2ecf20Sopenharmony_ci	}
64518c2ecf20Sopenharmony_ci	if (res->fattr != NULL) {
64528c2ecf20Sopenharmony_ci		status = decode_getfattr(xdr, res->fattr, res->server);
64538c2ecf20Sopenharmony_ci		if (status != 0)
64548c2ecf20Sopenharmony_ci			goto out;
64558c2ecf20Sopenharmony_ci	}
64568c2ecf20Sopenharmony_ci	status = decode_close(xdr, res);
64578c2ecf20Sopenharmony_ciout:
64588c2ecf20Sopenharmony_ci	return status;
64598c2ecf20Sopenharmony_ci}
64608c2ecf20Sopenharmony_ci
64618c2ecf20Sopenharmony_ci/*
64628c2ecf20Sopenharmony_ci * Decode OPEN response
64638c2ecf20Sopenharmony_ci */
64648c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
64658c2ecf20Sopenharmony_ci			     void *data)
64668c2ecf20Sopenharmony_ci{
64678c2ecf20Sopenharmony_ci	struct nfs_openres *res = data;
64688c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
64698c2ecf20Sopenharmony_ci	int status;
64708c2ecf20Sopenharmony_ci
64718c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
64728c2ecf20Sopenharmony_ci	if (status)
64738c2ecf20Sopenharmony_ci		goto out;
64748c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
64758c2ecf20Sopenharmony_ci	if (status)
64768c2ecf20Sopenharmony_ci		goto out;
64778c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
64788c2ecf20Sopenharmony_ci	if (status)
64798c2ecf20Sopenharmony_ci		goto out;
64808c2ecf20Sopenharmony_ci	status = decode_open(xdr, res);
64818c2ecf20Sopenharmony_ci	if (status)
64828c2ecf20Sopenharmony_ci		goto out;
64838c2ecf20Sopenharmony_ci	status = decode_getfh(xdr, &res->fh);
64848c2ecf20Sopenharmony_ci	if (status)
64858c2ecf20Sopenharmony_ci		goto out;
64868c2ecf20Sopenharmony_ci	if (res->access_request)
64878c2ecf20Sopenharmony_ci		decode_access(xdr, &res->access_supported, &res->access_result);
64888c2ecf20Sopenharmony_ci	decode_getfattr_label(xdr, res->f_attr, res->f_label, res->server);
64898c2ecf20Sopenharmony_ci	if (res->lg_res)
64908c2ecf20Sopenharmony_ci		decode_layoutget(xdr, rqstp, res->lg_res);
64918c2ecf20Sopenharmony_ciout:
64928c2ecf20Sopenharmony_ci	return status;
64938c2ecf20Sopenharmony_ci}
64948c2ecf20Sopenharmony_ci
64958c2ecf20Sopenharmony_ci/*
64968c2ecf20Sopenharmony_ci * Decode OPEN_CONFIRM response
64978c2ecf20Sopenharmony_ci */
64988c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp,
64998c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
65008c2ecf20Sopenharmony_ci				     void *data)
65018c2ecf20Sopenharmony_ci{
65028c2ecf20Sopenharmony_ci	struct nfs_open_confirmres *res = data;
65038c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
65048c2ecf20Sopenharmony_ci	int status;
65058c2ecf20Sopenharmony_ci
65068c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
65078c2ecf20Sopenharmony_ci	if (status)
65088c2ecf20Sopenharmony_ci		goto out;
65098c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
65108c2ecf20Sopenharmony_ci	if (status)
65118c2ecf20Sopenharmony_ci		goto out;
65128c2ecf20Sopenharmony_ci	status = decode_open_confirm(xdr, res);
65138c2ecf20Sopenharmony_ciout:
65148c2ecf20Sopenharmony_ci	return status;
65158c2ecf20Sopenharmony_ci}
65168c2ecf20Sopenharmony_ci
65178c2ecf20Sopenharmony_ci/*
65188c2ecf20Sopenharmony_ci * Decode OPEN response
65198c2ecf20Sopenharmony_ci */
65208c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp,
65218c2ecf20Sopenharmony_ci				    struct xdr_stream *xdr,
65228c2ecf20Sopenharmony_ci				    void *data)
65238c2ecf20Sopenharmony_ci{
65248c2ecf20Sopenharmony_ci	struct nfs_openres *res = data;
65258c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
65268c2ecf20Sopenharmony_ci	int status;
65278c2ecf20Sopenharmony_ci
65288c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
65298c2ecf20Sopenharmony_ci	if (status)
65308c2ecf20Sopenharmony_ci		goto out;
65318c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
65328c2ecf20Sopenharmony_ci	if (status)
65338c2ecf20Sopenharmony_ci		goto out;
65348c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
65358c2ecf20Sopenharmony_ci	if (status)
65368c2ecf20Sopenharmony_ci		goto out;
65378c2ecf20Sopenharmony_ci	status = decode_open(xdr, res);
65388c2ecf20Sopenharmony_ci	if (status)
65398c2ecf20Sopenharmony_ci		goto out;
65408c2ecf20Sopenharmony_ci	if (res->access_request)
65418c2ecf20Sopenharmony_ci		decode_access(xdr, &res->access_supported, &res->access_result);
65428c2ecf20Sopenharmony_ci	decode_getfattr(xdr, res->f_attr, res->server);
65438c2ecf20Sopenharmony_ci	if (res->lg_res)
65448c2ecf20Sopenharmony_ci		decode_layoutget(xdr, rqstp, res->lg_res);
65458c2ecf20Sopenharmony_ciout:
65468c2ecf20Sopenharmony_ci	return status;
65478c2ecf20Sopenharmony_ci}
65488c2ecf20Sopenharmony_ci
65498c2ecf20Sopenharmony_ci/*
65508c2ecf20Sopenharmony_ci * Decode SETATTR response
65518c2ecf20Sopenharmony_ci */
65528c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp,
65538c2ecf20Sopenharmony_ci				struct xdr_stream *xdr,
65548c2ecf20Sopenharmony_ci				void *data)
65558c2ecf20Sopenharmony_ci{
65568c2ecf20Sopenharmony_ci	struct nfs_setattrres *res = data;
65578c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
65588c2ecf20Sopenharmony_ci	int status;
65598c2ecf20Sopenharmony_ci
65608c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
65618c2ecf20Sopenharmony_ci	if (status)
65628c2ecf20Sopenharmony_ci		goto out;
65638c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
65648c2ecf20Sopenharmony_ci	if (status)
65658c2ecf20Sopenharmony_ci		goto out;
65668c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
65678c2ecf20Sopenharmony_ci	if (status)
65688c2ecf20Sopenharmony_ci		goto out;
65698c2ecf20Sopenharmony_ci	status = decode_setattr(xdr);
65708c2ecf20Sopenharmony_ci	if (status)
65718c2ecf20Sopenharmony_ci		goto out;
65728c2ecf20Sopenharmony_ci	decode_getfattr_label(xdr, res->fattr, res->label, res->server);
65738c2ecf20Sopenharmony_ciout:
65748c2ecf20Sopenharmony_ci	return status;
65758c2ecf20Sopenharmony_ci}
65768c2ecf20Sopenharmony_ci
65778c2ecf20Sopenharmony_ci/*
65788c2ecf20Sopenharmony_ci * Decode LOCK response
65798c2ecf20Sopenharmony_ci */
65808c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
65818c2ecf20Sopenharmony_ci			     void *data)
65828c2ecf20Sopenharmony_ci{
65838c2ecf20Sopenharmony_ci	struct nfs_lock_res *res = data;
65848c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
65858c2ecf20Sopenharmony_ci	int status;
65868c2ecf20Sopenharmony_ci
65878c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
65888c2ecf20Sopenharmony_ci	if (status)
65898c2ecf20Sopenharmony_ci		goto out;
65908c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
65918c2ecf20Sopenharmony_ci	if (status)
65928c2ecf20Sopenharmony_ci		goto out;
65938c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
65948c2ecf20Sopenharmony_ci	if (status)
65958c2ecf20Sopenharmony_ci		goto out;
65968c2ecf20Sopenharmony_ci	status = decode_lock(xdr, res);
65978c2ecf20Sopenharmony_ciout:
65988c2ecf20Sopenharmony_ci	return status;
65998c2ecf20Sopenharmony_ci}
66008c2ecf20Sopenharmony_ci
66018c2ecf20Sopenharmony_ci/*
66028c2ecf20Sopenharmony_ci * Decode LOCKT response
66038c2ecf20Sopenharmony_ci */
66048c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
66058c2ecf20Sopenharmony_ci			      void *data)
66068c2ecf20Sopenharmony_ci{
66078c2ecf20Sopenharmony_ci	struct nfs_lockt_res *res = data;
66088c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
66098c2ecf20Sopenharmony_ci	int status;
66108c2ecf20Sopenharmony_ci
66118c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
66128c2ecf20Sopenharmony_ci	if (status)
66138c2ecf20Sopenharmony_ci		goto out;
66148c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
66158c2ecf20Sopenharmony_ci	if (status)
66168c2ecf20Sopenharmony_ci		goto out;
66178c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
66188c2ecf20Sopenharmony_ci	if (status)
66198c2ecf20Sopenharmony_ci		goto out;
66208c2ecf20Sopenharmony_ci	status = decode_lockt(xdr, res);
66218c2ecf20Sopenharmony_ciout:
66228c2ecf20Sopenharmony_ci	return status;
66238c2ecf20Sopenharmony_ci}
66248c2ecf20Sopenharmony_ci
66258c2ecf20Sopenharmony_ci/*
66268c2ecf20Sopenharmony_ci * Decode LOCKU response
66278c2ecf20Sopenharmony_ci */
66288c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
66298c2ecf20Sopenharmony_ci			      void *data)
66308c2ecf20Sopenharmony_ci{
66318c2ecf20Sopenharmony_ci	struct nfs_locku_res *res = data;
66328c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
66338c2ecf20Sopenharmony_ci	int status;
66348c2ecf20Sopenharmony_ci
66358c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
66368c2ecf20Sopenharmony_ci	if (status)
66378c2ecf20Sopenharmony_ci		goto out;
66388c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
66398c2ecf20Sopenharmony_ci	if (status)
66408c2ecf20Sopenharmony_ci		goto out;
66418c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
66428c2ecf20Sopenharmony_ci	if (status)
66438c2ecf20Sopenharmony_ci		goto out;
66448c2ecf20Sopenharmony_ci	status = decode_locku(xdr, res);
66458c2ecf20Sopenharmony_ciout:
66468c2ecf20Sopenharmony_ci	return status;
66478c2ecf20Sopenharmony_ci}
66488c2ecf20Sopenharmony_ci
66498c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp,
66508c2ecf20Sopenharmony_ci					  struct xdr_stream *xdr, void *dummy)
66518c2ecf20Sopenharmony_ci{
66528c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
66538c2ecf20Sopenharmony_ci	int status;
66548c2ecf20Sopenharmony_ci
66558c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
66568c2ecf20Sopenharmony_ci	if (!status)
66578c2ecf20Sopenharmony_ci		status = decode_release_lockowner(xdr);
66588c2ecf20Sopenharmony_ci	return status;
66598c2ecf20Sopenharmony_ci}
66608c2ecf20Sopenharmony_ci
66618c2ecf20Sopenharmony_ci/*
66628c2ecf20Sopenharmony_ci * Decode READLINK response
66638c2ecf20Sopenharmony_ci */
66648c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp,
66658c2ecf20Sopenharmony_ci				 struct xdr_stream *xdr,
66668c2ecf20Sopenharmony_ci				 void *data)
66678c2ecf20Sopenharmony_ci{
66688c2ecf20Sopenharmony_ci	struct nfs4_readlink_res *res = data;
66698c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
66708c2ecf20Sopenharmony_ci	int status;
66718c2ecf20Sopenharmony_ci
66728c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
66738c2ecf20Sopenharmony_ci	if (status)
66748c2ecf20Sopenharmony_ci		goto out;
66758c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
66768c2ecf20Sopenharmony_ci	if (status)
66778c2ecf20Sopenharmony_ci		goto out;
66788c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
66798c2ecf20Sopenharmony_ci	if (status)
66808c2ecf20Sopenharmony_ci		goto out;
66818c2ecf20Sopenharmony_ci	status = decode_readlink(xdr, rqstp);
66828c2ecf20Sopenharmony_ciout:
66838c2ecf20Sopenharmony_ci	return status;
66848c2ecf20Sopenharmony_ci}
66858c2ecf20Sopenharmony_ci
66868c2ecf20Sopenharmony_ci/*
66878c2ecf20Sopenharmony_ci * Decode READDIR response
66888c2ecf20Sopenharmony_ci */
66898c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
66908c2ecf20Sopenharmony_ci				void *data)
66918c2ecf20Sopenharmony_ci{
66928c2ecf20Sopenharmony_ci	struct nfs4_readdir_res *res = data;
66938c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
66948c2ecf20Sopenharmony_ci	int status;
66958c2ecf20Sopenharmony_ci
66968c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
66978c2ecf20Sopenharmony_ci	if (status)
66988c2ecf20Sopenharmony_ci		goto out;
66998c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
67008c2ecf20Sopenharmony_ci	if (status)
67018c2ecf20Sopenharmony_ci		goto out;
67028c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
67038c2ecf20Sopenharmony_ci	if (status)
67048c2ecf20Sopenharmony_ci		goto out;
67058c2ecf20Sopenharmony_ci	status = decode_readdir(xdr, rqstp, res);
67068c2ecf20Sopenharmony_ciout:
67078c2ecf20Sopenharmony_ci	return status;
67088c2ecf20Sopenharmony_ci}
67098c2ecf20Sopenharmony_ci
67108c2ecf20Sopenharmony_ci/*
67118c2ecf20Sopenharmony_ci * Decode Read response
67128c2ecf20Sopenharmony_ci */
67138c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
67148c2ecf20Sopenharmony_ci			     void *data)
67158c2ecf20Sopenharmony_ci{
67168c2ecf20Sopenharmony_ci	struct nfs_pgio_res *res = data;
67178c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
67188c2ecf20Sopenharmony_ci	int status;
67198c2ecf20Sopenharmony_ci
67208c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
67218c2ecf20Sopenharmony_ci	res->op_status = hdr.status;
67228c2ecf20Sopenharmony_ci	if (status)
67238c2ecf20Sopenharmony_ci		goto out;
67248c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
67258c2ecf20Sopenharmony_ci	if (status)
67268c2ecf20Sopenharmony_ci		goto out;
67278c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
67288c2ecf20Sopenharmony_ci	if (status)
67298c2ecf20Sopenharmony_ci		goto out;
67308c2ecf20Sopenharmony_ci	status = decode_read(xdr, rqstp, res);
67318c2ecf20Sopenharmony_ci	if (!status)
67328c2ecf20Sopenharmony_ci		status = res->count;
67338c2ecf20Sopenharmony_ciout:
67348c2ecf20Sopenharmony_ci	return status;
67358c2ecf20Sopenharmony_ci}
67368c2ecf20Sopenharmony_ci
67378c2ecf20Sopenharmony_ci/*
67388c2ecf20Sopenharmony_ci * Decode WRITE response
67398c2ecf20Sopenharmony_ci */
67408c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
67418c2ecf20Sopenharmony_ci			      void *data)
67428c2ecf20Sopenharmony_ci{
67438c2ecf20Sopenharmony_ci	struct nfs_pgio_res *res = data;
67448c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
67458c2ecf20Sopenharmony_ci	int status;
67468c2ecf20Sopenharmony_ci
67478c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
67488c2ecf20Sopenharmony_ci	res->op_status = hdr.status;
67498c2ecf20Sopenharmony_ci	if (status)
67508c2ecf20Sopenharmony_ci		goto out;
67518c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
67528c2ecf20Sopenharmony_ci	if (status)
67538c2ecf20Sopenharmony_ci		goto out;
67548c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
67558c2ecf20Sopenharmony_ci	if (status)
67568c2ecf20Sopenharmony_ci		goto out;
67578c2ecf20Sopenharmony_ci	status = decode_write(xdr, res);
67588c2ecf20Sopenharmony_ci	if (status)
67598c2ecf20Sopenharmony_ci		goto out;
67608c2ecf20Sopenharmony_ci	if (res->fattr)
67618c2ecf20Sopenharmony_ci		decode_getfattr(xdr, res->fattr, res->server);
67628c2ecf20Sopenharmony_ci	if (!status)
67638c2ecf20Sopenharmony_ci		status = res->count;
67648c2ecf20Sopenharmony_ciout:
67658c2ecf20Sopenharmony_ci	return status;
67668c2ecf20Sopenharmony_ci}
67678c2ecf20Sopenharmony_ci
67688c2ecf20Sopenharmony_ci/*
67698c2ecf20Sopenharmony_ci * Decode COMMIT response
67708c2ecf20Sopenharmony_ci */
67718c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
67728c2ecf20Sopenharmony_ci			       void *data)
67738c2ecf20Sopenharmony_ci{
67748c2ecf20Sopenharmony_ci	struct nfs_commitres *res = data;
67758c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
67768c2ecf20Sopenharmony_ci	int status;
67778c2ecf20Sopenharmony_ci
67788c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
67798c2ecf20Sopenharmony_ci	res->op_status = hdr.status;
67808c2ecf20Sopenharmony_ci	if (status)
67818c2ecf20Sopenharmony_ci		goto out;
67828c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
67838c2ecf20Sopenharmony_ci	if (status)
67848c2ecf20Sopenharmony_ci		goto out;
67858c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
67868c2ecf20Sopenharmony_ci	if (status)
67878c2ecf20Sopenharmony_ci		goto out;
67888c2ecf20Sopenharmony_ci	status = decode_commit(xdr, res);
67898c2ecf20Sopenharmony_ciout:
67908c2ecf20Sopenharmony_ci	return status;
67918c2ecf20Sopenharmony_ci}
67928c2ecf20Sopenharmony_ci
67938c2ecf20Sopenharmony_ci/*
67948c2ecf20Sopenharmony_ci * Decode FSINFO response
67958c2ecf20Sopenharmony_ci */
67968c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr,
67978c2ecf20Sopenharmony_ci			       void *data)
67988c2ecf20Sopenharmony_ci{
67998c2ecf20Sopenharmony_ci	struct nfs4_fsinfo_res *res = data;
68008c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
68018c2ecf20Sopenharmony_ci	int status;
68028c2ecf20Sopenharmony_ci
68038c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
68048c2ecf20Sopenharmony_ci	if (!status)
68058c2ecf20Sopenharmony_ci		status = decode_sequence(xdr, &res->seq_res, req);
68068c2ecf20Sopenharmony_ci	if (!status)
68078c2ecf20Sopenharmony_ci		status = decode_putfh(xdr);
68088c2ecf20Sopenharmony_ci	if (!status)
68098c2ecf20Sopenharmony_ci		status = decode_fsinfo(xdr, res->fsinfo);
68108c2ecf20Sopenharmony_ci	return status;
68118c2ecf20Sopenharmony_ci}
68128c2ecf20Sopenharmony_ci
68138c2ecf20Sopenharmony_ci/*
68148c2ecf20Sopenharmony_ci * Decode PATHCONF response
68158c2ecf20Sopenharmony_ci */
68168c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
68178c2ecf20Sopenharmony_ci				 void *data)
68188c2ecf20Sopenharmony_ci{
68198c2ecf20Sopenharmony_ci	struct nfs4_pathconf_res *res = data;
68208c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
68218c2ecf20Sopenharmony_ci	int status;
68228c2ecf20Sopenharmony_ci
68238c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
68248c2ecf20Sopenharmony_ci	if (!status)
68258c2ecf20Sopenharmony_ci		status = decode_sequence(xdr, &res->seq_res, req);
68268c2ecf20Sopenharmony_ci	if (!status)
68278c2ecf20Sopenharmony_ci		status = decode_putfh(xdr);
68288c2ecf20Sopenharmony_ci	if (!status)
68298c2ecf20Sopenharmony_ci		status = decode_pathconf(xdr, res->pathconf);
68308c2ecf20Sopenharmony_ci	return status;
68318c2ecf20Sopenharmony_ci}
68328c2ecf20Sopenharmony_ci
68338c2ecf20Sopenharmony_ci/*
68348c2ecf20Sopenharmony_ci * Decode STATFS response
68358c2ecf20Sopenharmony_ci */
68368c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
68378c2ecf20Sopenharmony_ci			       void *data)
68388c2ecf20Sopenharmony_ci{
68398c2ecf20Sopenharmony_ci	struct nfs4_statfs_res *res = data;
68408c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
68418c2ecf20Sopenharmony_ci	int status;
68428c2ecf20Sopenharmony_ci
68438c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
68448c2ecf20Sopenharmony_ci	if (!status)
68458c2ecf20Sopenharmony_ci		status = decode_sequence(xdr, &res->seq_res, req);
68468c2ecf20Sopenharmony_ci	if (!status)
68478c2ecf20Sopenharmony_ci		status = decode_putfh(xdr);
68488c2ecf20Sopenharmony_ci	if (!status)
68498c2ecf20Sopenharmony_ci		status = decode_statfs(xdr, res->fsstat);
68508c2ecf20Sopenharmony_ci	return status;
68518c2ecf20Sopenharmony_ci}
68528c2ecf20Sopenharmony_ci
68538c2ecf20Sopenharmony_ci/*
68548c2ecf20Sopenharmony_ci * Decode GETATTR_BITMAP response
68558c2ecf20Sopenharmony_ci */
68568c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_server_caps(struct rpc_rqst *req,
68578c2ecf20Sopenharmony_ci				    struct xdr_stream *xdr,
68588c2ecf20Sopenharmony_ci				    void *data)
68598c2ecf20Sopenharmony_ci{
68608c2ecf20Sopenharmony_ci	struct nfs4_server_caps_res *res = data;
68618c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
68628c2ecf20Sopenharmony_ci	int status;
68638c2ecf20Sopenharmony_ci
68648c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
68658c2ecf20Sopenharmony_ci	if (status)
68668c2ecf20Sopenharmony_ci		goto out;
68678c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, req);
68688c2ecf20Sopenharmony_ci	if (status)
68698c2ecf20Sopenharmony_ci		goto out;
68708c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
68718c2ecf20Sopenharmony_ci	if (status)
68728c2ecf20Sopenharmony_ci		goto out;
68738c2ecf20Sopenharmony_ci	status = decode_server_caps(xdr, res);
68748c2ecf20Sopenharmony_ciout:
68758c2ecf20Sopenharmony_ci	return status;
68768c2ecf20Sopenharmony_ci}
68778c2ecf20Sopenharmony_ci
68788c2ecf20Sopenharmony_ci/*
68798c2ecf20Sopenharmony_ci * Decode RENEW response
68808c2ecf20Sopenharmony_ci */
68818c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
68828c2ecf20Sopenharmony_ci			      void *__unused)
68838c2ecf20Sopenharmony_ci{
68848c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
68858c2ecf20Sopenharmony_ci	int status;
68868c2ecf20Sopenharmony_ci
68878c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
68888c2ecf20Sopenharmony_ci	if (!status)
68898c2ecf20Sopenharmony_ci		status = decode_renew(xdr);
68908c2ecf20Sopenharmony_ci	return status;
68918c2ecf20Sopenharmony_ci}
68928c2ecf20Sopenharmony_ci
68938c2ecf20Sopenharmony_ci/*
68948c2ecf20Sopenharmony_ci * Decode SETCLIENTID response
68958c2ecf20Sopenharmony_ci */
68968c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_setclientid(struct rpc_rqst *req,
68978c2ecf20Sopenharmony_ci				    struct xdr_stream *xdr,
68988c2ecf20Sopenharmony_ci				    void *data)
68998c2ecf20Sopenharmony_ci{
69008c2ecf20Sopenharmony_ci	struct nfs4_setclientid_res *res = data;
69018c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
69028c2ecf20Sopenharmony_ci	int status;
69038c2ecf20Sopenharmony_ci
69048c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
69058c2ecf20Sopenharmony_ci	if (!status)
69068c2ecf20Sopenharmony_ci		status = decode_setclientid(xdr, res);
69078c2ecf20Sopenharmony_ci	return status;
69088c2ecf20Sopenharmony_ci}
69098c2ecf20Sopenharmony_ci
69108c2ecf20Sopenharmony_ci/*
69118c2ecf20Sopenharmony_ci * Decode SETCLIENTID_CONFIRM response
69128c2ecf20Sopenharmony_ci */
69138c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req,
69148c2ecf20Sopenharmony_ci					    struct xdr_stream *xdr,
69158c2ecf20Sopenharmony_ci					    void *data)
69168c2ecf20Sopenharmony_ci{
69178c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
69188c2ecf20Sopenharmony_ci	int status;
69198c2ecf20Sopenharmony_ci
69208c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
69218c2ecf20Sopenharmony_ci	if (!status)
69228c2ecf20Sopenharmony_ci		status = decode_setclientid_confirm(xdr);
69238c2ecf20Sopenharmony_ci	return status;
69248c2ecf20Sopenharmony_ci}
69258c2ecf20Sopenharmony_ci
69268c2ecf20Sopenharmony_ci/*
69278c2ecf20Sopenharmony_ci * Decode DELEGRETURN response
69288c2ecf20Sopenharmony_ci */
69298c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp,
69308c2ecf20Sopenharmony_ci				    struct xdr_stream *xdr,
69318c2ecf20Sopenharmony_ci				    void *data)
69328c2ecf20Sopenharmony_ci{
69338c2ecf20Sopenharmony_ci	struct nfs4_delegreturnres *res = data;
69348c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
69358c2ecf20Sopenharmony_ci	int status;
69368c2ecf20Sopenharmony_ci
69378c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
69388c2ecf20Sopenharmony_ci	if (status)
69398c2ecf20Sopenharmony_ci		goto out;
69408c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
69418c2ecf20Sopenharmony_ci	if (status)
69428c2ecf20Sopenharmony_ci		goto out;
69438c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
69448c2ecf20Sopenharmony_ci	if (status != 0)
69458c2ecf20Sopenharmony_ci		goto out;
69468c2ecf20Sopenharmony_ci	if (res->lr_res) {
69478c2ecf20Sopenharmony_ci		status = decode_layoutreturn(xdr, res->lr_res);
69488c2ecf20Sopenharmony_ci		res->lr_ret = status;
69498c2ecf20Sopenharmony_ci		if (status)
69508c2ecf20Sopenharmony_ci			goto out;
69518c2ecf20Sopenharmony_ci	}
69528c2ecf20Sopenharmony_ci	if (res->fattr) {
69538c2ecf20Sopenharmony_ci		status = decode_getfattr(xdr, res->fattr, res->server);
69548c2ecf20Sopenharmony_ci		if (status != 0)
69558c2ecf20Sopenharmony_ci			goto out;
69568c2ecf20Sopenharmony_ci	}
69578c2ecf20Sopenharmony_ci	status = decode_delegreturn(xdr);
69588c2ecf20Sopenharmony_ciout:
69598c2ecf20Sopenharmony_ci	return status;
69608c2ecf20Sopenharmony_ci}
69618c2ecf20Sopenharmony_ci
69628c2ecf20Sopenharmony_ci/*
69638c2ecf20Sopenharmony_ci * Decode FS_LOCATIONS response
69648c2ecf20Sopenharmony_ci */
69658c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
69668c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
69678c2ecf20Sopenharmony_ci				     void *data)
69688c2ecf20Sopenharmony_ci{
69698c2ecf20Sopenharmony_ci	struct nfs4_fs_locations_res *res = data;
69708c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
69718c2ecf20Sopenharmony_ci	int status;
69728c2ecf20Sopenharmony_ci
69738c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
69748c2ecf20Sopenharmony_ci	if (status)
69758c2ecf20Sopenharmony_ci		goto out;
69768c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, req);
69778c2ecf20Sopenharmony_ci	if (status)
69788c2ecf20Sopenharmony_ci		goto out;
69798c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
69808c2ecf20Sopenharmony_ci	if (status)
69818c2ecf20Sopenharmony_ci		goto out;
69828c2ecf20Sopenharmony_ci	if (res->migration) {
69838c2ecf20Sopenharmony_ci		xdr_enter_page(xdr, PAGE_SIZE);
69848c2ecf20Sopenharmony_ci		status = decode_getfattr_generic(xdr,
69858c2ecf20Sopenharmony_ci					&res->fs_locations->fattr,
69868c2ecf20Sopenharmony_ci					 NULL, res->fs_locations,
69878c2ecf20Sopenharmony_ci					 NULL, res->fs_locations->server);
69888c2ecf20Sopenharmony_ci		if (status)
69898c2ecf20Sopenharmony_ci			goto out;
69908c2ecf20Sopenharmony_ci		if (res->renew)
69918c2ecf20Sopenharmony_ci			status = decode_renew(xdr);
69928c2ecf20Sopenharmony_ci	} else {
69938c2ecf20Sopenharmony_ci		status = decode_lookup(xdr);
69948c2ecf20Sopenharmony_ci		if (status)
69958c2ecf20Sopenharmony_ci			goto out;
69968c2ecf20Sopenharmony_ci		xdr_enter_page(xdr, PAGE_SIZE);
69978c2ecf20Sopenharmony_ci		status = decode_getfattr_generic(xdr,
69988c2ecf20Sopenharmony_ci					&res->fs_locations->fattr,
69998c2ecf20Sopenharmony_ci					 NULL, res->fs_locations,
70008c2ecf20Sopenharmony_ci					 NULL, res->fs_locations->server);
70018c2ecf20Sopenharmony_ci	}
70028c2ecf20Sopenharmony_ciout:
70038c2ecf20Sopenharmony_ci	return status;
70048c2ecf20Sopenharmony_ci}
70058c2ecf20Sopenharmony_ci
70068c2ecf20Sopenharmony_ci/*
70078c2ecf20Sopenharmony_ci * Decode SECINFO response
70088c2ecf20Sopenharmony_ci */
70098c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_secinfo(struct rpc_rqst *rqstp,
70108c2ecf20Sopenharmony_ci				struct xdr_stream *xdr,
70118c2ecf20Sopenharmony_ci				void *data)
70128c2ecf20Sopenharmony_ci{
70138c2ecf20Sopenharmony_ci	struct nfs4_secinfo_res *res = data;
70148c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
70158c2ecf20Sopenharmony_ci	int status;
70168c2ecf20Sopenharmony_ci
70178c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
70188c2ecf20Sopenharmony_ci	if (status)
70198c2ecf20Sopenharmony_ci		goto out;
70208c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
70218c2ecf20Sopenharmony_ci	if (status)
70228c2ecf20Sopenharmony_ci		goto out;
70238c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
70248c2ecf20Sopenharmony_ci	if (status)
70258c2ecf20Sopenharmony_ci		goto out;
70268c2ecf20Sopenharmony_ci	status = decode_secinfo(xdr, res);
70278c2ecf20Sopenharmony_ciout:
70288c2ecf20Sopenharmony_ci	return status;
70298c2ecf20Sopenharmony_ci}
70308c2ecf20Sopenharmony_ci
70318c2ecf20Sopenharmony_ci/*
70328c2ecf20Sopenharmony_ci * Decode FSID_PRESENT response
70338c2ecf20Sopenharmony_ci */
70348c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_fsid_present(struct rpc_rqst *rqstp,
70358c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
70368c2ecf20Sopenharmony_ci				     void *data)
70378c2ecf20Sopenharmony_ci{
70388c2ecf20Sopenharmony_ci	struct nfs4_fsid_present_res *res = data;
70398c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
70408c2ecf20Sopenharmony_ci	int status;
70418c2ecf20Sopenharmony_ci
70428c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
70438c2ecf20Sopenharmony_ci	if (status)
70448c2ecf20Sopenharmony_ci		goto out;
70458c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
70468c2ecf20Sopenharmony_ci	if (status)
70478c2ecf20Sopenharmony_ci		goto out;
70488c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
70498c2ecf20Sopenharmony_ci	if (status)
70508c2ecf20Sopenharmony_ci		goto out;
70518c2ecf20Sopenharmony_ci	status = decode_getfh(xdr, res->fh);
70528c2ecf20Sopenharmony_ci	if (status)
70538c2ecf20Sopenharmony_ci		goto out;
70548c2ecf20Sopenharmony_ci	if (res->renew)
70558c2ecf20Sopenharmony_ci		status = decode_renew(xdr);
70568c2ecf20Sopenharmony_ciout:
70578c2ecf20Sopenharmony_ci	return status;
70588c2ecf20Sopenharmony_ci}
70598c2ecf20Sopenharmony_ci
70608c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
70618c2ecf20Sopenharmony_ci/*
70628c2ecf20Sopenharmony_ci * Decode BIND_CONN_TO_SESSION response
70638c2ecf20Sopenharmony_ci */
70648c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_bind_conn_to_session(struct rpc_rqst *rqstp,
70658c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
70668c2ecf20Sopenharmony_ci					void *res)
70678c2ecf20Sopenharmony_ci{
70688c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
70698c2ecf20Sopenharmony_ci	int status;
70708c2ecf20Sopenharmony_ci
70718c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
70728c2ecf20Sopenharmony_ci	if (!status)
70738c2ecf20Sopenharmony_ci		status = decode_bind_conn_to_session(xdr, res);
70748c2ecf20Sopenharmony_ci	return status;
70758c2ecf20Sopenharmony_ci}
70768c2ecf20Sopenharmony_ci
70778c2ecf20Sopenharmony_ci/*
70788c2ecf20Sopenharmony_ci * Decode EXCHANGE_ID response
70798c2ecf20Sopenharmony_ci */
70808c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp,
70818c2ecf20Sopenharmony_ci				    struct xdr_stream *xdr,
70828c2ecf20Sopenharmony_ci				    void *res)
70838c2ecf20Sopenharmony_ci{
70848c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
70858c2ecf20Sopenharmony_ci	int status;
70868c2ecf20Sopenharmony_ci
70878c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
70888c2ecf20Sopenharmony_ci	if (!status)
70898c2ecf20Sopenharmony_ci		status = decode_exchange_id(xdr, res);
70908c2ecf20Sopenharmony_ci	return status;
70918c2ecf20Sopenharmony_ci}
70928c2ecf20Sopenharmony_ci
70938c2ecf20Sopenharmony_ci/*
70948c2ecf20Sopenharmony_ci * Decode CREATE_SESSION response
70958c2ecf20Sopenharmony_ci */
70968c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp,
70978c2ecf20Sopenharmony_ci				       struct xdr_stream *xdr,
70988c2ecf20Sopenharmony_ci				       void *res)
70998c2ecf20Sopenharmony_ci{
71008c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
71018c2ecf20Sopenharmony_ci	int status;
71028c2ecf20Sopenharmony_ci
71038c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
71048c2ecf20Sopenharmony_ci	if (!status)
71058c2ecf20Sopenharmony_ci		status = decode_create_session(xdr, res);
71068c2ecf20Sopenharmony_ci	return status;
71078c2ecf20Sopenharmony_ci}
71088c2ecf20Sopenharmony_ci
71098c2ecf20Sopenharmony_ci/*
71108c2ecf20Sopenharmony_ci * Decode DESTROY_SESSION response
71118c2ecf20Sopenharmony_ci */
71128c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp,
71138c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
71148c2ecf20Sopenharmony_ci					void *res)
71158c2ecf20Sopenharmony_ci{
71168c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
71178c2ecf20Sopenharmony_ci	int status;
71188c2ecf20Sopenharmony_ci
71198c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
71208c2ecf20Sopenharmony_ci	if (!status)
71218c2ecf20Sopenharmony_ci		status = decode_destroy_session(xdr, res);
71228c2ecf20Sopenharmony_ci	return status;
71238c2ecf20Sopenharmony_ci}
71248c2ecf20Sopenharmony_ci
71258c2ecf20Sopenharmony_ci/*
71268c2ecf20Sopenharmony_ci * Decode DESTROY_CLIENTID response
71278c2ecf20Sopenharmony_ci */
71288c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_destroy_clientid(struct rpc_rqst *rqstp,
71298c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
71308c2ecf20Sopenharmony_ci					void *res)
71318c2ecf20Sopenharmony_ci{
71328c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
71338c2ecf20Sopenharmony_ci	int status;
71348c2ecf20Sopenharmony_ci
71358c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
71368c2ecf20Sopenharmony_ci	if (!status)
71378c2ecf20Sopenharmony_ci		status = decode_destroy_clientid(xdr, res);
71388c2ecf20Sopenharmony_ci	return status;
71398c2ecf20Sopenharmony_ci}
71408c2ecf20Sopenharmony_ci
71418c2ecf20Sopenharmony_ci/*
71428c2ecf20Sopenharmony_ci * Decode SEQUENCE response
71438c2ecf20Sopenharmony_ci */
71448c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp,
71458c2ecf20Sopenharmony_ci				 struct xdr_stream *xdr,
71468c2ecf20Sopenharmony_ci				 void *res)
71478c2ecf20Sopenharmony_ci{
71488c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
71498c2ecf20Sopenharmony_ci	int status;
71508c2ecf20Sopenharmony_ci
71518c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
71528c2ecf20Sopenharmony_ci	if (!status)
71538c2ecf20Sopenharmony_ci		status = decode_sequence(xdr, res, rqstp);
71548c2ecf20Sopenharmony_ci	return status;
71558c2ecf20Sopenharmony_ci}
71568c2ecf20Sopenharmony_ci
71578c2ecf20Sopenharmony_ci#endif
71588c2ecf20Sopenharmony_ci
71598c2ecf20Sopenharmony_ci/*
71608c2ecf20Sopenharmony_ci * Decode GET_LEASE_TIME response
71618c2ecf20Sopenharmony_ci */
71628c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp,
71638c2ecf20Sopenharmony_ci				       struct xdr_stream *xdr,
71648c2ecf20Sopenharmony_ci				       void *data)
71658c2ecf20Sopenharmony_ci{
71668c2ecf20Sopenharmony_ci	struct nfs4_get_lease_time_res *res = data;
71678c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
71688c2ecf20Sopenharmony_ci	int status;
71698c2ecf20Sopenharmony_ci
71708c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
71718c2ecf20Sopenharmony_ci	if (!status)
71728c2ecf20Sopenharmony_ci		status = decode_sequence(xdr, &res->lr_seq_res, rqstp);
71738c2ecf20Sopenharmony_ci	if (!status)
71748c2ecf20Sopenharmony_ci		status = decode_putrootfh(xdr);
71758c2ecf20Sopenharmony_ci	if (!status)
71768c2ecf20Sopenharmony_ci		status = decode_fsinfo(xdr, res->lr_fsinfo);
71778c2ecf20Sopenharmony_ci	return status;
71788c2ecf20Sopenharmony_ci}
71798c2ecf20Sopenharmony_ci
71808c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_1
71818c2ecf20Sopenharmony_ci
71828c2ecf20Sopenharmony_ci/*
71838c2ecf20Sopenharmony_ci * Decode RECLAIM_COMPLETE response
71848c2ecf20Sopenharmony_ci */
71858c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp,
71868c2ecf20Sopenharmony_ci					 struct xdr_stream *xdr,
71878c2ecf20Sopenharmony_ci					 void *data)
71888c2ecf20Sopenharmony_ci{
71898c2ecf20Sopenharmony_ci	struct nfs41_reclaim_complete_res *res = data;
71908c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
71918c2ecf20Sopenharmony_ci	int status;
71928c2ecf20Sopenharmony_ci
71938c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
71948c2ecf20Sopenharmony_ci	if (!status)
71958c2ecf20Sopenharmony_ci		status = decode_sequence(xdr, &res->seq_res, rqstp);
71968c2ecf20Sopenharmony_ci	if (!status)
71978c2ecf20Sopenharmony_ci		status = decode_reclaim_complete(xdr, NULL);
71988c2ecf20Sopenharmony_ci	return status;
71998c2ecf20Sopenharmony_ci}
72008c2ecf20Sopenharmony_ci
72018c2ecf20Sopenharmony_ci/*
72028c2ecf20Sopenharmony_ci * Decode GETDEVINFO response
72038c2ecf20Sopenharmony_ci */
72048c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp,
72058c2ecf20Sopenharmony_ci				      struct xdr_stream *xdr,
72068c2ecf20Sopenharmony_ci				      void *data)
72078c2ecf20Sopenharmony_ci{
72088c2ecf20Sopenharmony_ci	struct nfs4_getdeviceinfo_res *res = data;
72098c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
72108c2ecf20Sopenharmony_ci	int status;
72118c2ecf20Sopenharmony_ci
72128c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
72138c2ecf20Sopenharmony_ci	if (status != 0)
72148c2ecf20Sopenharmony_ci		goto out;
72158c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
72168c2ecf20Sopenharmony_ci	if (status != 0)
72178c2ecf20Sopenharmony_ci		goto out;
72188c2ecf20Sopenharmony_ci	status = decode_getdeviceinfo(xdr, res);
72198c2ecf20Sopenharmony_ciout:
72208c2ecf20Sopenharmony_ci	return status;
72218c2ecf20Sopenharmony_ci}
72228c2ecf20Sopenharmony_ci
72238c2ecf20Sopenharmony_ci/*
72248c2ecf20Sopenharmony_ci * Decode LAYOUTGET response
72258c2ecf20Sopenharmony_ci */
72268c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp,
72278c2ecf20Sopenharmony_ci				  struct xdr_stream *xdr,
72288c2ecf20Sopenharmony_ci				  void *data)
72298c2ecf20Sopenharmony_ci{
72308c2ecf20Sopenharmony_ci	struct nfs4_layoutget_res *res = data;
72318c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
72328c2ecf20Sopenharmony_ci	int status;
72338c2ecf20Sopenharmony_ci
72348c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
72358c2ecf20Sopenharmony_ci	if (status)
72368c2ecf20Sopenharmony_ci		goto out;
72378c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
72388c2ecf20Sopenharmony_ci	if (status)
72398c2ecf20Sopenharmony_ci		goto out;
72408c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
72418c2ecf20Sopenharmony_ci	if (status)
72428c2ecf20Sopenharmony_ci		goto out;
72438c2ecf20Sopenharmony_ci	status = decode_layoutget(xdr, rqstp, res);
72448c2ecf20Sopenharmony_ciout:
72458c2ecf20Sopenharmony_ci	return status;
72468c2ecf20Sopenharmony_ci}
72478c2ecf20Sopenharmony_ci
72488c2ecf20Sopenharmony_ci/*
72498c2ecf20Sopenharmony_ci * Decode LAYOUTRETURN response
72508c2ecf20Sopenharmony_ci */
72518c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp,
72528c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
72538c2ecf20Sopenharmony_ci				     void *data)
72548c2ecf20Sopenharmony_ci{
72558c2ecf20Sopenharmony_ci	struct nfs4_layoutreturn_res *res = data;
72568c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
72578c2ecf20Sopenharmony_ci	int status;
72588c2ecf20Sopenharmony_ci
72598c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
72608c2ecf20Sopenharmony_ci	if (status)
72618c2ecf20Sopenharmony_ci		goto out;
72628c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
72638c2ecf20Sopenharmony_ci	if (status)
72648c2ecf20Sopenharmony_ci		goto out;
72658c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
72668c2ecf20Sopenharmony_ci	if (status)
72678c2ecf20Sopenharmony_ci		goto out;
72688c2ecf20Sopenharmony_ci	status = decode_layoutreturn(xdr, res);
72698c2ecf20Sopenharmony_ciout:
72708c2ecf20Sopenharmony_ci	return status;
72718c2ecf20Sopenharmony_ci}
72728c2ecf20Sopenharmony_ci
72738c2ecf20Sopenharmony_ci/*
72748c2ecf20Sopenharmony_ci * Decode LAYOUTCOMMIT response
72758c2ecf20Sopenharmony_ci */
72768c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
72778c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
72788c2ecf20Sopenharmony_ci				     void *data)
72798c2ecf20Sopenharmony_ci{
72808c2ecf20Sopenharmony_ci	struct nfs4_layoutcommit_res *res = data;
72818c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
72828c2ecf20Sopenharmony_ci	int status;
72838c2ecf20Sopenharmony_ci
72848c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
72858c2ecf20Sopenharmony_ci	if (status)
72868c2ecf20Sopenharmony_ci		goto out;
72878c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
72888c2ecf20Sopenharmony_ci	if (status)
72898c2ecf20Sopenharmony_ci		goto out;
72908c2ecf20Sopenharmony_ci	status = decode_putfh(xdr);
72918c2ecf20Sopenharmony_ci	if (status)
72928c2ecf20Sopenharmony_ci		goto out;
72938c2ecf20Sopenharmony_ci	status = decode_layoutcommit(xdr, rqstp, res);
72948c2ecf20Sopenharmony_ci	if (status)
72958c2ecf20Sopenharmony_ci		goto out;
72968c2ecf20Sopenharmony_ci	decode_getfattr(xdr, res->fattr, res->server);
72978c2ecf20Sopenharmony_ciout:
72988c2ecf20Sopenharmony_ci	return status;
72998c2ecf20Sopenharmony_ci}
73008c2ecf20Sopenharmony_ci
73018c2ecf20Sopenharmony_ci/*
73028c2ecf20Sopenharmony_ci * Decode SECINFO_NO_NAME response
73038c2ecf20Sopenharmony_ci */
73048c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp,
73058c2ecf20Sopenharmony_ci					struct xdr_stream *xdr,
73068c2ecf20Sopenharmony_ci					void *data)
73078c2ecf20Sopenharmony_ci{
73088c2ecf20Sopenharmony_ci	struct nfs4_secinfo_res *res = data;
73098c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
73108c2ecf20Sopenharmony_ci	int status;
73118c2ecf20Sopenharmony_ci
73128c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
73138c2ecf20Sopenharmony_ci	if (status)
73148c2ecf20Sopenharmony_ci		goto out;
73158c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
73168c2ecf20Sopenharmony_ci	if (status)
73178c2ecf20Sopenharmony_ci		goto out;
73188c2ecf20Sopenharmony_ci	status = decode_putrootfh(xdr);
73198c2ecf20Sopenharmony_ci	if (status)
73208c2ecf20Sopenharmony_ci		goto out;
73218c2ecf20Sopenharmony_ci	status = decode_secinfo_no_name(xdr, res);
73228c2ecf20Sopenharmony_ciout:
73238c2ecf20Sopenharmony_ci	return status;
73248c2ecf20Sopenharmony_ci}
73258c2ecf20Sopenharmony_ci
73268c2ecf20Sopenharmony_ci/*
73278c2ecf20Sopenharmony_ci * Decode TEST_STATEID response
73288c2ecf20Sopenharmony_ci */
73298c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp,
73308c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
73318c2ecf20Sopenharmony_ci				     void *data)
73328c2ecf20Sopenharmony_ci{
73338c2ecf20Sopenharmony_ci	struct nfs41_test_stateid_res *res = data;
73348c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
73358c2ecf20Sopenharmony_ci	int status;
73368c2ecf20Sopenharmony_ci
73378c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
73388c2ecf20Sopenharmony_ci	if (status)
73398c2ecf20Sopenharmony_ci		goto out;
73408c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
73418c2ecf20Sopenharmony_ci	if (status)
73428c2ecf20Sopenharmony_ci		goto out;
73438c2ecf20Sopenharmony_ci	status = decode_test_stateid(xdr, res);
73448c2ecf20Sopenharmony_ciout:
73458c2ecf20Sopenharmony_ci	return status;
73468c2ecf20Sopenharmony_ci}
73478c2ecf20Sopenharmony_ci
73488c2ecf20Sopenharmony_ci/*
73498c2ecf20Sopenharmony_ci * Decode FREE_STATEID response
73508c2ecf20Sopenharmony_ci */
73518c2ecf20Sopenharmony_cistatic int nfs4_xdr_dec_free_stateid(struct rpc_rqst *rqstp,
73528c2ecf20Sopenharmony_ci				     struct xdr_stream *xdr,
73538c2ecf20Sopenharmony_ci				     void *data)
73548c2ecf20Sopenharmony_ci{
73558c2ecf20Sopenharmony_ci	struct nfs41_free_stateid_res *res = data;
73568c2ecf20Sopenharmony_ci	struct compound_hdr hdr;
73578c2ecf20Sopenharmony_ci	int status;
73588c2ecf20Sopenharmony_ci
73598c2ecf20Sopenharmony_ci	status = decode_compound_hdr(xdr, &hdr);
73608c2ecf20Sopenharmony_ci	if (status)
73618c2ecf20Sopenharmony_ci		goto out;
73628c2ecf20Sopenharmony_ci	status = decode_sequence(xdr, &res->seq_res, rqstp);
73638c2ecf20Sopenharmony_ci	if (status)
73648c2ecf20Sopenharmony_ci		goto out;
73658c2ecf20Sopenharmony_ci	status = decode_free_stateid(xdr, res);
73668c2ecf20Sopenharmony_ciout:
73678c2ecf20Sopenharmony_ci	return status;
73688c2ecf20Sopenharmony_ci}
73698c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */
73708c2ecf20Sopenharmony_ci
73718c2ecf20Sopenharmony_ci/**
73728c2ecf20Sopenharmony_ci * nfs4_decode_dirent - Decode a single NFSv4 directory entry stored in
73738c2ecf20Sopenharmony_ci *                      the local page cache.
73748c2ecf20Sopenharmony_ci * @xdr: XDR stream where entry resides
73758c2ecf20Sopenharmony_ci * @entry: buffer to fill in with entry data
73768c2ecf20Sopenharmony_ci * @plus: boolean indicating whether this should be a readdirplus entry
73778c2ecf20Sopenharmony_ci *
73788c2ecf20Sopenharmony_ci * Returns zero if successful, otherwise a negative errno value is
73798c2ecf20Sopenharmony_ci * returned.
73808c2ecf20Sopenharmony_ci *
73818c2ecf20Sopenharmony_ci * This function is not invoked during READDIR reply decoding, but
73828c2ecf20Sopenharmony_ci * rather whenever an application invokes the getdents(2) system call
73838c2ecf20Sopenharmony_ci * on a directory already in our cache.
73848c2ecf20Sopenharmony_ci */
73858c2ecf20Sopenharmony_ciint nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
73868c2ecf20Sopenharmony_ci		       bool plus)
73878c2ecf20Sopenharmony_ci{
73888c2ecf20Sopenharmony_ci	unsigned int savep;
73898c2ecf20Sopenharmony_ci	uint32_t bitmap[3] = {0};
73908c2ecf20Sopenharmony_ci	uint32_t len;
73918c2ecf20Sopenharmony_ci	uint64_t new_cookie;
73928c2ecf20Sopenharmony_ci	__be32 *p = xdr_inline_decode(xdr, 4);
73938c2ecf20Sopenharmony_ci	if (unlikely(!p))
73948c2ecf20Sopenharmony_ci		return -EAGAIN;
73958c2ecf20Sopenharmony_ci	if (*p == xdr_zero) {
73968c2ecf20Sopenharmony_ci		p = xdr_inline_decode(xdr, 4);
73978c2ecf20Sopenharmony_ci		if (unlikely(!p))
73988c2ecf20Sopenharmony_ci			return -EAGAIN;
73998c2ecf20Sopenharmony_ci		if (*p == xdr_zero)
74008c2ecf20Sopenharmony_ci			return -EAGAIN;
74018c2ecf20Sopenharmony_ci		entry->eof = 1;
74028c2ecf20Sopenharmony_ci		return -EBADCOOKIE;
74038c2ecf20Sopenharmony_ci	}
74048c2ecf20Sopenharmony_ci
74058c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, 12);
74068c2ecf20Sopenharmony_ci	if (unlikely(!p))
74078c2ecf20Sopenharmony_ci		return -EAGAIN;
74088c2ecf20Sopenharmony_ci	p = xdr_decode_hyper(p, &new_cookie);
74098c2ecf20Sopenharmony_ci	entry->len = be32_to_cpup(p);
74108c2ecf20Sopenharmony_ci
74118c2ecf20Sopenharmony_ci	p = xdr_inline_decode(xdr, entry->len);
74128c2ecf20Sopenharmony_ci	if (unlikely(!p))
74138c2ecf20Sopenharmony_ci		return -EAGAIN;
74148c2ecf20Sopenharmony_ci	entry->name = (const char *) p;
74158c2ecf20Sopenharmony_ci
74168c2ecf20Sopenharmony_ci	/*
74178c2ecf20Sopenharmony_ci	 * In case the server doesn't return an inode number,
74188c2ecf20Sopenharmony_ci	 * we fake one here.  (We don't use inode number 0,
74198c2ecf20Sopenharmony_ci	 * since glibc seems to choke on it...)
74208c2ecf20Sopenharmony_ci	 */
74218c2ecf20Sopenharmony_ci	entry->ino = 1;
74228c2ecf20Sopenharmony_ci	entry->fattr->valid = 0;
74238c2ecf20Sopenharmony_ci
74248c2ecf20Sopenharmony_ci	if (decode_attr_bitmap(xdr, bitmap) < 0)
74258c2ecf20Sopenharmony_ci		return -EAGAIN;
74268c2ecf20Sopenharmony_ci
74278c2ecf20Sopenharmony_ci	if (decode_attr_length(xdr, &len, &savep) < 0)
74288c2ecf20Sopenharmony_ci		return -EAGAIN;
74298c2ecf20Sopenharmony_ci
74308c2ecf20Sopenharmony_ci	if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
74318c2ecf20Sopenharmony_ci			NULL, entry->label, entry->server) < 0)
74328c2ecf20Sopenharmony_ci		return -EAGAIN;
74338c2ecf20Sopenharmony_ci	if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
74348c2ecf20Sopenharmony_ci		entry->ino = entry->fattr->mounted_on_fileid;
74358c2ecf20Sopenharmony_ci	else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
74368c2ecf20Sopenharmony_ci		entry->ino = entry->fattr->fileid;
74378c2ecf20Sopenharmony_ci
74388c2ecf20Sopenharmony_ci	entry->d_type = DT_UNKNOWN;
74398c2ecf20Sopenharmony_ci	if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE)
74408c2ecf20Sopenharmony_ci		entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
74418c2ecf20Sopenharmony_ci
74428c2ecf20Sopenharmony_ci	entry->prev_cookie = entry->cookie;
74438c2ecf20Sopenharmony_ci	entry->cookie = new_cookie;
74448c2ecf20Sopenharmony_ci
74458c2ecf20Sopenharmony_ci	return 0;
74468c2ecf20Sopenharmony_ci}
74478c2ecf20Sopenharmony_ci
74488c2ecf20Sopenharmony_ci/*
74498c2ecf20Sopenharmony_ci * We need to translate between nfs status return values and
74508c2ecf20Sopenharmony_ci * the local errno values which may not be the same.
74518c2ecf20Sopenharmony_ci */
74528c2ecf20Sopenharmony_cistatic struct {
74538c2ecf20Sopenharmony_ci	int stat;
74548c2ecf20Sopenharmony_ci	int errno;
74558c2ecf20Sopenharmony_ci} nfs_errtbl[] = {
74568c2ecf20Sopenharmony_ci	{ NFS4_OK,		0		},
74578c2ecf20Sopenharmony_ci	{ NFS4ERR_PERM,		-EPERM		},
74588c2ecf20Sopenharmony_ci	{ NFS4ERR_NOENT,	-ENOENT		},
74598c2ecf20Sopenharmony_ci	{ NFS4ERR_IO,		-errno_NFSERR_IO},
74608c2ecf20Sopenharmony_ci	{ NFS4ERR_NXIO,		-ENXIO		},
74618c2ecf20Sopenharmony_ci	{ NFS4ERR_ACCESS,	-EACCES		},
74628c2ecf20Sopenharmony_ci	{ NFS4ERR_EXIST,	-EEXIST		},
74638c2ecf20Sopenharmony_ci	{ NFS4ERR_XDEV,		-EXDEV		},
74648c2ecf20Sopenharmony_ci	{ NFS4ERR_NOTDIR,	-ENOTDIR	},
74658c2ecf20Sopenharmony_ci	{ NFS4ERR_ISDIR,	-EISDIR		},
74668c2ecf20Sopenharmony_ci	{ NFS4ERR_INVAL,	-EINVAL		},
74678c2ecf20Sopenharmony_ci	{ NFS4ERR_FBIG,		-EFBIG		},
74688c2ecf20Sopenharmony_ci	{ NFS4ERR_NOSPC,	-ENOSPC		},
74698c2ecf20Sopenharmony_ci	{ NFS4ERR_ROFS,		-EROFS		},
74708c2ecf20Sopenharmony_ci	{ NFS4ERR_MLINK,	-EMLINK		},
74718c2ecf20Sopenharmony_ci	{ NFS4ERR_NAMETOOLONG,	-ENAMETOOLONG	},
74728c2ecf20Sopenharmony_ci	{ NFS4ERR_NOTEMPTY,	-ENOTEMPTY	},
74738c2ecf20Sopenharmony_ci	{ NFS4ERR_DQUOT,	-EDQUOT		},
74748c2ecf20Sopenharmony_ci	{ NFS4ERR_STALE,	-ESTALE		},
74758c2ecf20Sopenharmony_ci	{ NFS4ERR_BADHANDLE,	-EBADHANDLE	},
74768c2ecf20Sopenharmony_ci	{ NFS4ERR_BAD_COOKIE,	-EBADCOOKIE	},
74778c2ecf20Sopenharmony_ci	{ NFS4ERR_NOTSUPP,	-ENOTSUPP	},
74788c2ecf20Sopenharmony_ci	{ NFS4ERR_TOOSMALL,	-ETOOSMALL	},
74798c2ecf20Sopenharmony_ci	{ NFS4ERR_SERVERFAULT,	-EREMOTEIO	},
74808c2ecf20Sopenharmony_ci	{ NFS4ERR_BADTYPE,	-EBADTYPE	},
74818c2ecf20Sopenharmony_ci	{ NFS4ERR_LOCKED,	-EAGAIN		},
74828c2ecf20Sopenharmony_ci	{ NFS4ERR_SYMLINK,	-ELOOP		},
74838c2ecf20Sopenharmony_ci	{ NFS4ERR_OP_ILLEGAL,	-EOPNOTSUPP	},
74848c2ecf20Sopenharmony_ci	{ NFS4ERR_DEADLOCK,	-EDEADLK	},
74858c2ecf20Sopenharmony_ci	{ NFS4ERR_NOXATTR,	-ENODATA	},
74868c2ecf20Sopenharmony_ci	{ NFS4ERR_XATTR2BIG,	-E2BIG		},
74878c2ecf20Sopenharmony_ci	{ -1,			-EIO		}
74888c2ecf20Sopenharmony_ci};
74898c2ecf20Sopenharmony_ci
74908c2ecf20Sopenharmony_ci/*
74918c2ecf20Sopenharmony_ci * Convert an NFS error code to a local one.
74928c2ecf20Sopenharmony_ci * This one is used jointly by NFSv2 and NFSv3.
74938c2ecf20Sopenharmony_ci */
74948c2ecf20Sopenharmony_cistatic int
74958c2ecf20Sopenharmony_cinfs4_stat_to_errno(int stat)
74968c2ecf20Sopenharmony_ci{
74978c2ecf20Sopenharmony_ci	int i;
74988c2ecf20Sopenharmony_ci	for (i = 0; nfs_errtbl[i].stat != -1; i++) {
74998c2ecf20Sopenharmony_ci		if (nfs_errtbl[i].stat == stat)
75008c2ecf20Sopenharmony_ci			return nfs_errtbl[i].errno;
75018c2ecf20Sopenharmony_ci	}
75028c2ecf20Sopenharmony_ci	if (stat <= 10000 || stat > 10100) {
75038c2ecf20Sopenharmony_ci		/* The server is looney tunes. */
75048c2ecf20Sopenharmony_ci		return -EREMOTEIO;
75058c2ecf20Sopenharmony_ci	}
75068c2ecf20Sopenharmony_ci	/* If we cannot translate the error, the recovery routines should
75078c2ecf20Sopenharmony_ci	 * handle it.
75088c2ecf20Sopenharmony_ci	 * Note: remaining NFSv4 error codes have values > 10000, so should
75098c2ecf20Sopenharmony_ci	 * not conflict with native Linux error codes.
75108c2ecf20Sopenharmony_ci	 */
75118c2ecf20Sopenharmony_ci	return -stat;
75128c2ecf20Sopenharmony_ci}
75138c2ecf20Sopenharmony_ci
75148c2ecf20Sopenharmony_ci#ifdef CONFIG_NFS_V4_2
75158c2ecf20Sopenharmony_ci#include "nfs42xdr.c"
75168c2ecf20Sopenharmony_ci#endif /* CONFIG_NFS_V4_2 */
75178c2ecf20Sopenharmony_ci
75188c2ecf20Sopenharmony_ci#define PROC(proc, argtype, restype)				\
75198c2ecf20Sopenharmony_ci[NFSPROC4_CLNT_##proc] = {					\
75208c2ecf20Sopenharmony_ci	.p_proc   = NFSPROC4_COMPOUND,				\
75218c2ecf20Sopenharmony_ci	.p_encode = nfs4_xdr_##argtype,				\
75228c2ecf20Sopenharmony_ci	.p_decode = nfs4_xdr_##restype,				\
75238c2ecf20Sopenharmony_ci	.p_arglen = NFS4_##argtype##_sz,			\
75248c2ecf20Sopenharmony_ci	.p_replen = NFS4_##restype##_sz,			\
75258c2ecf20Sopenharmony_ci	.p_statidx = NFSPROC4_CLNT_##proc,			\
75268c2ecf20Sopenharmony_ci	.p_name   = #proc,					\
75278c2ecf20Sopenharmony_ci}
75288c2ecf20Sopenharmony_ci
75298c2ecf20Sopenharmony_ci#define STUB(proc)		\
75308c2ecf20Sopenharmony_ci[NFSPROC4_CLNT_##proc] = {	\
75318c2ecf20Sopenharmony_ci	.p_name = #proc,	\
75328c2ecf20Sopenharmony_ci}
75338c2ecf20Sopenharmony_ci
75348c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_1)
75358c2ecf20Sopenharmony_ci#define PROC41(proc, argtype, restype)				\
75368c2ecf20Sopenharmony_ci	PROC(proc, argtype, restype)
75378c2ecf20Sopenharmony_ci#else
75388c2ecf20Sopenharmony_ci#define PROC41(proc, argtype, restype)				\
75398c2ecf20Sopenharmony_ci	STUB(proc)
75408c2ecf20Sopenharmony_ci#endif
75418c2ecf20Sopenharmony_ci
75428c2ecf20Sopenharmony_ci#if defined(CONFIG_NFS_V4_2)
75438c2ecf20Sopenharmony_ci#define PROC42(proc, argtype, restype)				\
75448c2ecf20Sopenharmony_ci	PROC(proc, argtype, restype)
75458c2ecf20Sopenharmony_ci#else
75468c2ecf20Sopenharmony_ci#define PROC42(proc, argtype, restype)				\
75478c2ecf20Sopenharmony_ci	STUB(proc)
75488c2ecf20Sopenharmony_ci#endif
75498c2ecf20Sopenharmony_ci
75508c2ecf20Sopenharmony_ciconst struct rpc_procinfo nfs4_procedures[] = {
75518c2ecf20Sopenharmony_ci	PROC(READ,		enc_read,		dec_read),
75528c2ecf20Sopenharmony_ci	PROC(WRITE,		enc_write,		dec_write),
75538c2ecf20Sopenharmony_ci	PROC(COMMIT,		enc_commit,		dec_commit),
75548c2ecf20Sopenharmony_ci	PROC(OPEN,		enc_open,		dec_open),
75558c2ecf20Sopenharmony_ci	PROC(OPEN_CONFIRM,	enc_open_confirm,	dec_open_confirm),
75568c2ecf20Sopenharmony_ci	PROC(OPEN_NOATTR,	enc_open_noattr,	dec_open_noattr),
75578c2ecf20Sopenharmony_ci	PROC(OPEN_DOWNGRADE,	enc_open_downgrade,	dec_open_downgrade),
75588c2ecf20Sopenharmony_ci	PROC(CLOSE,		enc_close,		dec_close),
75598c2ecf20Sopenharmony_ci	PROC(SETATTR,		enc_setattr,		dec_setattr),
75608c2ecf20Sopenharmony_ci	PROC(FSINFO,		enc_fsinfo,		dec_fsinfo),
75618c2ecf20Sopenharmony_ci	PROC(RENEW,		enc_renew,		dec_renew),
75628c2ecf20Sopenharmony_ci	PROC(SETCLIENTID,	enc_setclientid,	dec_setclientid),
75638c2ecf20Sopenharmony_ci	PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm),
75648c2ecf20Sopenharmony_ci	PROC(LOCK,		enc_lock,		dec_lock),
75658c2ecf20Sopenharmony_ci	PROC(LOCKT,		enc_lockt,		dec_lockt),
75668c2ecf20Sopenharmony_ci	PROC(LOCKU,		enc_locku,		dec_locku),
75678c2ecf20Sopenharmony_ci	PROC(ACCESS,		enc_access,		dec_access),
75688c2ecf20Sopenharmony_ci	PROC(GETATTR,		enc_getattr,		dec_getattr),
75698c2ecf20Sopenharmony_ci	PROC(LOOKUP,		enc_lookup,		dec_lookup),
75708c2ecf20Sopenharmony_ci	PROC(LOOKUP_ROOT,	enc_lookup_root,	dec_lookup_root),
75718c2ecf20Sopenharmony_ci	PROC(REMOVE,		enc_remove,		dec_remove),
75728c2ecf20Sopenharmony_ci	PROC(RENAME,		enc_rename,		dec_rename),
75738c2ecf20Sopenharmony_ci	PROC(LINK,		enc_link,		dec_link),
75748c2ecf20Sopenharmony_ci	PROC(SYMLINK,		enc_symlink,		dec_symlink),
75758c2ecf20Sopenharmony_ci	PROC(CREATE,		enc_create,		dec_create),
75768c2ecf20Sopenharmony_ci	PROC(PATHCONF,		enc_pathconf,		dec_pathconf),
75778c2ecf20Sopenharmony_ci	PROC(STATFS,		enc_statfs,		dec_statfs),
75788c2ecf20Sopenharmony_ci	PROC(READLINK,		enc_readlink,		dec_readlink),
75798c2ecf20Sopenharmony_ci	PROC(READDIR,		enc_readdir,		dec_readdir),
75808c2ecf20Sopenharmony_ci	PROC(SERVER_CAPS,	enc_server_caps,	dec_server_caps),
75818c2ecf20Sopenharmony_ci	PROC(DELEGRETURN,	enc_delegreturn,	dec_delegreturn),
75828c2ecf20Sopenharmony_ci	PROC(GETACL,		enc_getacl,		dec_getacl),
75838c2ecf20Sopenharmony_ci	PROC(SETACL,		enc_setacl,		dec_setacl),
75848c2ecf20Sopenharmony_ci	PROC(FS_LOCATIONS,	enc_fs_locations,	dec_fs_locations),
75858c2ecf20Sopenharmony_ci	PROC(RELEASE_LOCKOWNER,	enc_release_lockowner,	dec_release_lockowner),
75868c2ecf20Sopenharmony_ci	PROC(SECINFO,		enc_secinfo,		dec_secinfo),
75878c2ecf20Sopenharmony_ci	PROC(FSID_PRESENT,	enc_fsid_present,	dec_fsid_present),
75888c2ecf20Sopenharmony_ci	PROC41(EXCHANGE_ID,	enc_exchange_id,	dec_exchange_id),
75898c2ecf20Sopenharmony_ci	PROC41(CREATE_SESSION,	enc_create_session,	dec_create_session),
75908c2ecf20Sopenharmony_ci	PROC41(DESTROY_SESSION,	enc_destroy_session,	dec_destroy_session),
75918c2ecf20Sopenharmony_ci	PROC41(SEQUENCE,	enc_sequence,		dec_sequence),
75928c2ecf20Sopenharmony_ci	PROC(GET_LEASE_TIME,	enc_get_lease_time,	dec_get_lease_time),
75938c2ecf20Sopenharmony_ci	PROC41(RECLAIM_COMPLETE,enc_reclaim_complete,	dec_reclaim_complete),
75948c2ecf20Sopenharmony_ci	PROC41(GETDEVICEINFO,	enc_getdeviceinfo,	dec_getdeviceinfo),
75958c2ecf20Sopenharmony_ci	PROC41(LAYOUTGET,	enc_layoutget,		dec_layoutget),
75968c2ecf20Sopenharmony_ci	PROC41(LAYOUTCOMMIT,	enc_layoutcommit,	dec_layoutcommit),
75978c2ecf20Sopenharmony_ci	PROC41(LAYOUTRETURN,	enc_layoutreturn,	dec_layoutreturn),
75988c2ecf20Sopenharmony_ci	PROC41(SECINFO_NO_NAME,	enc_secinfo_no_name,	dec_secinfo_no_name),
75998c2ecf20Sopenharmony_ci	PROC41(TEST_STATEID,	enc_test_stateid,	dec_test_stateid),
76008c2ecf20Sopenharmony_ci	PROC41(FREE_STATEID,	enc_free_stateid,	dec_free_stateid),
76018c2ecf20Sopenharmony_ci	STUB(GETDEVICELIST),
76028c2ecf20Sopenharmony_ci	PROC41(BIND_CONN_TO_SESSION,
76038c2ecf20Sopenharmony_ci			enc_bind_conn_to_session, dec_bind_conn_to_session),
76048c2ecf20Sopenharmony_ci	PROC41(DESTROY_CLIENTID,enc_destroy_clientid,	dec_destroy_clientid),
76058c2ecf20Sopenharmony_ci	PROC42(SEEK,		enc_seek,		dec_seek),
76068c2ecf20Sopenharmony_ci	PROC42(ALLOCATE,	enc_allocate,		dec_allocate),
76078c2ecf20Sopenharmony_ci	PROC42(DEALLOCATE,	enc_deallocate,		dec_deallocate),
76088c2ecf20Sopenharmony_ci	PROC42(LAYOUTSTATS,	enc_layoutstats,	dec_layoutstats),
76098c2ecf20Sopenharmony_ci	PROC42(CLONE,		enc_clone,		dec_clone),
76108c2ecf20Sopenharmony_ci	PROC42(COPY,		enc_copy,		dec_copy),
76118c2ecf20Sopenharmony_ci	PROC42(OFFLOAD_CANCEL,	enc_offload_cancel,	dec_offload_cancel),
76128c2ecf20Sopenharmony_ci	PROC42(COPY_NOTIFY,	enc_copy_notify,	dec_copy_notify),
76138c2ecf20Sopenharmony_ci	PROC(LOOKUPP,		enc_lookupp,		dec_lookupp),
76148c2ecf20Sopenharmony_ci	PROC42(LAYOUTERROR,	enc_layouterror,	dec_layouterror),
76158c2ecf20Sopenharmony_ci	PROC42(GETXATTR,	enc_getxattr,		dec_getxattr),
76168c2ecf20Sopenharmony_ci	PROC42(SETXATTR,	enc_setxattr,		dec_setxattr),
76178c2ecf20Sopenharmony_ci	PROC42(LISTXATTRS,	enc_listxattrs,		dec_listxattrs),
76188c2ecf20Sopenharmony_ci	PROC42(REMOVEXATTR,	enc_removexattr,	dec_removexattr),
76198c2ecf20Sopenharmony_ci	PROC42(READ_PLUS,	enc_read_plus,		dec_read_plus),
76208c2ecf20Sopenharmony_ci};
76218c2ecf20Sopenharmony_ci
76228c2ecf20Sopenharmony_cistatic unsigned int nfs_version4_counts[ARRAY_SIZE(nfs4_procedures)];
76238c2ecf20Sopenharmony_ciconst struct rpc_version nfs_version4 = {
76248c2ecf20Sopenharmony_ci	.number			= 4,
76258c2ecf20Sopenharmony_ci	.nrprocs		= ARRAY_SIZE(nfs4_procedures),
76268c2ecf20Sopenharmony_ci	.procs			= nfs4_procedures,
76278c2ecf20Sopenharmony_ci	.counts			= nfs_version4_counts,
76288c2ecf20Sopenharmony_ci};
76298c2ecf20Sopenharmony_ci
76308c2ecf20Sopenharmony_ci/*
76318c2ecf20Sopenharmony_ci * Local variables:
76328c2ecf20Sopenharmony_ci *  c-basic-offset: 8
76338c2ecf20Sopenharmony_ci * End:
76348c2ecf20Sopenharmony_ci */
7635