162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * fs/nfs/nfs4xdr.c 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Client-side XDR for NFSv4. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 2002 The Regents of the University of Michigan. 762306a36Sopenharmony_ci * All rights reserved. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Kendrick Smith <kmsmith@umich.edu> 1062306a36Sopenharmony_ci * Andy Adamson <andros@umich.edu> 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 1362306a36Sopenharmony_ci * modification, are permitted provided that the following conditions 1462306a36Sopenharmony_ci * are met: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 1762306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 1862306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright 1962306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 2062306a36Sopenharmony_ci * documentation and/or other materials provided with the distribution. 2162306a36Sopenharmony_ci * 3. Neither the name of the University nor the names of its 2262306a36Sopenharmony_ci * contributors may be used to endorse or promote products derived 2362306a36Sopenharmony_ci * from this software without specific prior written permission. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 2662306a36Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2762306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2862306a36Sopenharmony_ci * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2962306a36Sopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3062306a36Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3162306a36Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 3262306a36Sopenharmony_ci * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3362306a36Sopenharmony_ci * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3462306a36Sopenharmony_ci * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3562306a36Sopenharmony_ci * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3662306a36Sopenharmony_ci */ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#include <linux/param.h> 3962306a36Sopenharmony_ci#include <linux/time.h> 4062306a36Sopenharmony_ci#include <linux/mm.h> 4162306a36Sopenharmony_ci#include <linux/errno.h> 4262306a36Sopenharmony_ci#include <linux/string.h> 4362306a36Sopenharmony_ci#include <linux/in.h> 4462306a36Sopenharmony_ci#include <linux/pagemap.h> 4562306a36Sopenharmony_ci#include <linux/proc_fs.h> 4662306a36Sopenharmony_ci#include <linux/kdev_t.h> 4762306a36Sopenharmony_ci#include <linux/module.h> 4862306a36Sopenharmony_ci#include <linux/utsname.h> 4962306a36Sopenharmony_ci#include <linux/sunrpc/clnt.h> 5062306a36Sopenharmony_ci#include <linux/sunrpc/msg_prot.h> 5162306a36Sopenharmony_ci#include <linux/sunrpc/gss_api.h> 5262306a36Sopenharmony_ci#include <linux/nfs.h> 5362306a36Sopenharmony_ci#include <linux/nfs4.h> 5462306a36Sopenharmony_ci#include <linux/nfs_fs.h> 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#include "nfs4_fs.h" 5762306a36Sopenharmony_ci#include "nfs4trace.h" 5862306a36Sopenharmony_ci#include "internal.h" 5962306a36Sopenharmony_ci#include "nfs4idmap.h" 6062306a36Sopenharmony_ci#include "nfs4session.h" 6162306a36Sopenharmony_ci#include "pnfs.h" 6262306a36Sopenharmony_ci#include "netns.h" 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci#define NFSDBG_FACILITY NFSDBG_XDR 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* Mapping from NFS error code to "errno" error code. */ 6762306a36Sopenharmony_ci#define errno_NFSERR_IO EIO 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistruct compound_hdr; 7062306a36Sopenharmony_cistatic int nfs4_stat_to_errno(int); 7162306a36Sopenharmony_cistatic void encode_layoutget(struct xdr_stream *xdr, 7262306a36Sopenharmony_ci const struct nfs4_layoutget_args *args, 7362306a36Sopenharmony_ci struct compound_hdr *hdr); 7462306a36Sopenharmony_cistatic int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, 7562306a36Sopenharmony_ci struct nfs4_layoutget_res *res); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* NFSv4 COMPOUND tags are only wanted for debugging purposes */ 7862306a36Sopenharmony_ci#ifdef DEBUG 7962306a36Sopenharmony_ci#define NFS4_MAXTAGLEN 20 8062306a36Sopenharmony_ci#else 8162306a36Sopenharmony_ci#define NFS4_MAXTAGLEN 0 8262306a36Sopenharmony_ci#endif 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/* lock,open owner id: 8562306a36Sopenharmony_ci * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2) 8662306a36Sopenharmony_ci */ 8762306a36Sopenharmony_ci#define pagepad_maxsz (1) 8862306a36Sopenharmony_ci#define open_owner_id_maxsz (1 + 2 + 1 + 1 + 2) 8962306a36Sopenharmony_ci#define lock_owner_id_maxsz (1 + 1 + 4) 9062306a36Sopenharmony_ci#define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 9162306a36Sopenharmony_ci#define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) 9262306a36Sopenharmony_ci#define compound_decode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) 9362306a36Sopenharmony_ci#define op_encode_hdr_maxsz (1) 9462306a36Sopenharmony_ci#define op_decode_hdr_maxsz (2) 9562306a36Sopenharmony_ci#define encode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE)) 9662306a36Sopenharmony_ci#define decode_stateid_maxsz (XDR_QUADLEN(NFS4_STATEID_SIZE)) 9762306a36Sopenharmony_ci#define encode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) 9862306a36Sopenharmony_ci#define decode_verifier_maxsz (XDR_QUADLEN(NFS4_VERIFIER_SIZE)) 9962306a36Sopenharmony_ci#define encode_putfh_maxsz (op_encode_hdr_maxsz + 1 + \ 10062306a36Sopenharmony_ci (NFS4_FHSIZE >> 2)) 10162306a36Sopenharmony_ci#define decode_putfh_maxsz (op_decode_hdr_maxsz) 10262306a36Sopenharmony_ci#define encode_putrootfh_maxsz (op_encode_hdr_maxsz) 10362306a36Sopenharmony_ci#define decode_putrootfh_maxsz (op_decode_hdr_maxsz) 10462306a36Sopenharmony_ci#define encode_getfh_maxsz (op_encode_hdr_maxsz) 10562306a36Sopenharmony_ci#define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ 10662306a36Sopenharmony_ci ((3+NFS4_FHSIZE) >> 2)) 10762306a36Sopenharmony_ci#define nfs4_fattr_bitmap_maxsz 4 10862306a36Sopenharmony_ci#define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) 10962306a36Sopenharmony_ci#define nfstime4_maxsz (3) 11062306a36Sopenharmony_ci#define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) 11162306a36Sopenharmony_ci#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) 11262306a36Sopenharmony_ci#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 11362306a36Sopenharmony_ci#define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 11462306a36Sopenharmony_ci#ifdef CONFIG_NFS_V4_SECURITY_LABEL 11562306a36Sopenharmony_ci/* PI(4 bytes) + LFS(4 bytes) + 1(for null terminator?) + MAXLABELLEN */ 11662306a36Sopenharmony_ci#define nfs4_label_maxsz (4 + 4 + 1 + XDR_QUADLEN(NFS4_MAXLABELLEN)) 11762306a36Sopenharmony_ci#else 11862306a36Sopenharmony_ci#define nfs4_label_maxsz 0 11962306a36Sopenharmony_ci#endif 12062306a36Sopenharmony_ci/* We support only one layout type per file system */ 12162306a36Sopenharmony_ci#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8) 12262306a36Sopenharmony_ci/* This is based on getfattr, which uses the most attributes: */ 12362306a36Sopenharmony_ci#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ 12462306a36Sopenharmony_ci 3*nfstime4_maxsz + \ 12562306a36Sopenharmony_ci nfs4_owner_maxsz + \ 12662306a36Sopenharmony_ci nfs4_group_maxsz + nfs4_label_maxsz + \ 12762306a36Sopenharmony_ci decode_mdsthreshold_maxsz)) 12862306a36Sopenharmony_ci#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ 12962306a36Sopenharmony_ci nfs4_fattr_value_maxsz) 13062306a36Sopenharmony_ci#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) 13162306a36Sopenharmony_ci#define encode_attrs_maxsz (nfs4_fattr_bitmap_maxsz + \ 13262306a36Sopenharmony_ci 1 + 2 + 1 + \ 13362306a36Sopenharmony_ci nfs4_owner_maxsz + \ 13462306a36Sopenharmony_ci nfs4_group_maxsz + \ 13562306a36Sopenharmony_ci nfs4_label_maxsz + \ 13662306a36Sopenharmony_ci 1 + nfstime4_maxsz + \ 13762306a36Sopenharmony_ci 1 + nfstime4_maxsz) 13862306a36Sopenharmony_ci#define encode_savefh_maxsz (op_encode_hdr_maxsz) 13962306a36Sopenharmony_ci#define decode_savefh_maxsz (op_decode_hdr_maxsz) 14062306a36Sopenharmony_ci#define encode_restorefh_maxsz (op_encode_hdr_maxsz) 14162306a36Sopenharmony_ci#define decode_restorefh_maxsz (op_decode_hdr_maxsz) 14262306a36Sopenharmony_ci#define encode_fsinfo_maxsz (encode_getattr_maxsz) 14362306a36Sopenharmony_ci/* The 5 accounts for the PNFS attributes, and assumes that at most three 14462306a36Sopenharmony_ci * layout types will be returned. 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_ci#define decode_fsinfo_maxsz (op_decode_hdr_maxsz + \ 14762306a36Sopenharmony_ci nfs4_fattr_bitmap_maxsz + 1 + \ 14862306a36Sopenharmony_ci 1 /* lease time */ + \ 14962306a36Sopenharmony_ci 2 /* max filesize */ + \ 15062306a36Sopenharmony_ci 2 /* max read */ + \ 15162306a36Sopenharmony_ci 2 /* max write */ + \ 15262306a36Sopenharmony_ci nfstime4_maxsz /* time delta */ + \ 15362306a36Sopenharmony_ci 5 /* fs layout types */ + \ 15462306a36Sopenharmony_ci 1 /* layout blksize */ + \ 15562306a36Sopenharmony_ci 1 /* clone blksize */ + \ 15662306a36Sopenharmony_ci 1 /* change attr type */ + \ 15762306a36Sopenharmony_ci 1 /* xattr support */) 15862306a36Sopenharmony_ci#define encode_renew_maxsz (op_encode_hdr_maxsz + 3) 15962306a36Sopenharmony_ci#define decode_renew_maxsz (op_decode_hdr_maxsz) 16062306a36Sopenharmony_ci#define encode_setclientid_maxsz \ 16162306a36Sopenharmony_ci (op_encode_hdr_maxsz + \ 16262306a36Sopenharmony_ci XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \ 16362306a36Sopenharmony_ci /* client name */ \ 16462306a36Sopenharmony_ci 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 16562306a36Sopenharmony_ci 1 /* sc_prog */ + \ 16662306a36Sopenharmony_ci 1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \ 16762306a36Sopenharmony_ci 1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \ 16862306a36Sopenharmony_ci 1) /* sc_cb_ident */ 16962306a36Sopenharmony_ci#define decode_setclientid_maxsz \ 17062306a36Sopenharmony_ci (op_decode_hdr_maxsz + \ 17162306a36Sopenharmony_ci 2 /* clientid */ + \ 17262306a36Sopenharmony_ci XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \ 17362306a36Sopenharmony_ci 1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \ 17462306a36Sopenharmony_ci 1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN)) 17562306a36Sopenharmony_ci#define encode_setclientid_confirm_maxsz \ 17662306a36Sopenharmony_ci (op_encode_hdr_maxsz + \ 17762306a36Sopenharmony_ci 3 + (NFS4_VERIFIER_SIZE >> 2)) 17862306a36Sopenharmony_ci#define decode_setclientid_confirm_maxsz \ 17962306a36Sopenharmony_ci (op_decode_hdr_maxsz) 18062306a36Sopenharmony_ci#define encode_lookup_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz) 18162306a36Sopenharmony_ci#define decode_lookup_maxsz (op_decode_hdr_maxsz) 18262306a36Sopenharmony_ci#define encode_lookupp_maxsz (op_encode_hdr_maxsz) 18362306a36Sopenharmony_ci#define decode_lookupp_maxsz (op_decode_hdr_maxsz) 18462306a36Sopenharmony_ci#define encode_share_access_maxsz \ 18562306a36Sopenharmony_ci (2) 18662306a36Sopenharmony_ci#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz) 18762306a36Sopenharmony_ci#define encode_opentype_maxsz (1 + encode_createmode_maxsz) 18862306a36Sopenharmony_ci#define encode_claim_null_maxsz (1 + nfs4_name_maxsz) 18962306a36Sopenharmony_ci#define encode_open_maxsz (op_encode_hdr_maxsz + \ 19062306a36Sopenharmony_ci 2 + encode_share_access_maxsz + 2 + \ 19162306a36Sopenharmony_ci open_owner_id_maxsz + \ 19262306a36Sopenharmony_ci encode_opentype_maxsz + \ 19362306a36Sopenharmony_ci encode_claim_null_maxsz) 19462306a36Sopenharmony_ci#define decode_space_limit_maxsz (3) 19562306a36Sopenharmony_ci#define decode_ace_maxsz (3 + nfs4_owner_maxsz) 19662306a36Sopenharmony_ci#define decode_delegation_maxsz (1 + decode_stateid_maxsz + 1 + \ 19762306a36Sopenharmony_ci decode_space_limit_maxsz + \ 19862306a36Sopenharmony_ci decode_ace_maxsz) 19962306a36Sopenharmony_ci#define decode_change_info_maxsz (5) 20062306a36Sopenharmony_ci#define decode_open_maxsz (op_decode_hdr_maxsz + \ 20162306a36Sopenharmony_ci decode_stateid_maxsz + \ 20262306a36Sopenharmony_ci decode_change_info_maxsz + 1 + \ 20362306a36Sopenharmony_ci nfs4_fattr_bitmap_maxsz + \ 20462306a36Sopenharmony_ci decode_delegation_maxsz) 20562306a36Sopenharmony_ci#define encode_open_confirm_maxsz \ 20662306a36Sopenharmony_ci (op_encode_hdr_maxsz + \ 20762306a36Sopenharmony_ci encode_stateid_maxsz + 1) 20862306a36Sopenharmony_ci#define decode_open_confirm_maxsz \ 20962306a36Sopenharmony_ci (op_decode_hdr_maxsz + \ 21062306a36Sopenharmony_ci decode_stateid_maxsz) 21162306a36Sopenharmony_ci#define encode_open_downgrade_maxsz \ 21262306a36Sopenharmony_ci (op_encode_hdr_maxsz + \ 21362306a36Sopenharmony_ci encode_stateid_maxsz + 1 + \ 21462306a36Sopenharmony_ci encode_share_access_maxsz) 21562306a36Sopenharmony_ci#define decode_open_downgrade_maxsz \ 21662306a36Sopenharmony_ci (op_decode_hdr_maxsz + \ 21762306a36Sopenharmony_ci decode_stateid_maxsz) 21862306a36Sopenharmony_ci#define encode_close_maxsz (op_encode_hdr_maxsz + \ 21962306a36Sopenharmony_ci 1 + encode_stateid_maxsz) 22062306a36Sopenharmony_ci#define decode_close_maxsz (op_decode_hdr_maxsz + \ 22162306a36Sopenharmony_ci decode_stateid_maxsz) 22262306a36Sopenharmony_ci#define encode_setattr_maxsz (op_encode_hdr_maxsz + \ 22362306a36Sopenharmony_ci encode_stateid_maxsz + \ 22462306a36Sopenharmony_ci encode_attrs_maxsz) 22562306a36Sopenharmony_ci#define decode_setattr_maxsz (op_decode_hdr_maxsz + \ 22662306a36Sopenharmony_ci nfs4_fattr_bitmap_maxsz) 22762306a36Sopenharmony_ci#define encode_read_maxsz (op_encode_hdr_maxsz + \ 22862306a36Sopenharmony_ci encode_stateid_maxsz + 3) 22962306a36Sopenharmony_ci#define decode_read_maxsz (op_decode_hdr_maxsz + 2 + pagepad_maxsz) 23062306a36Sopenharmony_ci#define encode_readdir_maxsz (op_encode_hdr_maxsz + \ 23162306a36Sopenharmony_ci 2 + encode_verifier_maxsz + 5 + \ 23262306a36Sopenharmony_ci nfs4_label_maxsz) 23362306a36Sopenharmony_ci#define decode_readdir_maxsz (op_decode_hdr_maxsz + \ 23462306a36Sopenharmony_ci decode_verifier_maxsz + pagepad_maxsz) 23562306a36Sopenharmony_ci#define encode_readlink_maxsz (op_encode_hdr_maxsz) 23662306a36Sopenharmony_ci#define decode_readlink_maxsz (op_decode_hdr_maxsz + 1 + pagepad_maxsz) 23762306a36Sopenharmony_ci#define encode_write_maxsz (op_encode_hdr_maxsz + \ 23862306a36Sopenharmony_ci encode_stateid_maxsz + 4) 23962306a36Sopenharmony_ci#define decode_write_maxsz (op_decode_hdr_maxsz + \ 24062306a36Sopenharmony_ci 2 + decode_verifier_maxsz) 24162306a36Sopenharmony_ci#define encode_commit_maxsz (op_encode_hdr_maxsz + 3) 24262306a36Sopenharmony_ci#define decode_commit_maxsz (op_decode_hdr_maxsz + \ 24362306a36Sopenharmony_ci decode_verifier_maxsz) 24462306a36Sopenharmony_ci#define encode_remove_maxsz (op_encode_hdr_maxsz + \ 24562306a36Sopenharmony_ci nfs4_name_maxsz) 24662306a36Sopenharmony_ci#define decode_remove_maxsz (op_decode_hdr_maxsz + \ 24762306a36Sopenharmony_ci decode_change_info_maxsz) 24862306a36Sopenharmony_ci#define encode_rename_maxsz (op_encode_hdr_maxsz + \ 24962306a36Sopenharmony_ci 2 * nfs4_name_maxsz) 25062306a36Sopenharmony_ci#define decode_rename_maxsz (op_decode_hdr_maxsz + \ 25162306a36Sopenharmony_ci decode_change_info_maxsz + \ 25262306a36Sopenharmony_ci decode_change_info_maxsz) 25362306a36Sopenharmony_ci#define encode_link_maxsz (op_encode_hdr_maxsz + \ 25462306a36Sopenharmony_ci nfs4_name_maxsz) 25562306a36Sopenharmony_ci#define decode_link_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz) 25662306a36Sopenharmony_ci#define encode_lockowner_maxsz (7) 25762306a36Sopenharmony_ci#define encode_lock_maxsz (op_encode_hdr_maxsz + \ 25862306a36Sopenharmony_ci 7 + \ 25962306a36Sopenharmony_ci 1 + encode_stateid_maxsz + 1 + \ 26062306a36Sopenharmony_ci encode_lockowner_maxsz) 26162306a36Sopenharmony_ci#define decode_lock_denied_maxsz \ 26262306a36Sopenharmony_ci (8 + decode_lockowner_maxsz) 26362306a36Sopenharmony_ci#define decode_lock_maxsz (op_decode_hdr_maxsz + \ 26462306a36Sopenharmony_ci decode_lock_denied_maxsz) 26562306a36Sopenharmony_ci#define encode_lockt_maxsz (op_encode_hdr_maxsz + 5 + \ 26662306a36Sopenharmony_ci encode_lockowner_maxsz) 26762306a36Sopenharmony_ci#define decode_lockt_maxsz (op_decode_hdr_maxsz + \ 26862306a36Sopenharmony_ci decode_lock_denied_maxsz) 26962306a36Sopenharmony_ci#define encode_locku_maxsz (op_encode_hdr_maxsz + 3 + \ 27062306a36Sopenharmony_ci encode_stateid_maxsz + \ 27162306a36Sopenharmony_ci 4) 27262306a36Sopenharmony_ci#define decode_locku_maxsz (op_decode_hdr_maxsz + \ 27362306a36Sopenharmony_ci decode_stateid_maxsz) 27462306a36Sopenharmony_ci#define encode_release_lockowner_maxsz \ 27562306a36Sopenharmony_ci (op_encode_hdr_maxsz + \ 27662306a36Sopenharmony_ci encode_lockowner_maxsz) 27762306a36Sopenharmony_ci#define decode_release_lockowner_maxsz \ 27862306a36Sopenharmony_ci (op_decode_hdr_maxsz) 27962306a36Sopenharmony_ci#define encode_access_maxsz (op_encode_hdr_maxsz + 1) 28062306a36Sopenharmony_ci#define decode_access_maxsz (op_decode_hdr_maxsz + 2) 28162306a36Sopenharmony_ci#define encode_symlink_maxsz (op_encode_hdr_maxsz + \ 28262306a36Sopenharmony_ci 1 + nfs4_name_maxsz + \ 28362306a36Sopenharmony_ci 1 + \ 28462306a36Sopenharmony_ci nfs4_fattr_maxsz) 28562306a36Sopenharmony_ci#define decode_symlink_maxsz (op_decode_hdr_maxsz + 8) 28662306a36Sopenharmony_ci#define encode_create_maxsz (op_encode_hdr_maxsz + \ 28762306a36Sopenharmony_ci 1 + 2 + nfs4_name_maxsz + \ 28862306a36Sopenharmony_ci encode_attrs_maxsz) 28962306a36Sopenharmony_ci#define decode_create_maxsz (op_decode_hdr_maxsz + \ 29062306a36Sopenharmony_ci decode_change_info_maxsz + \ 29162306a36Sopenharmony_ci nfs4_fattr_bitmap_maxsz) 29262306a36Sopenharmony_ci#define encode_statfs_maxsz (encode_getattr_maxsz) 29362306a36Sopenharmony_ci#define decode_statfs_maxsz (decode_getattr_maxsz) 29462306a36Sopenharmony_ci#define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4) 29562306a36Sopenharmony_ci#define decode_delegreturn_maxsz (op_decode_hdr_maxsz) 29662306a36Sopenharmony_ci#define encode_getacl_maxsz (encode_getattr_maxsz) 29762306a36Sopenharmony_ci#define decode_getacl_maxsz (op_decode_hdr_maxsz + \ 29862306a36Sopenharmony_ci nfs4_fattr_bitmap_maxsz + 1 + pagepad_maxsz) 29962306a36Sopenharmony_ci#define encode_setacl_maxsz (op_encode_hdr_maxsz + \ 30062306a36Sopenharmony_ci encode_stateid_maxsz + 3) 30162306a36Sopenharmony_ci#define decode_setacl_maxsz (decode_setattr_maxsz) 30262306a36Sopenharmony_ci#define encode_fs_locations_maxsz \ 30362306a36Sopenharmony_ci (encode_getattr_maxsz) 30462306a36Sopenharmony_ci#define decode_fs_locations_maxsz \ 30562306a36Sopenharmony_ci (pagepad_maxsz) 30662306a36Sopenharmony_ci#define encode_secinfo_maxsz (op_encode_hdr_maxsz + nfs4_name_maxsz) 30762306a36Sopenharmony_ci#define decode_secinfo_maxsz (op_decode_hdr_maxsz + 1 + ((NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)) / 4)) 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 31062306a36Sopenharmony_ci#define NFS4_MAX_MACHINE_NAME_LEN (64) 31162306a36Sopenharmony_ci#define IMPL_NAME_LIMIT (sizeof(utsname()->sysname) + sizeof(utsname()->release) + \ 31262306a36Sopenharmony_ci sizeof(utsname()->version) + sizeof(utsname()->machine) + 8) 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci#define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \ 31562306a36Sopenharmony_ci encode_verifier_maxsz + \ 31662306a36Sopenharmony_ci 1 /* co_ownerid.len */ + \ 31762306a36Sopenharmony_ci /* eia_clientowner */ \ 31862306a36Sopenharmony_ci 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 31962306a36Sopenharmony_ci 1 /* flags */ + \ 32062306a36Sopenharmony_ci 1 /* spa_how */ + \ 32162306a36Sopenharmony_ci /* max is SP4_MACH_CRED (for now) */ + \ 32262306a36Sopenharmony_ci 1 + NFS4_OP_MAP_NUM_WORDS + \ 32362306a36Sopenharmony_ci 1 + NFS4_OP_MAP_NUM_WORDS + \ 32462306a36Sopenharmony_ci 1 /* implementation id array of size 1 */ + \ 32562306a36Sopenharmony_ci 1 /* nii_domain */ + \ 32662306a36Sopenharmony_ci XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 32762306a36Sopenharmony_ci 1 /* nii_name */ + \ 32862306a36Sopenharmony_ci XDR_QUADLEN(IMPL_NAME_LIMIT) + \ 32962306a36Sopenharmony_ci 3 /* nii_date */) 33062306a36Sopenharmony_ci#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \ 33162306a36Sopenharmony_ci 2 /* eir_clientid */ + \ 33262306a36Sopenharmony_ci 1 /* eir_sequenceid */ + \ 33362306a36Sopenharmony_ci 1 /* eir_flags */ + \ 33462306a36Sopenharmony_ci 1 /* spr_how */ + \ 33562306a36Sopenharmony_ci /* max is SP4_MACH_CRED (for now) */ + \ 33662306a36Sopenharmony_ci 1 + NFS4_OP_MAP_NUM_WORDS + \ 33762306a36Sopenharmony_ci 1 + NFS4_OP_MAP_NUM_WORDS + \ 33862306a36Sopenharmony_ci 2 /* eir_server_owner.so_minor_id */ + \ 33962306a36Sopenharmony_ci /* eir_server_owner.so_major_id<> */ \ 34062306a36Sopenharmony_ci XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \ 34162306a36Sopenharmony_ci /* eir_server_scope<> */ \ 34262306a36Sopenharmony_ci XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \ 34362306a36Sopenharmony_ci 1 /* eir_server_impl_id array length */ + \ 34462306a36Sopenharmony_ci 1 /* nii_domain */ + \ 34562306a36Sopenharmony_ci XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 34662306a36Sopenharmony_ci 1 /* nii_name */ + \ 34762306a36Sopenharmony_ci XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \ 34862306a36Sopenharmony_ci 3 /* nii_date */) 34962306a36Sopenharmony_ci#define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */) 35062306a36Sopenharmony_ci#define decode_channel_attrs_maxsz (6 + \ 35162306a36Sopenharmony_ci 1 /* ca_rdma_ird.len */ + \ 35262306a36Sopenharmony_ci 1 /* ca_rdma_ird */) 35362306a36Sopenharmony_ci#define encode_create_session_maxsz (op_encode_hdr_maxsz + \ 35462306a36Sopenharmony_ci 2 /* csa_clientid */ + \ 35562306a36Sopenharmony_ci 1 /* csa_sequence */ + \ 35662306a36Sopenharmony_ci 1 /* csa_flags */ + \ 35762306a36Sopenharmony_ci encode_channel_attrs_maxsz + \ 35862306a36Sopenharmony_ci encode_channel_attrs_maxsz + \ 35962306a36Sopenharmony_ci 1 /* csa_cb_program */ + \ 36062306a36Sopenharmony_ci 1 /* csa_sec_parms.len (1) */ + \ 36162306a36Sopenharmony_ci 1 /* cb_secflavor (AUTH_SYS) */ + \ 36262306a36Sopenharmony_ci 1 /* stamp */ + \ 36362306a36Sopenharmony_ci 1 /* machinename.len */ + \ 36462306a36Sopenharmony_ci XDR_QUADLEN(NFS4_MAX_MACHINE_NAME_LEN) + \ 36562306a36Sopenharmony_ci 1 /* uid */ + \ 36662306a36Sopenharmony_ci 1 /* gid */ + \ 36762306a36Sopenharmony_ci 1 /* gids.len (0) */) 36862306a36Sopenharmony_ci#define decode_create_session_maxsz (op_decode_hdr_maxsz + \ 36962306a36Sopenharmony_ci XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ 37062306a36Sopenharmony_ci 1 /* csr_sequence */ + \ 37162306a36Sopenharmony_ci 1 /* csr_flags */ + \ 37262306a36Sopenharmony_ci decode_channel_attrs_maxsz + \ 37362306a36Sopenharmony_ci decode_channel_attrs_maxsz) 37462306a36Sopenharmony_ci#define encode_bind_conn_to_session_maxsz (op_encode_hdr_maxsz + \ 37562306a36Sopenharmony_ci /* bctsa_sessid */ \ 37662306a36Sopenharmony_ci XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ 37762306a36Sopenharmony_ci 1 /* bctsa_dir */ + \ 37862306a36Sopenharmony_ci 1 /* bctsa_use_conn_in_rdma_mode */) 37962306a36Sopenharmony_ci#define decode_bind_conn_to_session_maxsz (op_decode_hdr_maxsz + \ 38062306a36Sopenharmony_ci /* bctsr_sessid */ \ 38162306a36Sopenharmony_ci XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \ 38262306a36Sopenharmony_ci 1 /* bctsr_dir */ + \ 38362306a36Sopenharmony_ci 1 /* bctsr_use_conn_in_rdma_mode */) 38462306a36Sopenharmony_ci#define encode_destroy_session_maxsz (op_encode_hdr_maxsz + 4) 38562306a36Sopenharmony_ci#define decode_destroy_session_maxsz (op_decode_hdr_maxsz) 38662306a36Sopenharmony_ci#define encode_destroy_clientid_maxsz (op_encode_hdr_maxsz + 2) 38762306a36Sopenharmony_ci#define decode_destroy_clientid_maxsz (op_decode_hdr_maxsz) 38862306a36Sopenharmony_ci#define encode_sequence_maxsz (op_encode_hdr_maxsz + \ 38962306a36Sopenharmony_ci XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4) 39062306a36Sopenharmony_ci#define decode_sequence_maxsz (op_decode_hdr_maxsz + \ 39162306a36Sopenharmony_ci XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) 39262306a36Sopenharmony_ci#define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) 39362306a36Sopenharmony_ci#define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) 39462306a36Sopenharmony_ci#define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \ 39562306a36Sopenharmony_ci XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ 39662306a36Sopenharmony_ci 1 /* layout type */ + \ 39762306a36Sopenharmony_ci 1 /* maxcount */ + \ 39862306a36Sopenharmony_ci 1 /* bitmap size */ + \ 39962306a36Sopenharmony_ci 1 /* notification bitmap length */ + \ 40062306a36Sopenharmony_ci 1 /* notification bitmap, word 0 */) 40162306a36Sopenharmony_ci#define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ 40262306a36Sopenharmony_ci 1 /* layout type */ + \ 40362306a36Sopenharmony_ci 1 /* opaque devaddr4 length */ + \ 40462306a36Sopenharmony_ci /* devaddr4 payload is read into page */ \ 40562306a36Sopenharmony_ci 1 /* notification bitmap length */ + \ 40662306a36Sopenharmony_ci 1 /* notification bitmap, word 0 */ + \ 40762306a36Sopenharmony_ci pagepad_maxsz /* possible XDR padding */) 40862306a36Sopenharmony_ci#define encode_layoutget_maxsz (op_encode_hdr_maxsz + 10 + \ 40962306a36Sopenharmony_ci encode_stateid_maxsz) 41062306a36Sopenharmony_ci#define decode_layoutget_maxsz (op_decode_hdr_maxsz + 8 + \ 41162306a36Sopenharmony_ci decode_stateid_maxsz + \ 41262306a36Sopenharmony_ci XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE) + \ 41362306a36Sopenharmony_ci pagepad_maxsz) 41462306a36Sopenharmony_ci#define encode_layoutcommit_maxsz (op_encode_hdr_maxsz + \ 41562306a36Sopenharmony_ci 2 /* offset */ + \ 41662306a36Sopenharmony_ci 2 /* length */ + \ 41762306a36Sopenharmony_ci 1 /* reclaim */ + \ 41862306a36Sopenharmony_ci encode_stateid_maxsz + \ 41962306a36Sopenharmony_ci 1 /* new offset (true) */ + \ 42062306a36Sopenharmony_ci 2 /* last byte written */ + \ 42162306a36Sopenharmony_ci 1 /* nt_timechanged (false) */ + \ 42262306a36Sopenharmony_ci 1 /* layoutupdate4 layout type */ + \ 42362306a36Sopenharmony_ci 1 /* layoutupdate4 opaqueue len */) 42462306a36Sopenharmony_ci /* the actual content of layoutupdate4 should 42562306a36Sopenharmony_ci be allocated by drivers and spliced in 42662306a36Sopenharmony_ci using xdr_write_pages */ 42762306a36Sopenharmony_ci#define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) 42862306a36Sopenharmony_ci#define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \ 42962306a36Sopenharmony_ci encode_stateid_maxsz + \ 43062306a36Sopenharmony_ci 1 + \ 43162306a36Sopenharmony_ci XDR_QUADLEN(NFS4_OPAQUE_LIMIT)) 43262306a36Sopenharmony_ci#define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \ 43362306a36Sopenharmony_ci 1 + decode_stateid_maxsz) 43462306a36Sopenharmony_ci#define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 1) 43562306a36Sopenharmony_ci#define decode_secinfo_no_name_maxsz decode_secinfo_maxsz 43662306a36Sopenharmony_ci#define encode_test_stateid_maxsz (op_encode_hdr_maxsz + 2 + \ 43762306a36Sopenharmony_ci XDR_QUADLEN(NFS4_STATEID_SIZE)) 43862306a36Sopenharmony_ci#define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1) 43962306a36Sopenharmony_ci#define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \ 44062306a36Sopenharmony_ci XDR_QUADLEN(NFS4_STATEID_SIZE)) 44162306a36Sopenharmony_ci#define decode_free_stateid_maxsz (op_decode_hdr_maxsz) 44262306a36Sopenharmony_ci#else /* CONFIG_NFS_V4_1 */ 44362306a36Sopenharmony_ci#define encode_sequence_maxsz 0 44462306a36Sopenharmony_ci#define decode_sequence_maxsz 0 44562306a36Sopenharmony_ci#define encode_layoutreturn_maxsz 0 44662306a36Sopenharmony_ci#define decode_layoutreturn_maxsz 0 44762306a36Sopenharmony_ci#define encode_layoutget_maxsz 0 44862306a36Sopenharmony_ci#define decode_layoutget_maxsz 0 44962306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */ 45262306a36Sopenharmony_ci#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */ 45362306a36Sopenharmony_ci#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \ 45462306a36Sopenharmony_ci encode_sequence_maxsz + \ 45562306a36Sopenharmony_ci encode_putfh_maxsz + \ 45662306a36Sopenharmony_ci encode_read_maxsz) 45762306a36Sopenharmony_ci#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \ 45862306a36Sopenharmony_ci decode_sequence_maxsz + \ 45962306a36Sopenharmony_ci decode_putfh_maxsz + \ 46062306a36Sopenharmony_ci decode_read_maxsz) 46162306a36Sopenharmony_ci#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \ 46262306a36Sopenharmony_ci encode_sequence_maxsz + \ 46362306a36Sopenharmony_ci encode_putfh_maxsz + \ 46462306a36Sopenharmony_ci encode_readlink_maxsz) 46562306a36Sopenharmony_ci#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \ 46662306a36Sopenharmony_ci decode_sequence_maxsz + \ 46762306a36Sopenharmony_ci decode_putfh_maxsz + \ 46862306a36Sopenharmony_ci decode_readlink_maxsz) 46962306a36Sopenharmony_ci#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \ 47062306a36Sopenharmony_ci encode_sequence_maxsz + \ 47162306a36Sopenharmony_ci encode_putfh_maxsz + \ 47262306a36Sopenharmony_ci encode_readdir_maxsz) 47362306a36Sopenharmony_ci#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \ 47462306a36Sopenharmony_ci decode_sequence_maxsz + \ 47562306a36Sopenharmony_ci decode_putfh_maxsz + \ 47662306a36Sopenharmony_ci decode_readdir_maxsz) 47762306a36Sopenharmony_ci#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \ 47862306a36Sopenharmony_ci encode_sequence_maxsz + \ 47962306a36Sopenharmony_ci encode_putfh_maxsz + \ 48062306a36Sopenharmony_ci encode_write_maxsz + \ 48162306a36Sopenharmony_ci encode_getattr_maxsz) 48262306a36Sopenharmony_ci#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \ 48362306a36Sopenharmony_ci decode_sequence_maxsz + \ 48462306a36Sopenharmony_ci decode_putfh_maxsz + \ 48562306a36Sopenharmony_ci decode_write_maxsz + \ 48662306a36Sopenharmony_ci decode_getattr_maxsz) 48762306a36Sopenharmony_ci#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ 48862306a36Sopenharmony_ci encode_sequence_maxsz + \ 48962306a36Sopenharmony_ci encode_putfh_maxsz + \ 49062306a36Sopenharmony_ci encode_commit_maxsz) 49162306a36Sopenharmony_ci#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ 49262306a36Sopenharmony_ci decode_sequence_maxsz + \ 49362306a36Sopenharmony_ci decode_putfh_maxsz + \ 49462306a36Sopenharmony_ci decode_commit_maxsz) 49562306a36Sopenharmony_ci#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ 49662306a36Sopenharmony_ci encode_sequence_maxsz + \ 49762306a36Sopenharmony_ci encode_putfh_maxsz + \ 49862306a36Sopenharmony_ci encode_open_maxsz + \ 49962306a36Sopenharmony_ci encode_access_maxsz + \ 50062306a36Sopenharmony_ci encode_getfh_maxsz + \ 50162306a36Sopenharmony_ci encode_getattr_maxsz + \ 50262306a36Sopenharmony_ci encode_layoutget_maxsz) 50362306a36Sopenharmony_ci#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ 50462306a36Sopenharmony_ci decode_sequence_maxsz + \ 50562306a36Sopenharmony_ci decode_putfh_maxsz + \ 50662306a36Sopenharmony_ci decode_open_maxsz + \ 50762306a36Sopenharmony_ci decode_access_maxsz + \ 50862306a36Sopenharmony_ci decode_getfh_maxsz + \ 50962306a36Sopenharmony_ci decode_getattr_maxsz + \ 51062306a36Sopenharmony_ci decode_layoutget_maxsz) 51162306a36Sopenharmony_ci#define NFS4_enc_open_confirm_sz \ 51262306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 51362306a36Sopenharmony_ci encode_putfh_maxsz + \ 51462306a36Sopenharmony_ci encode_open_confirm_maxsz) 51562306a36Sopenharmony_ci#define NFS4_dec_open_confirm_sz \ 51662306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 51762306a36Sopenharmony_ci decode_putfh_maxsz + \ 51862306a36Sopenharmony_ci decode_open_confirm_maxsz) 51962306a36Sopenharmony_ci#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \ 52062306a36Sopenharmony_ci encode_sequence_maxsz + \ 52162306a36Sopenharmony_ci encode_putfh_maxsz + \ 52262306a36Sopenharmony_ci encode_open_maxsz + \ 52362306a36Sopenharmony_ci encode_access_maxsz + \ 52462306a36Sopenharmony_ci encode_getattr_maxsz + \ 52562306a36Sopenharmony_ci encode_layoutget_maxsz) 52662306a36Sopenharmony_ci#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \ 52762306a36Sopenharmony_ci decode_sequence_maxsz + \ 52862306a36Sopenharmony_ci decode_putfh_maxsz + \ 52962306a36Sopenharmony_ci decode_open_maxsz + \ 53062306a36Sopenharmony_ci decode_access_maxsz + \ 53162306a36Sopenharmony_ci decode_getattr_maxsz + \ 53262306a36Sopenharmony_ci decode_layoutget_maxsz) 53362306a36Sopenharmony_ci#define NFS4_enc_open_downgrade_sz \ 53462306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 53562306a36Sopenharmony_ci encode_sequence_maxsz + \ 53662306a36Sopenharmony_ci encode_putfh_maxsz + \ 53762306a36Sopenharmony_ci encode_layoutreturn_maxsz + \ 53862306a36Sopenharmony_ci encode_open_downgrade_maxsz) 53962306a36Sopenharmony_ci#define NFS4_dec_open_downgrade_sz \ 54062306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 54162306a36Sopenharmony_ci decode_sequence_maxsz + \ 54262306a36Sopenharmony_ci decode_putfh_maxsz + \ 54362306a36Sopenharmony_ci decode_layoutreturn_maxsz + \ 54462306a36Sopenharmony_ci decode_open_downgrade_maxsz) 54562306a36Sopenharmony_ci#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \ 54662306a36Sopenharmony_ci encode_sequence_maxsz + \ 54762306a36Sopenharmony_ci encode_putfh_maxsz + \ 54862306a36Sopenharmony_ci encode_layoutreturn_maxsz + \ 54962306a36Sopenharmony_ci encode_close_maxsz + \ 55062306a36Sopenharmony_ci encode_getattr_maxsz) 55162306a36Sopenharmony_ci#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \ 55262306a36Sopenharmony_ci decode_sequence_maxsz + \ 55362306a36Sopenharmony_ci decode_putfh_maxsz + \ 55462306a36Sopenharmony_ci decode_layoutreturn_maxsz + \ 55562306a36Sopenharmony_ci decode_close_maxsz + \ 55662306a36Sopenharmony_ci decode_getattr_maxsz) 55762306a36Sopenharmony_ci#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \ 55862306a36Sopenharmony_ci encode_sequence_maxsz + \ 55962306a36Sopenharmony_ci encode_putfh_maxsz + \ 56062306a36Sopenharmony_ci encode_setattr_maxsz + \ 56162306a36Sopenharmony_ci encode_getattr_maxsz) 56262306a36Sopenharmony_ci#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \ 56362306a36Sopenharmony_ci decode_sequence_maxsz + \ 56462306a36Sopenharmony_ci decode_putfh_maxsz + \ 56562306a36Sopenharmony_ci decode_setattr_maxsz + \ 56662306a36Sopenharmony_ci decode_getattr_maxsz) 56762306a36Sopenharmony_ci#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \ 56862306a36Sopenharmony_ci encode_sequence_maxsz + \ 56962306a36Sopenharmony_ci encode_putfh_maxsz + \ 57062306a36Sopenharmony_ci encode_fsinfo_maxsz) 57162306a36Sopenharmony_ci#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \ 57262306a36Sopenharmony_ci decode_sequence_maxsz + \ 57362306a36Sopenharmony_ci decode_putfh_maxsz + \ 57462306a36Sopenharmony_ci decode_fsinfo_maxsz) 57562306a36Sopenharmony_ci#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \ 57662306a36Sopenharmony_ci encode_renew_maxsz) 57762306a36Sopenharmony_ci#define NFS4_dec_renew_sz (compound_decode_hdr_maxsz + \ 57862306a36Sopenharmony_ci decode_renew_maxsz) 57962306a36Sopenharmony_ci#define NFS4_enc_setclientid_sz (compound_encode_hdr_maxsz + \ 58062306a36Sopenharmony_ci encode_setclientid_maxsz) 58162306a36Sopenharmony_ci#define NFS4_dec_setclientid_sz (compound_decode_hdr_maxsz + \ 58262306a36Sopenharmony_ci decode_setclientid_maxsz) 58362306a36Sopenharmony_ci#define NFS4_enc_setclientid_confirm_sz \ 58462306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 58562306a36Sopenharmony_ci encode_setclientid_confirm_maxsz) 58662306a36Sopenharmony_ci#define NFS4_dec_setclientid_confirm_sz \ 58762306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 58862306a36Sopenharmony_ci decode_setclientid_confirm_maxsz) 58962306a36Sopenharmony_ci#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \ 59062306a36Sopenharmony_ci encode_sequence_maxsz + \ 59162306a36Sopenharmony_ci encode_putfh_maxsz + \ 59262306a36Sopenharmony_ci encode_lock_maxsz) 59362306a36Sopenharmony_ci#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \ 59462306a36Sopenharmony_ci decode_sequence_maxsz + \ 59562306a36Sopenharmony_ci decode_putfh_maxsz + \ 59662306a36Sopenharmony_ci decode_lock_maxsz) 59762306a36Sopenharmony_ci#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \ 59862306a36Sopenharmony_ci encode_sequence_maxsz + \ 59962306a36Sopenharmony_ci encode_putfh_maxsz + \ 60062306a36Sopenharmony_ci encode_lockt_maxsz) 60162306a36Sopenharmony_ci#define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \ 60262306a36Sopenharmony_ci decode_sequence_maxsz + \ 60362306a36Sopenharmony_ci decode_putfh_maxsz + \ 60462306a36Sopenharmony_ci decode_lockt_maxsz) 60562306a36Sopenharmony_ci#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \ 60662306a36Sopenharmony_ci encode_sequence_maxsz + \ 60762306a36Sopenharmony_ci encode_putfh_maxsz + \ 60862306a36Sopenharmony_ci encode_locku_maxsz) 60962306a36Sopenharmony_ci#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \ 61062306a36Sopenharmony_ci decode_sequence_maxsz + \ 61162306a36Sopenharmony_ci decode_putfh_maxsz + \ 61262306a36Sopenharmony_ci decode_locku_maxsz) 61362306a36Sopenharmony_ci#define NFS4_enc_release_lockowner_sz \ 61462306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 61562306a36Sopenharmony_ci encode_lockowner_maxsz) 61662306a36Sopenharmony_ci#define NFS4_dec_release_lockowner_sz \ 61762306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 61862306a36Sopenharmony_ci decode_lockowner_maxsz) 61962306a36Sopenharmony_ci#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \ 62062306a36Sopenharmony_ci encode_sequence_maxsz + \ 62162306a36Sopenharmony_ci encode_putfh_maxsz + \ 62262306a36Sopenharmony_ci encode_access_maxsz + \ 62362306a36Sopenharmony_ci encode_getattr_maxsz) 62462306a36Sopenharmony_ci#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \ 62562306a36Sopenharmony_ci decode_sequence_maxsz + \ 62662306a36Sopenharmony_ci decode_putfh_maxsz + \ 62762306a36Sopenharmony_ci decode_access_maxsz + \ 62862306a36Sopenharmony_ci decode_getattr_maxsz) 62962306a36Sopenharmony_ci#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \ 63062306a36Sopenharmony_ci encode_sequence_maxsz + \ 63162306a36Sopenharmony_ci encode_putfh_maxsz + \ 63262306a36Sopenharmony_ci encode_getattr_maxsz + \ 63362306a36Sopenharmony_ci encode_renew_maxsz) 63462306a36Sopenharmony_ci#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \ 63562306a36Sopenharmony_ci decode_sequence_maxsz + \ 63662306a36Sopenharmony_ci decode_putfh_maxsz + \ 63762306a36Sopenharmony_ci decode_getattr_maxsz + \ 63862306a36Sopenharmony_ci decode_renew_maxsz) 63962306a36Sopenharmony_ci#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \ 64062306a36Sopenharmony_ci encode_sequence_maxsz + \ 64162306a36Sopenharmony_ci encode_putfh_maxsz + \ 64262306a36Sopenharmony_ci encode_lookup_maxsz + \ 64362306a36Sopenharmony_ci encode_getattr_maxsz + \ 64462306a36Sopenharmony_ci encode_getfh_maxsz) 64562306a36Sopenharmony_ci#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \ 64662306a36Sopenharmony_ci decode_sequence_maxsz + \ 64762306a36Sopenharmony_ci decode_putfh_maxsz + \ 64862306a36Sopenharmony_ci decode_lookup_maxsz + \ 64962306a36Sopenharmony_ci decode_getattr_maxsz + \ 65062306a36Sopenharmony_ci decode_getfh_maxsz) 65162306a36Sopenharmony_ci#define NFS4_enc_lookupp_sz (compound_encode_hdr_maxsz + \ 65262306a36Sopenharmony_ci encode_sequence_maxsz + \ 65362306a36Sopenharmony_ci encode_putfh_maxsz + \ 65462306a36Sopenharmony_ci encode_lookupp_maxsz + \ 65562306a36Sopenharmony_ci encode_getattr_maxsz + \ 65662306a36Sopenharmony_ci encode_getfh_maxsz) 65762306a36Sopenharmony_ci#define NFS4_dec_lookupp_sz (compound_decode_hdr_maxsz + \ 65862306a36Sopenharmony_ci decode_sequence_maxsz + \ 65962306a36Sopenharmony_ci decode_putfh_maxsz + \ 66062306a36Sopenharmony_ci decode_lookupp_maxsz + \ 66162306a36Sopenharmony_ci decode_getattr_maxsz + \ 66262306a36Sopenharmony_ci decode_getfh_maxsz) 66362306a36Sopenharmony_ci#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \ 66462306a36Sopenharmony_ci encode_sequence_maxsz + \ 66562306a36Sopenharmony_ci encode_putrootfh_maxsz + \ 66662306a36Sopenharmony_ci encode_getattr_maxsz + \ 66762306a36Sopenharmony_ci encode_getfh_maxsz) 66862306a36Sopenharmony_ci#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \ 66962306a36Sopenharmony_ci decode_sequence_maxsz + \ 67062306a36Sopenharmony_ci decode_putrootfh_maxsz + \ 67162306a36Sopenharmony_ci decode_getattr_maxsz + \ 67262306a36Sopenharmony_ci decode_getfh_maxsz) 67362306a36Sopenharmony_ci#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ 67462306a36Sopenharmony_ci encode_sequence_maxsz + \ 67562306a36Sopenharmony_ci encode_putfh_maxsz + \ 67662306a36Sopenharmony_ci encode_remove_maxsz) 67762306a36Sopenharmony_ci#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ 67862306a36Sopenharmony_ci decode_sequence_maxsz + \ 67962306a36Sopenharmony_ci decode_putfh_maxsz + \ 68062306a36Sopenharmony_ci decode_remove_maxsz) 68162306a36Sopenharmony_ci#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ 68262306a36Sopenharmony_ci encode_sequence_maxsz + \ 68362306a36Sopenharmony_ci encode_putfh_maxsz + \ 68462306a36Sopenharmony_ci encode_savefh_maxsz + \ 68562306a36Sopenharmony_ci encode_putfh_maxsz + \ 68662306a36Sopenharmony_ci encode_rename_maxsz) 68762306a36Sopenharmony_ci#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ 68862306a36Sopenharmony_ci decode_sequence_maxsz + \ 68962306a36Sopenharmony_ci decode_putfh_maxsz + \ 69062306a36Sopenharmony_ci decode_savefh_maxsz + \ 69162306a36Sopenharmony_ci decode_putfh_maxsz + \ 69262306a36Sopenharmony_ci decode_rename_maxsz) 69362306a36Sopenharmony_ci#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ 69462306a36Sopenharmony_ci encode_sequence_maxsz + \ 69562306a36Sopenharmony_ci encode_putfh_maxsz + \ 69662306a36Sopenharmony_ci encode_savefh_maxsz + \ 69762306a36Sopenharmony_ci encode_putfh_maxsz + \ 69862306a36Sopenharmony_ci encode_link_maxsz + \ 69962306a36Sopenharmony_ci encode_restorefh_maxsz + \ 70062306a36Sopenharmony_ci encode_getattr_maxsz) 70162306a36Sopenharmony_ci#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ 70262306a36Sopenharmony_ci decode_sequence_maxsz + \ 70362306a36Sopenharmony_ci decode_putfh_maxsz + \ 70462306a36Sopenharmony_ci decode_savefh_maxsz + \ 70562306a36Sopenharmony_ci decode_putfh_maxsz + \ 70662306a36Sopenharmony_ci decode_link_maxsz + \ 70762306a36Sopenharmony_ci decode_restorefh_maxsz + \ 70862306a36Sopenharmony_ci decode_getattr_maxsz) 70962306a36Sopenharmony_ci#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ 71062306a36Sopenharmony_ci encode_sequence_maxsz + \ 71162306a36Sopenharmony_ci encode_putfh_maxsz + \ 71262306a36Sopenharmony_ci encode_symlink_maxsz + \ 71362306a36Sopenharmony_ci encode_getattr_maxsz + \ 71462306a36Sopenharmony_ci encode_getfh_maxsz) 71562306a36Sopenharmony_ci#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \ 71662306a36Sopenharmony_ci decode_sequence_maxsz + \ 71762306a36Sopenharmony_ci decode_putfh_maxsz + \ 71862306a36Sopenharmony_ci decode_symlink_maxsz + \ 71962306a36Sopenharmony_ci decode_getattr_maxsz + \ 72062306a36Sopenharmony_ci decode_getfh_maxsz) 72162306a36Sopenharmony_ci#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ 72262306a36Sopenharmony_ci encode_sequence_maxsz + \ 72362306a36Sopenharmony_ci encode_putfh_maxsz + \ 72462306a36Sopenharmony_ci encode_create_maxsz + \ 72562306a36Sopenharmony_ci encode_getfh_maxsz + \ 72662306a36Sopenharmony_ci encode_getattr_maxsz) 72762306a36Sopenharmony_ci#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ 72862306a36Sopenharmony_ci decode_sequence_maxsz + \ 72962306a36Sopenharmony_ci decode_putfh_maxsz + \ 73062306a36Sopenharmony_ci decode_create_maxsz + \ 73162306a36Sopenharmony_ci decode_getfh_maxsz + \ 73262306a36Sopenharmony_ci decode_getattr_maxsz) 73362306a36Sopenharmony_ci#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ 73462306a36Sopenharmony_ci encode_sequence_maxsz + \ 73562306a36Sopenharmony_ci encode_putfh_maxsz + \ 73662306a36Sopenharmony_ci encode_getattr_maxsz) 73762306a36Sopenharmony_ci#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \ 73862306a36Sopenharmony_ci decode_sequence_maxsz + \ 73962306a36Sopenharmony_ci decode_putfh_maxsz + \ 74062306a36Sopenharmony_ci decode_getattr_maxsz) 74162306a36Sopenharmony_ci#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \ 74262306a36Sopenharmony_ci encode_sequence_maxsz + \ 74362306a36Sopenharmony_ci encode_putfh_maxsz + \ 74462306a36Sopenharmony_ci encode_statfs_maxsz) 74562306a36Sopenharmony_ci#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \ 74662306a36Sopenharmony_ci decode_sequence_maxsz + \ 74762306a36Sopenharmony_ci decode_putfh_maxsz + \ 74862306a36Sopenharmony_ci decode_statfs_maxsz) 74962306a36Sopenharmony_ci#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \ 75062306a36Sopenharmony_ci encode_sequence_maxsz + \ 75162306a36Sopenharmony_ci encode_putfh_maxsz + \ 75262306a36Sopenharmony_ci encode_getattr_maxsz) 75362306a36Sopenharmony_ci#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \ 75462306a36Sopenharmony_ci decode_sequence_maxsz + \ 75562306a36Sopenharmony_ci decode_putfh_maxsz + \ 75662306a36Sopenharmony_ci decode_getattr_maxsz) 75762306a36Sopenharmony_ci#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \ 75862306a36Sopenharmony_ci encode_sequence_maxsz + \ 75962306a36Sopenharmony_ci encode_putfh_maxsz + \ 76062306a36Sopenharmony_ci encode_layoutreturn_maxsz + \ 76162306a36Sopenharmony_ci encode_delegreturn_maxsz + \ 76262306a36Sopenharmony_ci encode_getattr_maxsz) 76362306a36Sopenharmony_ci#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \ 76462306a36Sopenharmony_ci decode_sequence_maxsz + \ 76562306a36Sopenharmony_ci decode_putfh_maxsz + \ 76662306a36Sopenharmony_ci decode_layoutreturn_maxsz + \ 76762306a36Sopenharmony_ci decode_delegreturn_maxsz + \ 76862306a36Sopenharmony_ci decode_getattr_maxsz) 76962306a36Sopenharmony_ci#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \ 77062306a36Sopenharmony_ci encode_sequence_maxsz + \ 77162306a36Sopenharmony_ci encode_putfh_maxsz + \ 77262306a36Sopenharmony_ci encode_getacl_maxsz) 77362306a36Sopenharmony_ci#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \ 77462306a36Sopenharmony_ci decode_sequence_maxsz + \ 77562306a36Sopenharmony_ci decode_putfh_maxsz + \ 77662306a36Sopenharmony_ci decode_getacl_maxsz) 77762306a36Sopenharmony_ci#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \ 77862306a36Sopenharmony_ci encode_sequence_maxsz + \ 77962306a36Sopenharmony_ci encode_putfh_maxsz + \ 78062306a36Sopenharmony_ci encode_setacl_maxsz) 78162306a36Sopenharmony_ci#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \ 78262306a36Sopenharmony_ci decode_sequence_maxsz + \ 78362306a36Sopenharmony_ci decode_putfh_maxsz + \ 78462306a36Sopenharmony_ci decode_setacl_maxsz) 78562306a36Sopenharmony_ci#define NFS4_enc_fs_locations_sz \ 78662306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 78762306a36Sopenharmony_ci encode_sequence_maxsz + \ 78862306a36Sopenharmony_ci encode_putfh_maxsz + \ 78962306a36Sopenharmony_ci encode_lookup_maxsz + \ 79062306a36Sopenharmony_ci encode_fs_locations_maxsz + \ 79162306a36Sopenharmony_ci encode_renew_maxsz) 79262306a36Sopenharmony_ci#define NFS4_dec_fs_locations_sz \ 79362306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 79462306a36Sopenharmony_ci decode_sequence_maxsz + \ 79562306a36Sopenharmony_ci decode_putfh_maxsz + \ 79662306a36Sopenharmony_ci decode_lookup_maxsz + \ 79762306a36Sopenharmony_ci decode_fs_locations_maxsz + \ 79862306a36Sopenharmony_ci decode_renew_maxsz) 79962306a36Sopenharmony_ci#define NFS4_enc_secinfo_sz (compound_encode_hdr_maxsz + \ 80062306a36Sopenharmony_ci encode_sequence_maxsz + \ 80162306a36Sopenharmony_ci encode_putfh_maxsz + \ 80262306a36Sopenharmony_ci encode_secinfo_maxsz) 80362306a36Sopenharmony_ci#define NFS4_dec_secinfo_sz (compound_decode_hdr_maxsz + \ 80462306a36Sopenharmony_ci decode_sequence_maxsz + \ 80562306a36Sopenharmony_ci decode_putfh_maxsz + \ 80662306a36Sopenharmony_ci decode_secinfo_maxsz) 80762306a36Sopenharmony_ci#define NFS4_enc_fsid_present_sz \ 80862306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 80962306a36Sopenharmony_ci encode_sequence_maxsz + \ 81062306a36Sopenharmony_ci encode_putfh_maxsz + \ 81162306a36Sopenharmony_ci encode_getfh_maxsz + \ 81262306a36Sopenharmony_ci encode_renew_maxsz) 81362306a36Sopenharmony_ci#define NFS4_dec_fsid_present_sz \ 81462306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 81562306a36Sopenharmony_ci decode_sequence_maxsz + \ 81662306a36Sopenharmony_ci decode_putfh_maxsz + \ 81762306a36Sopenharmony_ci decode_getfh_maxsz + \ 81862306a36Sopenharmony_ci decode_renew_maxsz) 81962306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 82062306a36Sopenharmony_ci#define NFS4_enc_bind_conn_to_session_sz \ 82162306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 82262306a36Sopenharmony_ci encode_bind_conn_to_session_maxsz) 82362306a36Sopenharmony_ci#define NFS4_dec_bind_conn_to_session_sz \ 82462306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 82562306a36Sopenharmony_ci decode_bind_conn_to_session_maxsz) 82662306a36Sopenharmony_ci#define NFS4_enc_exchange_id_sz \ 82762306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 82862306a36Sopenharmony_ci encode_exchange_id_maxsz) 82962306a36Sopenharmony_ci#define NFS4_dec_exchange_id_sz \ 83062306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 83162306a36Sopenharmony_ci decode_exchange_id_maxsz) 83262306a36Sopenharmony_ci#define NFS4_enc_create_session_sz \ 83362306a36Sopenharmony_ci (compound_encode_hdr_maxsz + \ 83462306a36Sopenharmony_ci encode_create_session_maxsz) 83562306a36Sopenharmony_ci#define NFS4_dec_create_session_sz \ 83662306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 83762306a36Sopenharmony_ci decode_create_session_maxsz) 83862306a36Sopenharmony_ci#define NFS4_enc_destroy_session_sz (compound_encode_hdr_maxsz + \ 83962306a36Sopenharmony_ci encode_destroy_session_maxsz) 84062306a36Sopenharmony_ci#define NFS4_dec_destroy_session_sz (compound_decode_hdr_maxsz + \ 84162306a36Sopenharmony_ci decode_destroy_session_maxsz) 84262306a36Sopenharmony_ci#define NFS4_enc_destroy_clientid_sz (compound_encode_hdr_maxsz + \ 84362306a36Sopenharmony_ci encode_destroy_clientid_maxsz) 84462306a36Sopenharmony_ci#define NFS4_dec_destroy_clientid_sz (compound_decode_hdr_maxsz + \ 84562306a36Sopenharmony_ci decode_destroy_clientid_maxsz) 84662306a36Sopenharmony_ci#define NFS4_enc_sequence_sz \ 84762306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 84862306a36Sopenharmony_ci encode_sequence_maxsz) 84962306a36Sopenharmony_ci#define NFS4_dec_sequence_sz \ 85062306a36Sopenharmony_ci (compound_decode_hdr_maxsz + \ 85162306a36Sopenharmony_ci decode_sequence_maxsz) 85262306a36Sopenharmony_ci#endif 85362306a36Sopenharmony_ci#define NFS4_enc_get_lease_time_sz (compound_encode_hdr_maxsz + \ 85462306a36Sopenharmony_ci encode_sequence_maxsz + \ 85562306a36Sopenharmony_ci encode_putrootfh_maxsz + \ 85662306a36Sopenharmony_ci encode_fsinfo_maxsz) 85762306a36Sopenharmony_ci#define NFS4_dec_get_lease_time_sz (compound_decode_hdr_maxsz + \ 85862306a36Sopenharmony_ci decode_sequence_maxsz + \ 85962306a36Sopenharmony_ci decode_putrootfh_maxsz + \ 86062306a36Sopenharmony_ci decode_fsinfo_maxsz) 86162306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 86262306a36Sopenharmony_ci#define NFS4_enc_reclaim_complete_sz (compound_encode_hdr_maxsz + \ 86362306a36Sopenharmony_ci encode_sequence_maxsz + \ 86462306a36Sopenharmony_ci encode_reclaim_complete_maxsz) 86562306a36Sopenharmony_ci#define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ 86662306a36Sopenharmony_ci decode_sequence_maxsz + \ 86762306a36Sopenharmony_ci decode_reclaim_complete_maxsz) 86862306a36Sopenharmony_ci#define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ 86962306a36Sopenharmony_ci encode_sequence_maxsz +\ 87062306a36Sopenharmony_ci encode_getdeviceinfo_maxsz) 87162306a36Sopenharmony_ci#define NFS4_dec_getdeviceinfo_sz (compound_decode_hdr_maxsz + \ 87262306a36Sopenharmony_ci decode_sequence_maxsz + \ 87362306a36Sopenharmony_ci decode_getdeviceinfo_maxsz) 87462306a36Sopenharmony_ci#define NFS4_enc_layoutget_sz (compound_encode_hdr_maxsz + \ 87562306a36Sopenharmony_ci encode_sequence_maxsz + \ 87662306a36Sopenharmony_ci encode_putfh_maxsz + \ 87762306a36Sopenharmony_ci encode_layoutget_maxsz) 87862306a36Sopenharmony_ci#define NFS4_dec_layoutget_sz (compound_decode_hdr_maxsz + \ 87962306a36Sopenharmony_ci decode_sequence_maxsz + \ 88062306a36Sopenharmony_ci decode_putfh_maxsz + \ 88162306a36Sopenharmony_ci decode_layoutget_maxsz) 88262306a36Sopenharmony_ci#define NFS4_enc_layoutcommit_sz (compound_encode_hdr_maxsz + \ 88362306a36Sopenharmony_ci encode_sequence_maxsz +\ 88462306a36Sopenharmony_ci encode_putfh_maxsz + \ 88562306a36Sopenharmony_ci encode_layoutcommit_maxsz + \ 88662306a36Sopenharmony_ci encode_getattr_maxsz) 88762306a36Sopenharmony_ci#define NFS4_dec_layoutcommit_sz (compound_decode_hdr_maxsz + \ 88862306a36Sopenharmony_ci decode_sequence_maxsz + \ 88962306a36Sopenharmony_ci decode_putfh_maxsz + \ 89062306a36Sopenharmony_ci decode_layoutcommit_maxsz + \ 89162306a36Sopenharmony_ci decode_getattr_maxsz) 89262306a36Sopenharmony_ci#define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \ 89362306a36Sopenharmony_ci encode_sequence_maxsz + \ 89462306a36Sopenharmony_ci encode_putfh_maxsz + \ 89562306a36Sopenharmony_ci encode_layoutreturn_maxsz) 89662306a36Sopenharmony_ci#define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \ 89762306a36Sopenharmony_ci decode_sequence_maxsz + \ 89862306a36Sopenharmony_ci decode_putfh_maxsz + \ 89962306a36Sopenharmony_ci decode_layoutreturn_maxsz) 90062306a36Sopenharmony_ci#define NFS4_enc_secinfo_no_name_sz (compound_encode_hdr_maxsz + \ 90162306a36Sopenharmony_ci encode_sequence_maxsz + \ 90262306a36Sopenharmony_ci encode_putrootfh_maxsz +\ 90362306a36Sopenharmony_ci encode_secinfo_no_name_maxsz) 90462306a36Sopenharmony_ci#define NFS4_dec_secinfo_no_name_sz (compound_decode_hdr_maxsz + \ 90562306a36Sopenharmony_ci decode_sequence_maxsz + \ 90662306a36Sopenharmony_ci decode_putrootfh_maxsz + \ 90762306a36Sopenharmony_ci decode_secinfo_no_name_maxsz) 90862306a36Sopenharmony_ci#define NFS4_enc_test_stateid_sz (compound_encode_hdr_maxsz + \ 90962306a36Sopenharmony_ci encode_sequence_maxsz + \ 91062306a36Sopenharmony_ci encode_test_stateid_maxsz) 91162306a36Sopenharmony_ci#define NFS4_dec_test_stateid_sz (compound_decode_hdr_maxsz + \ 91262306a36Sopenharmony_ci decode_sequence_maxsz + \ 91362306a36Sopenharmony_ci decode_test_stateid_maxsz) 91462306a36Sopenharmony_ci#define NFS4_enc_free_stateid_sz (compound_encode_hdr_maxsz + \ 91562306a36Sopenharmony_ci encode_sequence_maxsz + \ 91662306a36Sopenharmony_ci encode_free_stateid_maxsz) 91762306a36Sopenharmony_ci#define NFS4_dec_free_stateid_sz (compound_decode_hdr_maxsz + \ 91862306a36Sopenharmony_ci decode_sequence_maxsz + \ 91962306a36Sopenharmony_ci decode_free_stateid_maxsz) 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ciconst u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 92262306a36Sopenharmony_ci compound_encode_hdr_maxsz + 92362306a36Sopenharmony_ci encode_sequence_maxsz + 92462306a36Sopenharmony_ci encode_putfh_maxsz + 92562306a36Sopenharmony_ci encode_getattr_maxsz) * 92662306a36Sopenharmony_ci XDR_UNIT); 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ciconst u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH + 92962306a36Sopenharmony_ci compound_decode_hdr_maxsz + 93062306a36Sopenharmony_ci decode_sequence_maxsz + 93162306a36Sopenharmony_ci decode_putfh_maxsz) * 93262306a36Sopenharmony_ci XDR_UNIT); 93362306a36Sopenharmony_ci 93462306a36Sopenharmony_ciconst u32 nfs41_maxgetdevinfo_overhead = ((RPC_MAX_REPHEADER_WITH_AUTH + 93562306a36Sopenharmony_ci compound_decode_hdr_maxsz + 93662306a36Sopenharmony_ci decode_sequence_maxsz) * 93762306a36Sopenharmony_ci XDR_UNIT); 93862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(nfs41_maxgetdevinfo_overhead); 93962306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_cistatic const umode_t nfs_type2fmt[] = { 94262306a36Sopenharmony_ci [NF4BAD] = 0, 94362306a36Sopenharmony_ci [NF4REG] = S_IFREG, 94462306a36Sopenharmony_ci [NF4DIR] = S_IFDIR, 94562306a36Sopenharmony_ci [NF4BLK] = S_IFBLK, 94662306a36Sopenharmony_ci [NF4CHR] = S_IFCHR, 94762306a36Sopenharmony_ci [NF4LNK] = S_IFLNK, 94862306a36Sopenharmony_ci [NF4SOCK] = S_IFSOCK, 94962306a36Sopenharmony_ci [NF4FIFO] = S_IFIFO, 95062306a36Sopenharmony_ci [NF4ATTRDIR] = 0, 95162306a36Sopenharmony_ci [NF4NAMEDATTR] = 0, 95262306a36Sopenharmony_ci}; 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_cistruct compound_hdr { 95562306a36Sopenharmony_ci int32_t status; 95662306a36Sopenharmony_ci uint32_t nops; 95762306a36Sopenharmony_ci __be32 * nops_p; 95862306a36Sopenharmony_ci uint32_t taglen; 95962306a36Sopenharmony_ci char * tag; 96062306a36Sopenharmony_ci uint32_t replen; /* expected reply words */ 96162306a36Sopenharmony_ci u32 minorversion; 96262306a36Sopenharmony_ci}; 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_cistatic __be32 *reserve_space(struct xdr_stream *xdr, size_t nbytes) 96562306a36Sopenharmony_ci{ 96662306a36Sopenharmony_ci __be32 *p = xdr_reserve_space(xdr, nbytes); 96762306a36Sopenharmony_ci BUG_ON(!p); 96862306a36Sopenharmony_ci return p; 96962306a36Sopenharmony_ci} 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_cistatic void encode_opaque_fixed(struct xdr_stream *xdr, const void *buf, size_t len) 97262306a36Sopenharmony_ci{ 97362306a36Sopenharmony_ci WARN_ON_ONCE(xdr_stream_encode_opaque_fixed(xdr, buf, len) < 0); 97462306a36Sopenharmony_ci} 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_cistatic void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) 97762306a36Sopenharmony_ci{ 97862306a36Sopenharmony_ci WARN_ON_ONCE(xdr_stream_encode_opaque(xdr, str, len) < 0); 97962306a36Sopenharmony_ci} 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_cistatic void encode_uint32(struct xdr_stream *xdr, u32 n) 98262306a36Sopenharmony_ci{ 98362306a36Sopenharmony_ci WARN_ON_ONCE(xdr_stream_encode_u32(xdr, n) < 0); 98462306a36Sopenharmony_ci} 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_cistatic void encode_uint64(struct xdr_stream *xdr, u64 n) 98762306a36Sopenharmony_ci{ 98862306a36Sopenharmony_ci WARN_ON_ONCE(xdr_stream_encode_u64(xdr, n) < 0); 98962306a36Sopenharmony_ci} 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_cistatic ssize_t xdr_encode_bitmap4(struct xdr_stream *xdr, 99262306a36Sopenharmony_ci const __u32 *bitmap, size_t len) 99362306a36Sopenharmony_ci{ 99462306a36Sopenharmony_ci ssize_t ret; 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci /* Trim empty words */ 99762306a36Sopenharmony_ci while (len > 0 && bitmap[len-1] == 0) 99862306a36Sopenharmony_ci len--; 99962306a36Sopenharmony_ci ret = xdr_stream_encode_uint32_array(xdr, bitmap, len); 100062306a36Sopenharmony_ci if (WARN_ON_ONCE(ret < 0)) 100162306a36Sopenharmony_ci return ret; 100262306a36Sopenharmony_ci return len; 100362306a36Sopenharmony_ci} 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_cistatic size_t mask_bitmap4(const __u32 *bitmap, const __u32 *mask, 100662306a36Sopenharmony_ci __u32 *res, size_t len) 100762306a36Sopenharmony_ci{ 100862306a36Sopenharmony_ci size_t i; 100962306a36Sopenharmony_ci __u32 tmp; 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci while (len > 0 && (bitmap[len-1] == 0 || mask[len-1] == 0)) 101262306a36Sopenharmony_ci len--; 101362306a36Sopenharmony_ci for (i = len; i-- > 0;) { 101462306a36Sopenharmony_ci tmp = bitmap[i] & mask[i]; 101562306a36Sopenharmony_ci res[i] = tmp; 101662306a36Sopenharmony_ci } 101762306a36Sopenharmony_ci return len; 101862306a36Sopenharmony_ci} 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_cistatic void encode_nfs4_seqid(struct xdr_stream *xdr, 102162306a36Sopenharmony_ci const struct nfs_seqid *seqid) 102262306a36Sopenharmony_ci{ 102362306a36Sopenharmony_ci if (seqid != NULL) 102462306a36Sopenharmony_ci encode_uint32(xdr, seqid->sequence->counter); 102562306a36Sopenharmony_ci else 102662306a36Sopenharmony_ci encode_uint32(xdr, 0); 102762306a36Sopenharmony_ci} 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_cistatic void encode_compound_hdr(struct xdr_stream *xdr, 103062306a36Sopenharmony_ci struct rpc_rqst *req, 103162306a36Sopenharmony_ci struct compound_hdr *hdr) 103262306a36Sopenharmony_ci{ 103362306a36Sopenharmony_ci __be32 *p; 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci /* initialize running count of expected bytes in reply. 103662306a36Sopenharmony_ci * NOTE: the replied tag SHOULD be the same is the one sent, 103762306a36Sopenharmony_ci * but this is not required as a MUST for the server to do so. */ 103862306a36Sopenharmony_ci hdr->replen = 3 + hdr->taglen; 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci WARN_ON_ONCE(hdr->taglen > NFS4_MAXTAGLEN); 104162306a36Sopenharmony_ci encode_string(xdr, hdr->taglen, hdr->tag); 104262306a36Sopenharmony_ci p = reserve_space(xdr, 8); 104362306a36Sopenharmony_ci *p++ = cpu_to_be32(hdr->minorversion); 104462306a36Sopenharmony_ci hdr->nops_p = p; 104562306a36Sopenharmony_ci *p = cpu_to_be32(hdr->nops); 104662306a36Sopenharmony_ci} 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_cistatic void encode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 op, 104962306a36Sopenharmony_ci uint32_t replen, 105062306a36Sopenharmony_ci struct compound_hdr *hdr) 105162306a36Sopenharmony_ci{ 105262306a36Sopenharmony_ci encode_uint32(xdr, op); 105362306a36Sopenharmony_ci hdr->nops++; 105462306a36Sopenharmony_ci hdr->replen += replen; 105562306a36Sopenharmony_ci} 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_cistatic void encode_nops(struct compound_hdr *hdr) 105862306a36Sopenharmony_ci{ 105962306a36Sopenharmony_ci WARN_ON_ONCE(hdr->nops > NFS4_MAX_OPS); 106062306a36Sopenharmony_ci *hdr->nops_p = htonl(hdr->nops); 106162306a36Sopenharmony_ci} 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_cistatic void encode_nfs4_stateid(struct xdr_stream *xdr, const nfs4_stateid *stateid) 106462306a36Sopenharmony_ci{ 106562306a36Sopenharmony_ci encode_opaque_fixed(xdr, stateid, NFS4_STATEID_SIZE); 106662306a36Sopenharmony_ci} 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_cistatic void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf) 106962306a36Sopenharmony_ci{ 107062306a36Sopenharmony_ci encode_opaque_fixed(xdr, verf->data, NFS4_VERIFIER_SIZE); 107162306a36Sopenharmony_ci} 107262306a36Sopenharmony_ci 107362306a36Sopenharmony_cistatic __be32 * 107462306a36Sopenharmony_cixdr_encode_nfstime4(__be32 *p, const struct timespec64 *t) 107562306a36Sopenharmony_ci{ 107662306a36Sopenharmony_ci p = xdr_encode_hyper(p, t->tv_sec); 107762306a36Sopenharmony_ci *p++ = cpu_to_be32(t->tv_nsec); 107862306a36Sopenharmony_ci return p; 107962306a36Sopenharmony_ci} 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_cistatic void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, 108262306a36Sopenharmony_ci const struct nfs4_label *label, 108362306a36Sopenharmony_ci const umode_t *umask, 108462306a36Sopenharmony_ci const struct nfs_server *server, 108562306a36Sopenharmony_ci const uint32_t attrmask[]) 108662306a36Sopenharmony_ci{ 108762306a36Sopenharmony_ci char owner_name[IDMAP_NAMESZ]; 108862306a36Sopenharmony_ci char owner_group[IDMAP_NAMESZ]; 108962306a36Sopenharmony_ci int owner_namelen = 0; 109062306a36Sopenharmony_ci int owner_grouplen = 0; 109162306a36Sopenharmony_ci __be32 *p; 109262306a36Sopenharmony_ci uint32_t len = 0; 109362306a36Sopenharmony_ci uint32_t bmval[3] = { 0 }; 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_ci /* 109662306a36Sopenharmony_ci * We reserve enough space to write the entire attribute buffer at once. 109762306a36Sopenharmony_ci */ 109862306a36Sopenharmony_ci if ((iap->ia_valid & ATTR_SIZE) && (attrmask[0] & FATTR4_WORD0_SIZE)) { 109962306a36Sopenharmony_ci bmval[0] |= FATTR4_WORD0_SIZE; 110062306a36Sopenharmony_ci len += 8; 110162306a36Sopenharmony_ci } 110262306a36Sopenharmony_ci if (iap->ia_valid & ATTR_MODE) { 110362306a36Sopenharmony_ci if (umask && (attrmask[2] & FATTR4_WORD2_MODE_UMASK)) { 110462306a36Sopenharmony_ci bmval[2] |= FATTR4_WORD2_MODE_UMASK; 110562306a36Sopenharmony_ci len += 8; 110662306a36Sopenharmony_ci } else if (attrmask[1] & FATTR4_WORD1_MODE) { 110762306a36Sopenharmony_ci bmval[1] |= FATTR4_WORD1_MODE; 110862306a36Sopenharmony_ci len += 4; 110962306a36Sopenharmony_ci } 111062306a36Sopenharmony_ci } 111162306a36Sopenharmony_ci if ((iap->ia_valid & ATTR_UID) && (attrmask[1] & FATTR4_WORD1_OWNER)) { 111262306a36Sopenharmony_ci owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); 111362306a36Sopenharmony_ci if (owner_namelen < 0) { 111462306a36Sopenharmony_ci dprintk("nfs: couldn't resolve uid %d to string\n", 111562306a36Sopenharmony_ci from_kuid(&init_user_ns, iap->ia_uid)); 111662306a36Sopenharmony_ci /* XXX */ 111762306a36Sopenharmony_ci strcpy(owner_name, "nobody"); 111862306a36Sopenharmony_ci owner_namelen = sizeof("nobody") - 1; 111962306a36Sopenharmony_ci /* goto out; */ 112062306a36Sopenharmony_ci } 112162306a36Sopenharmony_ci bmval[1] |= FATTR4_WORD1_OWNER; 112262306a36Sopenharmony_ci len += 4 + (XDR_QUADLEN(owner_namelen) << 2); 112362306a36Sopenharmony_ci } 112462306a36Sopenharmony_ci if ((iap->ia_valid & ATTR_GID) && 112562306a36Sopenharmony_ci (attrmask[1] & FATTR4_WORD1_OWNER_GROUP)) { 112662306a36Sopenharmony_ci owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ); 112762306a36Sopenharmony_ci if (owner_grouplen < 0) { 112862306a36Sopenharmony_ci dprintk("nfs: couldn't resolve gid %d to string\n", 112962306a36Sopenharmony_ci from_kgid(&init_user_ns, iap->ia_gid)); 113062306a36Sopenharmony_ci strcpy(owner_group, "nobody"); 113162306a36Sopenharmony_ci owner_grouplen = sizeof("nobody") - 1; 113262306a36Sopenharmony_ci /* goto out; */ 113362306a36Sopenharmony_ci } 113462306a36Sopenharmony_ci bmval[1] |= FATTR4_WORD1_OWNER_GROUP; 113562306a36Sopenharmony_ci len += 4 + (XDR_QUADLEN(owner_grouplen) << 2); 113662306a36Sopenharmony_ci } 113762306a36Sopenharmony_ci if (attrmask[1] & FATTR4_WORD1_TIME_ACCESS_SET) { 113862306a36Sopenharmony_ci if (iap->ia_valid & ATTR_ATIME_SET) { 113962306a36Sopenharmony_ci bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; 114062306a36Sopenharmony_ci len += 4 + (nfstime4_maxsz << 2); 114162306a36Sopenharmony_ci } else if (iap->ia_valid & ATTR_ATIME) { 114262306a36Sopenharmony_ci bmval[1] |= FATTR4_WORD1_TIME_ACCESS_SET; 114362306a36Sopenharmony_ci len += 4; 114462306a36Sopenharmony_ci } 114562306a36Sopenharmony_ci } 114662306a36Sopenharmony_ci if (attrmask[1] & FATTR4_WORD1_TIME_MODIFY_SET) { 114762306a36Sopenharmony_ci if (iap->ia_valid & ATTR_MTIME_SET) { 114862306a36Sopenharmony_ci bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; 114962306a36Sopenharmony_ci len += 4 + (nfstime4_maxsz << 2); 115062306a36Sopenharmony_ci } else if (iap->ia_valid & ATTR_MTIME) { 115162306a36Sopenharmony_ci bmval[1] |= FATTR4_WORD1_TIME_MODIFY_SET; 115262306a36Sopenharmony_ci len += 4; 115362306a36Sopenharmony_ci } 115462306a36Sopenharmony_ci } 115562306a36Sopenharmony_ci 115662306a36Sopenharmony_ci if (label && (attrmask[2] & FATTR4_WORD2_SECURITY_LABEL)) { 115762306a36Sopenharmony_ci len += 4 + 4 + 4 + (XDR_QUADLEN(label->len) << 2); 115862306a36Sopenharmony_ci bmval[2] |= FATTR4_WORD2_SECURITY_LABEL; 115962306a36Sopenharmony_ci } 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_ci xdr_encode_bitmap4(xdr, bmval, ARRAY_SIZE(bmval)); 116262306a36Sopenharmony_ci xdr_stream_encode_opaque_inline(xdr, (void **)&p, len); 116362306a36Sopenharmony_ci 116462306a36Sopenharmony_ci if (bmval[0] & FATTR4_WORD0_SIZE) 116562306a36Sopenharmony_ci p = xdr_encode_hyper(p, iap->ia_size); 116662306a36Sopenharmony_ci if (bmval[1] & FATTR4_WORD1_MODE) 116762306a36Sopenharmony_ci *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); 116862306a36Sopenharmony_ci if (bmval[1] & FATTR4_WORD1_OWNER) 116962306a36Sopenharmony_ci p = xdr_encode_opaque(p, owner_name, owner_namelen); 117062306a36Sopenharmony_ci if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) 117162306a36Sopenharmony_ci p = xdr_encode_opaque(p, owner_group, owner_grouplen); 117262306a36Sopenharmony_ci if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { 117362306a36Sopenharmony_ci if (iap->ia_valid & ATTR_ATIME_SET) { 117462306a36Sopenharmony_ci *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); 117562306a36Sopenharmony_ci p = xdr_encode_nfstime4(p, &iap->ia_atime); 117662306a36Sopenharmony_ci } else 117762306a36Sopenharmony_ci *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); 117862306a36Sopenharmony_ci } 117962306a36Sopenharmony_ci if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) { 118062306a36Sopenharmony_ci if (iap->ia_valid & ATTR_MTIME_SET) { 118162306a36Sopenharmony_ci *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); 118262306a36Sopenharmony_ci p = xdr_encode_nfstime4(p, &iap->ia_mtime); 118362306a36Sopenharmony_ci } else 118462306a36Sopenharmony_ci *p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME); 118562306a36Sopenharmony_ci } 118662306a36Sopenharmony_ci if (label && (bmval[2] & FATTR4_WORD2_SECURITY_LABEL)) { 118762306a36Sopenharmony_ci *p++ = cpu_to_be32(label->lfs); 118862306a36Sopenharmony_ci *p++ = cpu_to_be32(label->pi); 118962306a36Sopenharmony_ci *p++ = cpu_to_be32(label->len); 119062306a36Sopenharmony_ci p = xdr_encode_opaque_fixed(p, label->label, label->len); 119162306a36Sopenharmony_ci } 119262306a36Sopenharmony_ci if (bmval[2] & FATTR4_WORD2_MODE_UMASK) { 119362306a36Sopenharmony_ci *p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO); 119462306a36Sopenharmony_ci *p++ = cpu_to_be32(*umask); 119562306a36Sopenharmony_ci } 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci/* out: */ 119862306a36Sopenharmony_ci} 119962306a36Sopenharmony_ci 120062306a36Sopenharmony_cistatic void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hdr *hdr) 120162306a36Sopenharmony_ci{ 120262306a36Sopenharmony_ci encode_op_hdr(xdr, OP_ACCESS, decode_access_maxsz, hdr); 120362306a36Sopenharmony_ci encode_uint32(xdr, access); 120462306a36Sopenharmony_ci} 120562306a36Sopenharmony_ci 120662306a36Sopenharmony_cistatic void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr) 120762306a36Sopenharmony_ci{ 120862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_CLOSE, decode_close_maxsz, hdr); 120962306a36Sopenharmony_ci encode_nfs4_seqid(xdr, arg->seqid); 121062306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &arg->stateid); 121162306a36Sopenharmony_ci} 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_cistatic void encode_commit(struct xdr_stream *xdr, const struct nfs_commitargs *args, struct compound_hdr *hdr) 121462306a36Sopenharmony_ci{ 121562306a36Sopenharmony_ci __be32 *p; 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ci encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); 121862306a36Sopenharmony_ci p = reserve_space(xdr, 12); 121962306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->offset); 122062306a36Sopenharmony_ci *p = cpu_to_be32(args->count); 122162306a36Sopenharmony_ci} 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_cistatic void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr) 122462306a36Sopenharmony_ci{ 122562306a36Sopenharmony_ci __be32 *p; 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci encode_op_hdr(xdr, OP_CREATE, decode_create_maxsz, hdr); 122862306a36Sopenharmony_ci encode_uint32(xdr, create->ftype); 122962306a36Sopenharmony_ci 123062306a36Sopenharmony_ci switch (create->ftype) { 123162306a36Sopenharmony_ci case NF4LNK: 123262306a36Sopenharmony_ci p = reserve_space(xdr, 4); 123362306a36Sopenharmony_ci *p = cpu_to_be32(create->u.symlink.len); 123462306a36Sopenharmony_ci xdr_write_pages(xdr, create->u.symlink.pages, 0, 123562306a36Sopenharmony_ci create->u.symlink.len); 123662306a36Sopenharmony_ci xdr->buf->flags |= XDRBUF_WRITE; 123762306a36Sopenharmony_ci break; 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci case NF4BLK: case NF4CHR: 124062306a36Sopenharmony_ci p = reserve_space(xdr, 8); 124162306a36Sopenharmony_ci *p++ = cpu_to_be32(create->u.device.specdata1); 124262306a36Sopenharmony_ci *p = cpu_to_be32(create->u.device.specdata2); 124362306a36Sopenharmony_ci break; 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci default: 124662306a36Sopenharmony_ci break; 124762306a36Sopenharmony_ci } 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci encode_string(xdr, create->name->len, create->name->name); 125062306a36Sopenharmony_ci encode_attrs(xdr, create->attrs, create->label, &create->umask, 125162306a36Sopenharmony_ci create->server, create->server->attr_bitmask); 125262306a36Sopenharmony_ci} 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_cistatic void encode_getattr(struct xdr_stream *xdr, 125562306a36Sopenharmony_ci const __u32 *bitmap, const __u32 *mask, size_t len, 125662306a36Sopenharmony_ci struct compound_hdr *hdr) 125762306a36Sopenharmony_ci{ 125862306a36Sopenharmony_ci __u32 masked_bitmap[nfs4_fattr_bitmap_maxsz]; 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci encode_op_hdr(xdr, OP_GETATTR, decode_getattr_maxsz, hdr); 126162306a36Sopenharmony_ci if (mask) { 126262306a36Sopenharmony_ci if (WARN_ON_ONCE(len > ARRAY_SIZE(masked_bitmap))) 126362306a36Sopenharmony_ci len = ARRAY_SIZE(masked_bitmap); 126462306a36Sopenharmony_ci len = mask_bitmap4(bitmap, mask, masked_bitmap, len); 126562306a36Sopenharmony_ci bitmap = masked_bitmap; 126662306a36Sopenharmony_ci } 126762306a36Sopenharmony_ci xdr_encode_bitmap4(xdr, bitmap, len); 126862306a36Sopenharmony_ci} 126962306a36Sopenharmony_ci 127062306a36Sopenharmony_cistatic void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 127162306a36Sopenharmony_ci{ 127262306a36Sopenharmony_ci encode_getattr(xdr, nfs4_fattr_bitmap, bitmask, 127362306a36Sopenharmony_ci ARRAY_SIZE(nfs4_fattr_bitmap), hdr); 127462306a36Sopenharmony_ci} 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_cistatic void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask, 127762306a36Sopenharmony_ci const u32 *open_bitmap, 127862306a36Sopenharmony_ci struct compound_hdr *hdr) 127962306a36Sopenharmony_ci{ 128062306a36Sopenharmony_ci encode_getattr(xdr, open_bitmap, bitmask, 3, hdr); 128162306a36Sopenharmony_ci} 128262306a36Sopenharmony_ci 128362306a36Sopenharmony_cistatic void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 128462306a36Sopenharmony_ci{ 128562306a36Sopenharmony_ci encode_getattr(xdr, nfs4_fsinfo_bitmap, bitmask, 128662306a36Sopenharmony_ci ARRAY_SIZE(nfs4_fsinfo_bitmap), hdr); 128762306a36Sopenharmony_ci} 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_cistatic void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 129062306a36Sopenharmony_ci{ 129162306a36Sopenharmony_ci encode_getattr(xdr, nfs4_fs_locations_bitmap, bitmask, 129262306a36Sopenharmony_ci ARRAY_SIZE(nfs4_fs_locations_bitmap), hdr); 129362306a36Sopenharmony_ci} 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_cistatic void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr) 129662306a36Sopenharmony_ci{ 129762306a36Sopenharmony_ci encode_op_hdr(xdr, OP_GETFH, decode_getfh_maxsz, hdr); 129862306a36Sopenharmony_ci} 129962306a36Sopenharmony_ci 130062306a36Sopenharmony_cistatic void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) 130162306a36Sopenharmony_ci{ 130262306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LINK, decode_link_maxsz, hdr); 130362306a36Sopenharmony_ci encode_string(xdr, name->len, name->name); 130462306a36Sopenharmony_ci} 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_cistatic inline int nfs4_lock_type(struct file_lock *fl, int block) 130762306a36Sopenharmony_ci{ 130862306a36Sopenharmony_ci if (fl->fl_type == F_RDLCK) 130962306a36Sopenharmony_ci return block ? NFS4_READW_LT : NFS4_READ_LT; 131062306a36Sopenharmony_ci return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT; 131162306a36Sopenharmony_ci} 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_cistatic inline uint64_t nfs4_lock_length(struct file_lock *fl) 131462306a36Sopenharmony_ci{ 131562306a36Sopenharmony_ci if (fl->fl_end == OFFSET_MAX) 131662306a36Sopenharmony_ci return ~(uint64_t)0; 131762306a36Sopenharmony_ci return fl->fl_end - fl->fl_start + 1; 131862306a36Sopenharmony_ci} 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_cistatic void encode_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner) 132162306a36Sopenharmony_ci{ 132262306a36Sopenharmony_ci __be32 *p; 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_ci p = reserve_space(xdr, 32); 132562306a36Sopenharmony_ci p = xdr_encode_hyper(p, lowner->clientid); 132662306a36Sopenharmony_ci *p++ = cpu_to_be32(20); 132762306a36Sopenharmony_ci p = xdr_encode_opaque_fixed(p, "lock id:", 8); 132862306a36Sopenharmony_ci *p++ = cpu_to_be32(lowner->s_dev); 132962306a36Sopenharmony_ci xdr_encode_hyper(p, lowner->id); 133062306a36Sopenharmony_ci} 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_ci/* 133362306a36Sopenharmony_ci * opcode,type,reclaim,offset,length,new_lock_owner = 32 133462306a36Sopenharmony_ci * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40 133562306a36Sopenharmony_ci */ 133662306a36Sopenharmony_cistatic void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args, struct compound_hdr *hdr) 133762306a36Sopenharmony_ci{ 133862306a36Sopenharmony_ci __be32 *p; 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LOCK, decode_lock_maxsz, hdr); 134162306a36Sopenharmony_ci p = reserve_space(xdr, 28); 134262306a36Sopenharmony_ci *p++ = cpu_to_be32(nfs4_lock_type(args->fl, args->block)); 134362306a36Sopenharmony_ci *p++ = cpu_to_be32(args->reclaim); 134462306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->fl->fl_start); 134562306a36Sopenharmony_ci p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); 134662306a36Sopenharmony_ci *p = cpu_to_be32(args->new_lock_owner); 134762306a36Sopenharmony_ci if (args->new_lock_owner){ 134862306a36Sopenharmony_ci encode_nfs4_seqid(xdr, args->open_seqid); 134962306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->open_stateid); 135062306a36Sopenharmony_ci encode_nfs4_seqid(xdr, args->lock_seqid); 135162306a36Sopenharmony_ci encode_lockowner(xdr, &args->lock_owner); 135262306a36Sopenharmony_ci } 135362306a36Sopenharmony_ci else { 135462306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->lock_stateid); 135562306a36Sopenharmony_ci encode_nfs4_seqid(xdr, args->lock_seqid); 135662306a36Sopenharmony_ci } 135762306a36Sopenharmony_ci} 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_cistatic void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr) 136062306a36Sopenharmony_ci{ 136162306a36Sopenharmony_ci __be32 *p; 136262306a36Sopenharmony_ci 136362306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LOCKT, decode_lockt_maxsz, hdr); 136462306a36Sopenharmony_ci p = reserve_space(xdr, 20); 136562306a36Sopenharmony_ci *p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0)); 136662306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->fl->fl_start); 136762306a36Sopenharmony_ci p = xdr_encode_hyper(p, nfs4_lock_length(args->fl)); 136862306a36Sopenharmony_ci encode_lockowner(xdr, &args->lock_owner); 136962306a36Sopenharmony_ci} 137062306a36Sopenharmony_ci 137162306a36Sopenharmony_cistatic void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr) 137262306a36Sopenharmony_ci{ 137362306a36Sopenharmony_ci __be32 *p; 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LOCKU, decode_locku_maxsz, hdr); 137662306a36Sopenharmony_ci encode_uint32(xdr, nfs4_lock_type(args->fl, 0)); 137762306a36Sopenharmony_ci encode_nfs4_seqid(xdr, args->seqid); 137862306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->stateid); 137962306a36Sopenharmony_ci p = reserve_space(xdr, 16); 138062306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->fl->fl_start); 138162306a36Sopenharmony_ci xdr_encode_hyper(p, nfs4_lock_length(args->fl)); 138262306a36Sopenharmony_ci} 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_cistatic void encode_release_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner, struct compound_hdr *hdr) 138562306a36Sopenharmony_ci{ 138662306a36Sopenharmony_ci encode_op_hdr(xdr, OP_RELEASE_LOCKOWNER, decode_release_lockowner_maxsz, hdr); 138762306a36Sopenharmony_ci encode_lockowner(xdr, lowner); 138862306a36Sopenharmony_ci} 138962306a36Sopenharmony_ci 139062306a36Sopenharmony_cistatic void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) 139162306a36Sopenharmony_ci{ 139262306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LOOKUP, decode_lookup_maxsz, hdr); 139362306a36Sopenharmony_ci encode_string(xdr, name->len, name->name); 139462306a36Sopenharmony_ci} 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_cistatic void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr) 139762306a36Sopenharmony_ci{ 139862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr); 139962306a36Sopenharmony_ci} 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_cistatic void encode_share_access(struct xdr_stream *xdr, u32 share_access) 140262306a36Sopenharmony_ci{ 140362306a36Sopenharmony_ci __be32 *p; 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci p = reserve_space(xdr, 8); 140662306a36Sopenharmony_ci *p++ = cpu_to_be32(share_access); 140762306a36Sopenharmony_ci *p = cpu_to_be32(0); /* for linux, share_deny = 0 always */ 140862306a36Sopenharmony_ci} 140962306a36Sopenharmony_ci 141062306a36Sopenharmony_cistatic inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg) 141162306a36Sopenharmony_ci{ 141262306a36Sopenharmony_ci __be32 *p; 141362306a36Sopenharmony_ci /* 141462306a36Sopenharmony_ci * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4, 141562306a36Sopenharmony_ci * owner 4 = 32 141662306a36Sopenharmony_ci */ 141762306a36Sopenharmony_ci encode_nfs4_seqid(xdr, arg->seqid); 141862306a36Sopenharmony_ci encode_share_access(xdr, arg->share_access); 141962306a36Sopenharmony_ci p = reserve_space(xdr, 36); 142062306a36Sopenharmony_ci p = xdr_encode_hyper(p, arg->clientid); 142162306a36Sopenharmony_ci *p++ = cpu_to_be32(24); 142262306a36Sopenharmony_ci p = xdr_encode_opaque_fixed(p, "open id:", 8); 142362306a36Sopenharmony_ci *p++ = cpu_to_be32(arg->server->s_dev); 142462306a36Sopenharmony_ci *p++ = cpu_to_be32(arg->id.uniquifier); 142562306a36Sopenharmony_ci xdr_encode_hyper(p, arg->id.create_time); 142662306a36Sopenharmony_ci} 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_cistatic inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) 142962306a36Sopenharmony_ci{ 143062306a36Sopenharmony_ci __be32 *p; 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci p = reserve_space(xdr, 4); 143362306a36Sopenharmony_ci switch(arg->createmode) { 143462306a36Sopenharmony_ci case NFS4_CREATE_UNCHECKED: 143562306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_CREATE_UNCHECKED); 143662306a36Sopenharmony_ci encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, 143762306a36Sopenharmony_ci arg->server, arg->server->attr_bitmask); 143862306a36Sopenharmony_ci break; 143962306a36Sopenharmony_ci case NFS4_CREATE_GUARDED: 144062306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_CREATE_GUARDED); 144162306a36Sopenharmony_ci encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, 144262306a36Sopenharmony_ci arg->server, arg->server->attr_bitmask); 144362306a36Sopenharmony_ci break; 144462306a36Sopenharmony_ci case NFS4_CREATE_EXCLUSIVE: 144562306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE); 144662306a36Sopenharmony_ci encode_nfs4_verifier(xdr, &arg->u.verifier); 144762306a36Sopenharmony_ci break; 144862306a36Sopenharmony_ci case NFS4_CREATE_EXCLUSIVE4_1: 144962306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1); 145062306a36Sopenharmony_ci encode_nfs4_verifier(xdr, &arg->u.verifier); 145162306a36Sopenharmony_ci encode_attrs(xdr, arg->u.attrs, arg->label, &arg->umask, 145262306a36Sopenharmony_ci arg->server, arg->server->exclcreat_bitmask); 145362306a36Sopenharmony_ci } 145462306a36Sopenharmony_ci} 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_cistatic void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg) 145762306a36Sopenharmony_ci{ 145862306a36Sopenharmony_ci __be32 *p; 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci p = reserve_space(xdr, 4); 146162306a36Sopenharmony_ci switch (arg->open_flags & O_CREAT) { 146262306a36Sopenharmony_ci case 0: 146362306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_NOCREATE); 146462306a36Sopenharmony_ci break; 146562306a36Sopenharmony_ci default: 146662306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_CREATE); 146762306a36Sopenharmony_ci encode_createmode(xdr, arg); 146862306a36Sopenharmony_ci } 146962306a36Sopenharmony_ci} 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_cistatic inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delegation_type) 147262306a36Sopenharmony_ci{ 147362306a36Sopenharmony_ci __be32 *p; 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci p = reserve_space(xdr, 4); 147662306a36Sopenharmony_ci switch (delegation_type) { 147762306a36Sopenharmony_ci case 0: 147862306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_DELEGATE_NONE); 147962306a36Sopenharmony_ci break; 148062306a36Sopenharmony_ci case FMODE_READ: 148162306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_DELEGATE_READ); 148262306a36Sopenharmony_ci break; 148362306a36Sopenharmony_ci case FMODE_WRITE|FMODE_READ: 148462306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_DELEGATE_WRITE); 148562306a36Sopenharmony_ci break; 148662306a36Sopenharmony_ci default: 148762306a36Sopenharmony_ci BUG(); 148862306a36Sopenharmony_ci } 148962306a36Sopenharmony_ci} 149062306a36Sopenharmony_ci 149162306a36Sopenharmony_cistatic inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name) 149262306a36Sopenharmony_ci{ 149362306a36Sopenharmony_ci __be32 *p; 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci p = reserve_space(xdr, 4); 149662306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_CLAIM_NULL); 149762306a36Sopenharmony_ci encode_string(xdr, name->len, name->name); 149862306a36Sopenharmony_ci} 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_cistatic inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type) 150162306a36Sopenharmony_ci{ 150262306a36Sopenharmony_ci __be32 *p; 150362306a36Sopenharmony_ci 150462306a36Sopenharmony_ci p = reserve_space(xdr, 4); 150562306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_CLAIM_PREVIOUS); 150662306a36Sopenharmony_ci encode_delegation_type(xdr, type); 150762306a36Sopenharmony_ci} 150862306a36Sopenharmony_ci 150962306a36Sopenharmony_cistatic inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid) 151062306a36Sopenharmony_ci{ 151162306a36Sopenharmony_ci __be32 *p; 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci p = reserve_space(xdr, 4); 151462306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_CLAIM_DELEGATE_CUR); 151562306a36Sopenharmony_ci encode_nfs4_stateid(xdr, stateid); 151662306a36Sopenharmony_ci encode_string(xdr, name->len, name->name); 151762306a36Sopenharmony_ci} 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_cistatic inline void encode_claim_fh(struct xdr_stream *xdr) 152062306a36Sopenharmony_ci{ 152162306a36Sopenharmony_ci __be32 *p; 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci p = reserve_space(xdr, 4); 152462306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_CLAIM_FH); 152562306a36Sopenharmony_ci} 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_cistatic inline void encode_claim_delegate_cur_fh(struct xdr_stream *xdr, const nfs4_stateid *stateid) 152862306a36Sopenharmony_ci{ 152962306a36Sopenharmony_ci __be32 *p; 153062306a36Sopenharmony_ci 153162306a36Sopenharmony_ci p = reserve_space(xdr, 4); 153262306a36Sopenharmony_ci *p = cpu_to_be32(NFS4_OPEN_CLAIM_DELEG_CUR_FH); 153362306a36Sopenharmony_ci encode_nfs4_stateid(xdr, stateid); 153462306a36Sopenharmony_ci} 153562306a36Sopenharmony_ci 153662306a36Sopenharmony_cistatic void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr) 153762306a36Sopenharmony_ci{ 153862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_OPEN, decode_open_maxsz, hdr); 153962306a36Sopenharmony_ci encode_openhdr(xdr, arg); 154062306a36Sopenharmony_ci encode_opentype(xdr, arg); 154162306a36Sopenharmony_ci switch (arg->claim) { 154262306a36Sopenharmony_ci case NFS4_OPEN_CLAIM_NULL: 154362306a36Sopenharmony_ci encode_claim_null(xdr, arg->name); 154462306a36Sopenharmony_ci break; 154562306a36Sopenharmony_ci case NFS4_OPEN_CLAIM_PREVIOUS: 154662306a36Sopenharmony_ci encode_claim_previous(xdr, arg->u.delegation_type); 154762306a36Sopenharmony_ci break; 154862306a36Sopenharmony_ci case NFS4_OPEN_CLAIM_DELEGATE_CUR: 154962306a36Sopenharmony_ci encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation); 155062306a36Sopenharmony_ci break; 155162306a36Sopenharmony_ci case NFS4_OPEN_CLAIM_FH: 155262306a36Sopenharmony_ci encode_claim_fh(xdr); 155362306a36Sopenharmony_ci break; 155462306a36Sopenharmony_ci case NFS4_OPEN_CLAIM_DELEG_CUR_FH: 155562306a36Sopenharmony_ci encode_claim_delegate_cur_fh(xdr, &arg->u.delegation); 155662306a36Sopenharmony_ci break; 155762306a36Sopenharmony_ci default: 155862306a36Sopenharmony_ci BUG(); 155962306a36Sopenharmony_ci } 156062306a36Sopenharmony_ci} 156162306a36Sopenharmony_ci 156262306a36Sopenharmony_cistatic void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr) 156362306a36Sopenharmony_ci{ 156462306a36Sopenharmony_ci encode_op_hdr(xdr, OP_OPEN_CONFIRM, decode_open_confirm_maxsz, hdr); 156562306a36Sopenharmony_ci encode_nfs4_stateid(xdr, arg->stateid); 156662306a36Sopenharmony_ci encode_nfs4_seqid(xdr, arg->seqid); 156762306a36Sopenharmony_ci} 156862306a36Sopenharmony_ci 156962306a36Sopenharmony_cistatic void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr) 157062306a36Sopenharmony_ci{ 157162306a36Sopenharmony_ci encode_op_hdr(xdr, OP_OPEN_DOWNGRADE, decode_open_downgrade_maxsz, hdr); 157262306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &arg->stateid); 157362306a36Sopenharmony_ci encode_nfs4_seqid(xdr, arg->seqid); 157462306a36Sopenharmony_ci encode_share_access(xdr, arg->share_access); 157562306a36Sopenharmony_ci} 157662306a36Sopenharmony_ci 157762306a36Sopenharmony_cistatic void 157862306a36Sopenharmony_ciencode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hdr *hdr) 157962306a36Sopenharmony_ci{ 158062306a36Sopenharmony_ci encode_op_hdr(xdr, OP_PUTFH, decode_putfh_maxsz, hdr); 158162306a36Sopenharmony_ci encode_string(xdr, fh->size, fh->data); 158262306a36Sopenharmony_ci} 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_cistatic void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) 158562306a36Sopenharmony_ci{ 158662306a36Sopenharmony_ci encode_op_hdr(xdr, OP_PUTROOTFH, decode_putrootfh_maxsz, hdr); 158762306a36Sopenharmony_ci} 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_cistatic void encode_read(struct xdr_stream *xdr, const struct nfs_pgio_args *args, 159062306a36Sopenharmony_ci struct compound_hdr *hdr) 159162306a36Sopenharmony_ci{ 159262306a36Sopenharmony_ci __be32 *p; 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci encode_op_hdr(xdr, OP_READ, decode_read_maxsz, hdr); 159562306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->stateid); 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci p = reserve_space(xdr, 12); 159862306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->offset); 159962306a36Sopenharmony_ci *p = cpu_to_be32(args->count); 160062306a36Sopenharmony_ci} 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_cistatic void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr) 160362306a36Sopenharmony_ci{ 160462306a36Sopenharmony_ci uint32_t attrs[3] = { 160562306a36Sopenharmony_ci FATTR4_WORD0_RDATTR_ERROR, 160662306a36Sopenharmony_ci FATTR4_WORD1_MOUNTED_ON_FILEID, 160762306a36Sopenharmony_ci }; 160862306a36Sopenharmony_ci uint32_t dircount = readdir->count; 160962306a36Sopenharmony_ci uint32_t maxcount = readdir->count; 161062306a36Sopenharmony_ci __be32 *p, verf[2]; 161162306a36Sopenharmony_ci uint32_t attrlen = 0; 161262306a36Sopenharmony_ci unsigned int i; 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci if (readdir->plus) { 161562306a36Sopenharmony_ci attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE| 161662306a36Sopenharmony_ci FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID; 161762306a36Sopenharmony_ci attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER| 161862306a36Sopenharmony_ci FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV| 161962306a36Sopenharmony_ci FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS| 162062306a36Sopenharmony_ci FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY; 162162306a36Sopenharmony_ci attrs[2] |= FATTR4_WORD2_SECURITY_LABEL; 162262306a36Sopenharmony_ci } 162362306a36Sopenharmony_ci /* Use mounted_on_fileid only if the server supports it */ 162462306a36Sopenharmony_ci if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) 162562306a36Sopenharmony_ci attrs[0] |= FATTR4_WORD0_FILEID; 162662306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(attrs); i++) { 162762306a36Sopenharmony_ci attrs[i] &= readdir->bitmask[i]; 162862306a36Sopenharmony_ci if (attrs[i] != 0) 162962306a36Sopenharmony_ci attrlen = i+1; 163062306a36Sopenharmony_ci } 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ci encode_op_hdr(xdr, OP_READDIR, decode_readdir_maxsz, hdr); 163362306a36Sopenharmony_ci encode_uint64(xdr, readdir->cookie); 163462306a36Sopenharmony_ci encode_nfs4_verifier(xdr, &readdir->verifier); 163562306a36Sopenharmony_ci p = reserve_space(xdr, 12 + (attrlen << 2)); 163662306a36Sopenharmony_ci *p++ = cpu_to_be32(dircount); 163762306a36Sopenharmony_ci *p++ = cpu_to_be32(maxcount); 163862306a36Sopenharmony_ci *p++ = cpu_to_be32(attrlen); 163962306a36Sopenharmony_ci for (i = 0; i < attrlen; i++) 164062306a36Sopenharmony_ci *p++ = cpu_to_be32(attrs[i]); 164162306a36Sopenharmony_ci memcpy(verf, readdir->verifier.data, sizeof(verf)); 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci dprintk("%s: cookie = %llu, verifier = %08x:%08x, bitmap = %08x:%08x:%08x\n", 164462306a36Sopenharmony_ci __func__, 164562306a36Sopenharmony_ci (unsigned long long)readdir->cookie, 164662306a36Sopenharmony_ci verf[0], verf[1], 164762306a36Sopenharmony_ci attrs[0] & readdir->bitmask[0], 164862306a36Sopenharmony_ci attrs[1] & readdir->bitmask[1], 164962306a36Sopenharmony_ci attrs[2] & readdir->bitmask[2]); 165062306a36Sopenharmony_ci} 165162306a36Sopenharmony_ci 165262306a36Sopenharmony_cistatic void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr) 165362306a36Sopenharmony_ci{ 165462306a36Sopenharmony_ci encode_op_hdr(xdr, OP_READLINK, decode_readlink_maxsz, hdr); 165562306a36Sopenharmony_ci} 165662306a36Sopenharmony_ci 165762306a36Sopenharmony_cistatic void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) 165862306a36Sopenharmony_ci{ 165962306a36Sopenharmony_ci encode_op_hdr(xdr, OP_REMOVE, decode_remove_maxsz, hdr); 166062306a36Sopenharmony_ci encode_string(xdr, name->len, name->name); 166162306a36Sopenharmony_ci} 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_cistatic void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr) 166462306a36Sopenharmony_ci{ 166562306a36Sopenharmony_ci encode_op_hdr(xdr, OP_RENAME, decode_rename_maxsz, hdr); 166662306a36Sopenharmony_ci encode_string(xdr, oldname->len, oldname->name); 166762306a36Sopenharmony_ci encode_string(xdr, newname->len, newname->name); 166862306a36Sopenharmony_ci} 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_cistatic void encode_renew(struct xdr_stream *xdr, clientid4 clid, 167162306a36Sopenharmony_ci struct compound_hdr *hdr) 167262306a36Sopenharmony_ci{ 167362306a36Sopenharmony_ci encode_op_hdr(xdr, OP_RENEW, decode_renew_maxsz, hdr); 167462306a36Sopenharmony_ci encode_uint64(xdr, clid); 167562306a36Sopenharmony_ci} 167662306a36Sopenharmony_ci 167762306a36Sopenharmony_cistatic void 167862306a36Sopenharmony_ciencode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) 167962306a36Sopenharmony_ci{ 168062306a36Sopenharmony_ci encode_op_hdr(xdr, OP_RESTOREFH, decode_restorefh_maxsz, hdr); 168162306a36Sopenharmony_ci} 168262306a36Sopenharmony_ci 168362306a36Sopenharmony_cistatic void nfs4_acltype_to_bitmap(enum nfs4_acl_type type, __u32 bitmap[2]) 168462306a36Sopenharmony_ci{ 168562306a36Sopenharmony_ci switch (type) { 168662306a36Sopenharmony_ci default: 168762306a36Sopenharmony_ci bitmap[0] = FATTR4_WORD0_ACL; 168862306a36Sopenharmony_ci bitmap[1] = 0; 168962306a36Sopenharmony_ci break; 169062306a36Sopenharmony_ci case NFS4ACL_DACL: 169162306a36Sopenharmony_ci bitmap[0] = 0; 169262306a36Sopenharmony_ci bitmap[1] = FATTR4_WORD1_DACL; 169362306a36Sopenharmony_ci break; 169462306a36Sopenharmony_ci case NFS4ACL_SACL: 169562306a36Sopenharmony_ci bitmap[0] = 0; 169662306a36Sopenharmony_ci bitmap[1] = FATTR4_WORD1_SACL; 169762306a36Sopenharmony_ci } 169862306a36Sopenharmony_ci} 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_cistatic void encode_setacl(struct xdr_stream *xdr, 170162306a36Sopenharmony_ci const struct nfs_setaclargs *arg, 170262306a36Sopenharmony_ci struct compound_hdr *hdr) 170362306a36Sopenharmony_ci{ 170462306a36Sopenharmony_ci __u32 bitmap[2]; 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci nfs4_acltype_to_bitmap(arg->acl_type, bitmap); 170762306a36Sopenharmony_ci 170862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SETATTR, decode_setacl_maxsz, hdr); 170962306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &zero_stateid); 171062306a36Sopenharmony_ci xdr_encode_bitmap4(xdr, bitmap, ARRAY_SIZE(bitmap)); 171162306a36Sopenharmony_ci encode_uint32(xdr, arg->acl_len); 171262306a36Sopenharmony_ci xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); 171362306a36Sopenharmony_ci} 171462306a36Sopenharmony_ci 171562306a36Sopenharmony_cistatic void 171662306a36Sopenharmony_ciencode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr) 171762306a36Sopenharmony_ci{ 171862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SAVEFH, decode_savefh_maxsz, hdr); 171962306a36Sopenharmony_ci} 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_cistatic void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr) 172262306a36Sopenharmony_ci{ 172362306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SETATTR, decode_setattr_maxsz, hdr); 172462306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &arg->stateid); 172562306a36Sopenharmony_ci encode_attrs(xdr, arg->iap, arg->label, NULL, server, 172662306a36Sopenharmony_ci server->attr_bitmask); 172762306a36Sopenharmony_ci} 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_cistatic void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr) 173062306a36Sopenharmony_ci{ 173162306a36Sopenharmony_ci __be32 *p; 173262306a36Sopenharmony_ci 173362306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SETCLIENTID, decode_setclientid_maxsz, hdr); 173462306a36Sopenharmony_ci encode_nfs4_verifier(xdr, setclientid->sc_verifier); 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci encode_string(xdr, strlen(setclientid->sc_clnt->cl_owner_id), 173762306a36Sopenharmony_ci setclientid->sc_clnt->cl_owner_id); 173862306a36Sopenharmony_ci p = reserve_space(xdr, 4); 173962306a36Sopenharmony_ci *p = cpu_to_be32(setclientid->sc_prog); 174062306a36Sopenharmony_ci encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid); 174162306a36Sopenharmony_ci encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr); 174262306a36Sopenharmony_ci p = reserve_space(xdr, 4); 174362306a36Sopenharmony_ci *p = cpu_to_be32(setclientid->sc_clnt->cl_cb_ident); 174462306a36Sopenharmony_ci} 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_cistatic void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr) 174762306a36Sopenharmony_ci{ 174862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SETCLIENTID_CONFIRM, 174962306a36Sopenharmony_ci decode_setclientid_confirm_maxsz, hdr); 175062306a36Sopenharmony_ci encode_uint64(xdr, arg->clientid); 175162306a36Sopenharmony_ci encode_nfs4_verifier(xdr, &arg->confirm); 175262306a36Sopenharmony_ci} 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_cistatic void encode_write(struct xdr_stream *xdr, const struct nfs_pgio_args *args, 175562306a36Sopenharmony_ci struct compound_hdr *hdr) 175662306a36Sopenharmony_ci{ 175762306a36Sopenharmony_ci __be32 *p; 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci encode_op_hdr(xdr, OP_WRITE, decode_write_maxsz, hdr); 176062306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->stateid); 176162306a36Sopenharmony_ci 176262306a36Sopenharmony_ci p = reserve_space(xdr, 16); 176362306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->offset); 176462306a36Sopenharmony_ci *p++ = cpu_to_be32(args->stable); 176562306a36Sopenharmony_ci *p = cpu_to_be32(args->count); 176662306a36Sopenharmony_ci 176762306a36Sopenharmony_ci xdr_write_pages(xdr, args->pages, args->pgbase, args->count); 176862306a36Sopenharmony_ci} 176962306a36Sopenharmony_ci 177062306a36Sopenharmony_cistatic void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr) 177162306a36Sopenharmony_ci{ 177262306a36Sopenharmony_ci encode_op_hdr(xdr, OP_DELEGRETURN, decode_delegreturn_maxsz, hdr); 177362306a36Sopenharmony_ci encode_nfs4_stateid(xdr, stateid); 177462306a36Sopenharmony_ci} 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_cistatic void encode_secinfo(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr) 177762306a36Sopenharmony_ci{ 177862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SECINFO, decode_secinfo_maxsz, hdr); 177962306a36Sopenharmony_ci encode_string(xdr, name->len, name->name); 178062306a36Sopenharmony_ci} 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 178362306a36Sopenharmony_ci/* NFSv4.1 operations */ 178462306a36Sopenharmony_cistatic void encode_bind_conn_to_session(struct xdr_stream *xdr, 178562306a36Sopenharmony_ci const struct nfs41_bind_conn_to_session_args *args, 178662306a36Sopenharmony_ci struct compound_hdr *hdr) 178762306a36Sopenharmony_ci{ 178862306a36Sopenharmony_ci __be32 *p; 178962306a36Sopenharmony_ci 179062306a36Sopenharmony_ci encode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION, 179162306a36Sopenharmony_ci decode_bind_conn_to_session_maxsz, hdr); 179262306a36Sopenharmony_ci encode_opaque_fixed(xdr, args->sessionid.data, NFS4_MAX_SESSIONID_LEN); 179362306a36Sopenharmony_ci p = xdr_reserve_space(xdr, 8); 179462306a36Sopenharmony_ci *p++ = cpu_to_be32(args->dir); 179562306a36Sopenharmony_ci *p = (args->use_conn_in_rdma_mode) ? cpu_to_be32(1) : cpu_to_be32(0); 179662306a36Sopenharmony_ci} 179762306a36Sopenharmony_ci 179862306a36Sopenharmony_cistatic void encode_op_map(struct xdr_stream *xdr, const struct nfs4_op_map *op_map) 179962306a36Sopenharmony_ci{ 180062306a36Sopenharmony_ci unsigned int i; 180162306a36Sopenharmony_ci encode_uint32(xdr, NFS4_OP_MAP_NUM_WORDS); 180262306a36Sopenharmony_ci for (i = 0; i < NFS4_OP_MAP_NUM_WORDS; i++) 180362306a36Sopenharmony_ci encode_uint32(xdr, op_map->u.words[i]); 180462306a36Sopenharmony_ci} 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_cistatic void encode_exchange_id(struct xdr_stream *xdr, 180762306a36Sopenharmony_ci const struct nfs41_exchange_id_args *args, 180862306a36Sopenharmony_ci struct compound_hdr *hdr) 180962306a36Sopenharmony_ci{ 181062306a36Sopenharmony_ci __be32 *p; 181162306a36Sopenharmony_ci char impl_name[IMPL_NAME_LIMIT]; 181262306a36Sopenharmony_ci int len = 0; 181362306a36Sopenharmony_ci 181462306a36Sopenharmony_ci encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr); 181562306a36Sopenharmony_ci encode_nfs4_verifier(xdr, &args->verifier); 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci encode_string(xdr, strlen(args->client->cl_owner_id), 181862306a36Sopenharmony_ci args->client->cl_owner_id); 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_ci encode_uint32(xdr, args->flags); 182162306a36Sopenharmony_ci encode_uint32(xdr, args->state_protect.how); 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci switch (args->state_protect.how) { 182462306a36Sopenharmony_ci case SP4_NONE: 182562306a36Sopenharmony_ci break; 182662306a36Sopenharmony_ci case SP4_MACH_CRED: 182762306a36Sopenharmony_ci encode_op_map(xdr, &args->state_protect.enforce); 182862306a36Sopenharmony_ci encode_op_map(xdr, &args->state_protect.allow); 182962306a36Sopenharmony_ci break; 183062306a36Sopenharmony_ci default: 183162306a36Sopenharmony_ci WARN_ON_ONCE(1); 183262306a36Sopenharmony_ci break; 183362306a36Sopenharmony_ci } 183462306a36Sopenharmony_ci 183562306a36Sopenharmony_ci if (send_implementation_id && 183662306a36Sopenharmony_ci sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 && 183762306a36Sopenharmony_ci sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) 183862306a36Sopenharmony_ci <= sizeof(impl_name) + 1) 183962306a36Sopenharmony_ci len = snprintf(impl_name, sizeof(impl_name), "%s %s %s %s", 184062306a36Sopenharmony_ci utsname()->sysname, utsname()->release, 184162306a36Sopenharmony_ci utsname()->version, utsname()->machine); 184262306a36Sopenharmony_ci 184362306a36Sopenharmony_ci if (len > 0) { 184462306a36Sopenharmony_ci encode_uint32(xdr, 1); /* implementation id array length=1 */ 184562306a36Sopenharmony_ci 184662306a36Sopenharmony_ci encode_string(xdr, 184762306a36Sopenharmony_ci sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1, 184862306a36Sopenharmony_ci CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN); 184962306a36Sopenharmony_ci encode_string(xdr, len, impl_name); 185062306a36Sopenharmony_ci /* just send zeros for nii_date - the date is in nii_name */ 185162306a36Sopenharmony_ci p = reserve_space(xdr, 12); 185262306a36Sopenharmony_ci p = xdr_encode_hyper(p, 0); 185362306a36Sopenharmony_ci *p = cpu_to_be32(0); 185462306a36Sopenharmony_ci } else 185562306a36Sopenharmony_ci encode_uint32(xdr, 0); /* implementation id array length=0 */ 185662306a36Sopenharmony_ci} 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_cistatic void encode_create_session(struct xdr_stream *xdr, 185962306a36Sopenharmony_ci const struct nfs41_create_session_args *args, 186062306a36Sopenharmony_ci struct compound_hdr *hdr) 186162306a36Sopenharmony_ci{ 186262306a36Sopenharmony_ci __be32 *p; 186362306a36Sopenharmony_ci struct nfs_client *clp = args->client; 186462306a36Sopenharmony_ci struct rpc_clnt *clnt = clp->cl_rpcclient; 186562306a36Sopenharmony_ci struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id); 186662306a36Sopenharmony_ci u32 max_resp_sz_cached; 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_ci /* 186962306a36Sopenharmony_ci * Assumes OPEN is the biggest non-idempotent compound. 187062306a36Sopenharmony_ci * 2 is the verifier. 187162306a36Sopenharmony_ci */ 187262306a36Sopenharmony_ci max_resp_sz_cached = (NFS4_dec_open_sz + RPC_REPHDRSIZE + 2) 187362306a36Sopenharmony_ci * XDR_UNIT + RPC_MAX_AUTH_SIZE; 187462306a36Sopenharmony_ci 187562306a36Sopenharmony_ci encode_op_hdr(xdr, OP_CREATE_SESSION, decode_create_session_maxsz, hdr); 187662306a36Sopenharmony_ci p = reserve_space(xdr, 16 + 2*28 + 20 + clnt->cl_nodelen + 12); 187762306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->clientid); 187862306a36Sopenharmony_ci *p++ = cpu_to_be32(args->seqid); /*Sequence id */ 187962306a36Sopenharmony_ci *p++ = cpu_to_be32(args->flags); /*flags */ 188062306a36Sopenharmony_ci 188162306a36Sopenharmony_ci /* Fore Channel */ 188262306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* header padding size */ 188362306a36Sopenharmony_ci *p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz); /* max req size */ 188462306a36Sopenharmony_ci *p++ = cpu_to_be32(args->fc_attrs.max_resp_sz); /* max resp size */ 188562306a36Sopenharmony_ci *p++ = cpu_to_be32(max_resp_sz_cached); /* Max resp sz cached */ 188662306a36Sopenharmony_ci *p++ = cpu_to_be32(args->fc_attrs.max_ops); /* max operations */ 188762306a36Sopenharmony_ci *p++ = cpu_to_be32(args->fc_attrs.max_reqs); /* max requests */ 188862306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ 188962306a36Sopenharmony_ci 189062306a36Sopenharmony_ci /* Back Channel */ 189162306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* header padding size */ 189262306a36Sopenharmony_ci *p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz); /* max req size */ 189362306a36Sopenharmony_ci *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz); /* max resp size */ 189462306a36Sopenharmony_ci *p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached); /* Max resp sz cached */ 189562306a36Sopenharmony_ci *p++ = cpu_to_be32(args->bc_attrs.max_ops); /* max operations */ 189662306a36Sopenharmony_ci *p++ = cpu_to_be32(args->bc_attrs.max_reqs); /* max requests */ 189762306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* rdmachannel_attrs */ 189862306a36Sopenharmony_ci 189962306a36Sopenharmony_ci *p++ = cpu_to_be32(args->cb_program); /* cb_program */ 190062306a36Sopenharmony_ci *p++ = cpu_to_be32(1); 190162306a36Sopenharmony_ci *p++ = cpu_to_be32(RPC_AUTH_UNIX); /* auth_sys */ 190262306a36Sopenharmony_ci 190362306a36Sopenharmony_ci /* authsys_parms rfc1831 */ 190462306a36Sopenharmony_ci *p++ = cpu_to_be32(ktime_to_ns(nn->boot_time)); /* stamp */ 190562306a36Sopenharmony_ci p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen); 190662306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* UID */ 190762306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* GID */ 190862306a36Sopenharmony_ci *p = cpu_to_be32(0); /* No more gids */ 190962306a36Sopenharmony_ci} 191062306a36Sopenharmony_ci 191162306a36Sopenharmony_cistatic void encode_destroy_session(struct xdr_stream *xdr, 191262306a36Sopenharmony_ci const struct nfs4_session *session, 191362306a36Sopenharmony_ci struct compound_hdr *hdr) 191462306a36Sopenharmony_ci{ 191562306a36Sopenharmony_ci encode_op_hdr(xdr, OP_DESTROY_SESSION, decode_destroy_session_maxsz, hdr); 191662306a36Sopenharmony_ci encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN); 191762306a36Sopenharmony_ci} 191862306a36Sopenharmony_ci 191962306a36Sopenharmony_cistatic void encode_destroy_clientid(struct xdr_stream *xdr, 192062306a36Sopenharmony_ci uint64_t clientid, 192162306a36Sopenharmony_ci struct compound_hdr *hdr) 192262306a36Sopenharmony_ci{ 192362306a36Sopenharmony_ci encode_op_hdr(xdr, OP_DESTROY_CLIENTID, decode_destroy_clientid_maxsz, hdr); 192462306a36Sopenharmony_ci encode_uint64(xdr, clientid); 192562306a36Sopenharmony_ci} 192662306a36Sopenharmony_ci 192762306a36Sopenharmony_cistatic void encode_reclaim_complete(struct xdr_stream *xdr, 192862306a36Sopenharmony_ci const struct nfs41_reclaim_complete_args *args, 192962306a36Sopenharmony_ci struct compound_hdr *hdr) 193062306a36Sopenharmony_ci{ 193162306a36Sopenharmony_ci encode_op_hdr(xdr, OP_RECLAIM_COMPLETE, decode_reclaim_complete_maxsz, hdr); 193262306a36Sopenharmony_ci encode_uint32(xdr, args->one_fs); 193362306a36Sopenharmony_ci} 193462306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_cistatic void encode_sequence(struct xdr_stream *xdr, 193762306a36Sopenharmony_ci const struct nfs4_sequence_args *args, 193862306a36Sopenharmony_ci struct compound_hdr *hdr) 193962306a36Sopenharmony_ci{ 194062306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 194162306a36Sopenharmony_ci struct nfs4_session *session; 194262306a36Sopenharmony_ci struct nfs4_slot_table *tp; 194362306a36Sopenharmony_ci struct nfs4_slot *slot = args->sa_slot; 194462306a36Sopenharmony_ci __be32 *p; 194562306a36Sopenharmony_ci 194662306a36Sopenharmony_ci tp = slot->table; 194762306a36Sopenharmony_ci session = tp->session; 194862306a36Sopenharmony_ci if (!session) 194962306a36Sopenharmony_ci return; 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SEQUENCE, decode_sequence_maxsz, hdr); 195262306a36Sopenharmony_ci 195362306a36Sopenharmony_ci /* 195462306a36Sopenharmony_ci * Sessionid + seqid + slotid + max slotid + cache_this 195562306a36Sopenharmony_ci */ 195662306a36Sopenharmony_ci dprintk("%s: sessionid=%u:%u:%u:%u seqid=%d slotid=%d " 195762306a36Sopenharmony_ci "max_slotid=%d cache_this=%d\n", 195862306a36Sopenharmony_ci __func__, 195962306a36Sopenharmony_ci ((u32 *)session->sess_id.data)[0], 196062306a36Sopenharmony_ci ((u32 *)session->sess_id.data)[1], 196162306a36Sopenharmony_ci ((u32 *)session->sess_id.data)[2], 196262306a36Sopenharmony_ci ((u32 *)session->sess_id.data)[3], 196362306a36Sopenharmony_ci slot->seq_nr, slot->slot_nr, 196462306a36Sopenharmony_ci tp->highest_used_slotid, args->sa_cache_this); 196562306a36Sopenharmony_ci p = reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 16); 196662306a36Sopenharmony_ci p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN); 196762306a36Sopenharmony_ci *p++ = cpu_to_be32(slot->seq_nr); 196862306a36Sopenharmony_ci *p++ = cpu_to_be32(slot->slot_nr); 196962306a36Sopenharmony_ci *p++ = cpu_to_be32(tp->highest_used_slotid); 197062306a36Sopenharmony_ci *p = cpu_to_be32(args->sa_cache_this); 197162306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 197262306a36Sopenharmony_ci} 197362306a36Sopenharmony_ci 197462306a36Sopenharmony_ci#ifdef CONFIG_NFS_V4_1 197562306a36Sopenharmony_cistatic void 197662306a36Sopenharmony_ciencode_getdeviceinfo(struct xdr_stream *xdr, 197762306a36Sopenharmony_ci const struct nfs4_getdeviceinfo_args *args, 197862306a36Sopenharmony_ci struct compound_hdr *hdr) 197962306a36Sopenharmony_ci{ 198062306a36Sopenharmony_ci __be32 *p; 198162306a36Sopenharmony_ci 198262306a36Sopenharmony_ci encode_op_hdr(xdr, OP_GETDEVICEINFO, decode_getdeviceinfo_maxsz, hdr); 198362306a36Sopenharmony_ci p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 4 + 4); 198462306a36Sopenharmony_ci p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data, 198562306a36Sopenharmony_ci NFS4_DEVICEID4_SIZE); 198662306a36Sopenharmony_ci *p++ = cpu_to_be32(args->pdev->layout_type); 198762306a36Sopenharmony_ci *p++ = cpu_to_be32(args->pdev->maxcount); /* gdia_maxcount */ 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci p = reserve_space(xdr, 4 + 4); 199062306a36Sopenharmony_ci *p++ = cpu_to_be32(1); /* bitmap length */ 199162306a36Sopenharmony_ci *p++ = cpu_to_be32(args->notify_types); 199262306a36Sopenharmony_ci} 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_cistatic void 199562306a36Sopenharmony_ciencode_layoutget(struct xdr_stream *xdr, 199662306a36Sopenharmony_ci const struct nfs4_layoutget_args *args, 199762306a36Sopenharmony_ci struct compound_hdr *hdr) 199862306a36Sopenharmony_ci{ 199962306a36Sopenharmony_ci __be32 *p; 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LAYOUTGET, decode_layoutget_maxsz, hdr); 200262306a36Sopenharmony_ci p = reserve_space(xdr, 36); 200362306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* Signal layout available */ 200462306a36Sopenharmony_ci *p++ = cpu_to_be32(args->type); 200562306a36Sopenharmony_ci *p++ = cpu_to_be32(args->range.iomode); 200662306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->range.offset); 200762306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->range.length); 200862306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->minlength); 200962306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->stateid); 201062306a36Sopenharmony_ci encode_uint32(xdr, args->maxcount); 201162306a36Sopenharmony_ci 201262306a36Sopenharmony_ci dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d\n", 201362306a36Sopenharmony_ci __func__, 201462306a36Sopenharmony_ci args->type, 201562306a36Sopenharmony_ci args->range.iomode, 201662306a36Sopenharmony_ci (unsigned long)args->range.offset, 201762306a36Sopenharmony_ci (unsigned long)args->range.length, 201862306a36Sopenharmony_ci args->maxcount); 201962306a36Sopenharmony_ci} 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_cistatic int 202262306a36Sopenharmony_ciencode_layoutcommit(struct xdr_stream *xdr, 202362306a36Sopenharmony_ci struct inode *inode, 202462306a36Sopenharmony_ci const struct nfs4_layoutcommit_args *args, 202562306a36Sopenharmony_ci struct compound_hdr *hdr) 202662306a36Sopenharmony_ci{ 202762306a36Sopenharmony_ci __be32 *p; 202862306a36Sopenharmony_ci 202962306a36Sopenharmony_ci dprintk("%s: lbw: %llu type: %d\n", __func__, args->lastbytewritten, 203062306a36Sopenharmony_ci NFS_SERVER(args->inode)->pnfs_curr_ld->id); 203162306a36Sopenharmony_ci 203262306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LAYOUTCOMMIT, decode_layoutcommit_maxsz, hdr); 203362306a36Sopenharmony_ci p = reserve_space(xdr, 20); 203462306a36Sopenharmony_ci /* Only whole file layouts */ 203562306a36Sopenharmony_ci p = xdr_encode_hyper(p, 0); /* offset */ 203662306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ 203762306a36Sopenharmony_ci *p = cpu_to_be32(0); /* reclaim */ 203862306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->stateid); 203962306a36Sopenharmony_ci if (args->lastbytewritten != U64_MAX) { 204062306a36Sopenharmony_ci p = reserve_space(xdr, 20); 204162306a36Sopenharmony_ci *p++ = cpu_to_be32(1); /* newoffset = TRUE */ 204262306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->lastbytewritten); 204362306a36Sopenharmony_ci } else { 204462306a36Sopenharmony_ci p = reserve_space(xdr, 12); 204562306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* newoffset = FALSE */ 204662306a36Sopenharmony_ci } 204762306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ 204862306a36Sopenharmony_ci *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ 204962306a36Sopenharmony_ci 205062306a36Sopenharmony_ci encode_uint32(xdr, args->layoutupdate_len); 205162306a36Sopenharmony_ci if (args->layoutupdate_pages) 205262306a36Sopenharmony_ci xdr_write_pages(xdr, args->layoutupdate_pages, 0, 205362306a36Sopenharmony_ci args->layoutupdate_len); 205462306a36Sopenharmony_ci 205562306a36Sopenharmony_ci return 0; 205662306a36Sopenharmony_ci} 205762306a36Sopenharmony_ci 205862306a36Sopenharmony_cistatic void 205962306a36Sopenharmony_ciencode_layoutreturn(struct xdr_stream *xdr, 206062306a36Sopenharmony_ci const struct nfs4_layoutreturn_args *args, 206162306a36Sopenharmony_ci struct compound_hdr *hdr) 206262306a36Sopenharmony_ci{ 206362306a36Sopenharmony_ci __be32 *p; 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci encode_op_hdr(xdr, OP_LAYOUTRETURN, decode_layoutreturn_maxsz, hdr); 206662306a36Sopenharmony_ci p = reserve_space(xdr, 16); 206762306a36Sopenharmony_ci *p++ = cpu_to_be32(0); /* reclaim. always 0 for now */ 206862306a36Sopenharmony_ci *p++ = cpu_to_be32(args->layout_type); 206962306a36Sopenharmony_ci *p++ = cpu_to_be32(args->range.iomode); 207062306a36Sopenharmony_ci *p = cpu_to_be32(RETURN_FILE); 207162306a36Sopenharmony_ci p = reserve_space(xdr, 16); 207262306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->range.offset); 207362306a36Sopenharmony_ci p = xdr_encode_hyper(p, args->range.length); 207462306a36Sopenharmony_ci spin_lock(&args->inode->i_lock); 207562306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->stateid); 207662306a36Sopenharmony_ci spin_unlock(&args->inode->i_lock); 207762306a36Sopenharmony_ci if (args->ld_private->ops && args->ld_private->ops->encode) 207862306a36Sopenharmony_ci args->ld_private->ops->encode(xdr, args, args->ld_private); 207962306a36Sopenharmony_ci else 208062306a36Sopenharmony_ci encode_uint32(xdr, 0); 208162306a36Sopenharmony_ci} 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_cistatic int 208462306a36Sopenharmony_ciencode_secinfo_no_name(struct xdr_stream *xdr, 208562306a36Sopenharmony_ci const struct nfs41_secinfo_no_name_args *args, 208662306a36Sopenharmony_ci struct compound_hdr *hdr) 208762306a36Sopenharmony_ci{ 208862306a36Sopenharmony_ci encode_op_hdr(xdr, OP_SECINFO_NO_NAME, decode_secinfo_no_name_maxsz, hdr); 208962306a36Sopenharmony_ci encode_uint32(xdr, args->style); 209062306a36Sopenharmony_ci return 0; 209162306a36Sopenharmony_ci} 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_cistatic void encode_test_stateid(struct xdr_stream *xdr, 209462306a36Sopenharmony_ci const struct nfs41_test_stateid_args *args, 209562306a36Sopenharmony_ci struct compound_hdr *hdr) 209662306a36Sopenharmony_ci{ 209762306a36Sopenharmony_ci encode_op_hdr(xdr, OP_TEST_STATEID, decode_test_stateid_maxsz, hdr); 209862306a36Sopenharmony_ci encode_uint32(xdr, 1); 209962306a36Sopenharmony_ci encode_nfs4_stateid(xdr, args->stateid); 210062306a36Sopenharmony_ci} 210162306a36Sopenharmony_ci 210262306a36Sopenharmony_cistatic void encode_free_stateid(struct xdr_stream *xdr, 210362306a36Sopenharmony_ci const struct nfs41_free_stateid_args *args, 210462306a36Sopenharmony_ci struct compound_hdr *hdr) 210562306a36Sopenharmony_ci{ 210662306a36Sopenharmony_ci encode_op_hdr(xdr, OP_FREE_STATEID, decode_free_stateid_maxsz, hdr); 210762306a36Sopenharmony_ci encode_nfs4_stateid(xdr, &args->stateid); 210862306a36Sopenharmony_ci} 210962306a36Sopenharmony_ci#else 211062306a36Sopenharmony_cistatic inline void 211162306a36Sopenharmony_ciencode_layoutreturn(struct xdr_stream *xdr, 211262306a36Sopenharmony_ci const struct nfs4_layoutreturn_args *args, 211362306a36Sopenharmony_ci struct compound_hdr *hdr) 211462306a36Sopenharmony_ci{ 211562306a36Sopenharmony_ci} 211662306a36Sopenharmony_ci 211762306a36Sopenharmony_cistatic void 211862306a36Sopenharmony_ciencode_layoutget(struct xdr_stream *xdr, 211962306a36Sopenharmony_ci const struct nfs4_layoutget_args *args, 212062306a36Sopenharmony_ci struct compound_hdr *hdr) 212162306a36Sopenharmony_ci{ 212262306a36Sopenharmony_ci} 212362306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 212462306a36Sopenharmony_ci 212562306a36Sopenharmony_ci/* 212662306a36Sopenharmony_ci * END OF "GENERIC" ENCODE ROUTINES. 212762306a36Sopenharmony_ci */ 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_cistatic u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args) 213062306a36Sopenharmony_ci{ 213162306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 213262306a36Sopenharmony_ci struct nfs4_session *session = args->sa_slot->table->session; 213362306a36Sopenharmony_ci if (session) 213462306a36Sopenharmony_ci return session->clp->cl_mvops->minor_version; 213562306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 213662306a36Sopenharmony_ci return 0; 213762306a36Sopenharmony_ci} 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_ci/* 214062306a36Sopenharmony_ci * Encode an ACCESS request 214162306a36Sopenharmony_ci */ 214262306a36Sopenharmony_cistatic void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr, 214362306a36Sopenharmony_ci const void *data) 214462306a36Sopenharmony_ci{ 214562306a36Sopenharmony_ci const struct nfs4_accessargs *args = data; 214662306a36Sopenharmony_ci struct compound_hdr hdr = { 214762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 214862306a36Sopenharmony_ci }; 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 215162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 215262306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 215362306a36Sopenharmony_ci encode_access(xdr, args->access, &hdr); 215462306a36Sopenharmony_ci if (args->bitmask) 215562306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 215662306a36Sopenharmony_ci encode_nops(&hdr); 215762306a36Sopenharmony_ci} 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_ci/* 216062306a36Sopenharmony_ci * Encode LOOKUP request 216162306a36Sopenharmony_ci */ 216262306a36Sopenharmony_cistatic void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr, 216362306a36Sopenharmony_ci const void *data) 216462306a36Sopenharmony_ci{ 216562306a36Sopenharmony_ci const struct nfs4_lookup_arg *args = data; 216662306a36Sopenharmony_ci struct compound_hdr hdr = { 216762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 216862306a36Sopenharmony_ci }; 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 217162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 217262306a36Sopenharmony_ci encode_putfh(xdr, args->dir_fh, &hdr); 217362306a36Sopenharmony_ci encode_lookup(xdr, args->name, &hdr); 217462306a36Sopenharmony_ci encode_getfh(xdr, &hdr); 217562306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 217662306a36Sopenharmony_ci encode_nops(&hdr); 217762306a36Sopenharmony_ci} 217862306a36Sopenharmony_ci 217962306a36Sopenharmony_ci/* 218062306a36Sopenharmony_ci * Encode LOOKUPP request 218162306a36Sopenharmony_ci */ 218262306a36Sopenharmony_cistatic void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr, 218362306a36Sopenharmony_ci const void *data) 218462306a36Sopenharmony_ci{ 218562306a36Sopenharmony_ci const struct nfs4_lookupp_arg *args = data; 218662306a36Sopenharmony_ci struct compound_hdr hdr = { 218762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 218862306a36Sopenharmony_ci }; 218962306a36Sopenharmony_ci 219062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 219162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 219262306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 219362306a36Sopenharmony_ci encode_lookupp(xdr, &hdr); 219462306a36Sopenharmony_ci encode_getfh(xdr, &hdr); 219562306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 219662306a36Sopenharmony_ci encode_nops(&hdr); 219762306a36Sopenharmony_ci} 219862306a36Sopenharmony_ci 219962306a36Sopenharmony_ci/* 220062306a36Sopenharmony_ci * Encode LOOKUP_ROOT request 220162306a36Sopenharmony_ci */ 220262306a36Sopenharmony_cistatic void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, 220362306a36Sopenharmony_ci struct xdr_stream *xdr, 220462306a36Sopenharmony_ci const void *data) 220562306a36Sopenharmony_ci{ 220662306a36Sopenharmony_ci const struct nfs4_lookup_root_arg *args = data; 220762306a36Sopenharmony_ci struct compound_hdr hdr = { 220862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 220962306a36Sopenharmony_ci }; 221062306a36Sopenharmony_ci 221162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 221262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 221362306a36Sopenharmony_ci encode_putrootfh(xdr, &hdr); 221462306a36Sopenharmony_ci encode_getfh(xdr, &hdr); 221562306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 221662306a36Sopenharmony_ci encode_nops(&hdr); 221762306a36Sopenharmony_ci} 221862306a36Sopenharmony_ci 221962306a36Sopenharmony_ci/* 222062306a36Sopenharmony_ci * Encode REMOVE request 222162306a36Sopenharmony_ci */ 222262306a36Sopenharmony_cistatic void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr, 222362306a36Sopenharmony_ci const void *data) 222462306a36Sopenharmony_ci{ 222562306a36Sopenharmony_ci const struct nfs_removeargs *args = data; 222662306a36Sopenharmony_ci struct compound_hdr hdr = { 222762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 222862306a36Sopenharmony_ci }; 222962306a36Sopenharmony_ci 223062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 223162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 223262306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 223362306a36Sopenharmony_ci encode_remove(xdr, &args->name, &hdr); 223462306a36Sopenharmony_ci encode_nops(&hdr); 223562306a36Sopenharmony_ci} 223662306a36Sopenharmony_ci 223762306a36Sopenharmony_ci/* 223862306a36Sopenharmony_ci * Encode RENAME request 223962306a36Sopenharmony_ci */ 224062306a36Sopenharmony_cistatic void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr, 224162306a36Sopenharmony_ci const void *data) 224262306a36Sopenharmony_ci{ 224362306a36Sopenharmony_ci const struct nfs_renameargs *args = data; 224462306a36Sopenharmony_ci struct compound_hdr hdr = { 224562306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 224662306a36Sopenharmony_ci }; 224762306a36Sopenharmony_ci 224862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 224962306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 225062306a36Sopenharmony_ci encode_putfh(xdr, args->old_dir, &hdr); 225162306a36Sopenharmony_ci encode_savefh(xdr, &hdr); 225262306a36Sopenharmony_ci encode_putfh(xdr, args->new_dir, &hdr); 225362306a36Sopenharmony_ci encode_rename(xdr, args->old_name, args->new_name, &hdr); 225462306a36Sopenharmony_ci encode_nops(&hdr); 225562306a36Sopenharmony_ci} 225662306a36Sopenharmony_ci 225762306a36Sopenharmony_ci/* 225862306a36Sopenharmony_ci * Encode LINK request 225962306a36Sopenharmony_ci */ 226062306a36Sopenharmony_cistatic void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr, 226162306a36Sopenharmony_ci const void *data) 226262306a36Sopenharmony_ci{ 226362306a36Sopenharmony_ci const struct nfs4_link_arg *args = data; 226462306a36Sopenharmony_ci struct compound_hdr hdr = { 226562306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 226662306a36Sopenharmony_ci }; 226762306a36Sopenharmony_ci 226862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 226962306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 227062306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 227162306a36Sopenharmony_ci encode_savefh(xdr, &hdr); 227262306a36Sopenharmony_ci encode_putfh(xdr, args->dir_fh, &hdr); 227362306a36Sopenharmony_ci encode_link(xdr, args->name, &hdr); 227462306a36Sopenharmony_ci encode_restorefh(xdr, &hdr); 227562306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 227662306a36Sopenharmony_ci encode_nops(&hdr); 227762306a36Sopenharmony_ci} 227862306a36Sopenharmony_ci 227962306a36Sopenharmony_ci/* 228062306a36Sopenharmony_ci * Encode CREATE request 228162306a36Sopenharmony_ci */ 228262306a36Sopenharmony_cistatic void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr, 228362306a36Sopenharmony_ci const void *data) 228462306a36Sopenharmony_ci{ 228562306a36Sopenharmony_ci const struct nfs4_create_arg *args = data; 228662306a36Sopenharmony_ci struct compound_hdr hdr = { 228762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 228862306a36Sopenharmony_ci }; 228962306a36Sopenharmony_ci 229062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 229162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 229262306a36Sopenharmony_ci encode_putfh(xdr, args->dir_fh, &hdr); 229362306a36Sopenharmony_ci encode_create(xdr, args, &hdr); 229462306a36Sopenharmony_ci encode_getfh(xdr, &hdr); 229562306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 229662306a36Sopenharmony_ci encode_nops(&hdr); 229762306a36Sopenharmony_ci} 229862306a36Sopenharmony_ci 229962306a36Sopenharmony_ci/* 230062306a36Sopenharmony_ci * Encode SYMLINK request 230162306a36Sopenharmony_ci */ 230262306a36Sopenharmony_cistatic void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr, 230362306a36Sopenharmony_ci const void *data) 230462306a36Sopenharmony_ci{ 230562306a36Sopenharmony_ci const struct nfs4_create_arg *args = data; 230662306a36Sopenharmony_ci 230762306a36Sopenharmony_ci nfs4_xdr_enc_create(req, xdr, args); 230862306a36Sopenharmony_ci} 230962306a36Sopenharmony_ci 231062306a36Sopenharmony_ci/* 231162306a36Sopenharmony_ci * Encode GETATTR request 231262306a36Sopenharmony_ci */ 231362306a36Sopenharmony_cistatic void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr, 231462306a36Sopenharmony_ci const void *data) 231562306a36Sopenharmony_ci{ 231662306a36Sopenharmony_ci const struct nfs4_getattr_arg *args = data; 231762306a36Sopenharmony_ci struct compound_hdr hdr = { 231862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 231962306a36Sopenharmony_ci }; 232062306a36Sopenharmony_ci 232162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 232262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 232362306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 232462306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 232562306a36Sopenharmony_ci encode_nops(&hdr); 232662306a36Sopenharmony_ci} 232762306a36Sopenharmony_ci 232862306a36Sopenharmony_ci/* 232962306a36Sopenharmony_ci * Encode a CLOSE request 233062306a36Sopenharmony_ci */ 233162306a36Sopenharmony_cistatic void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr, 233262306a36Sopenharmony_ci const void *data) 233362306a36Sopenharmony_ci{ 233462306a36Sopenharmony_ci const struct nfs_closeargs *args = data; 233562306a36Sopenharmony_ci struct compound_hdr hdr = { 233662306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 233762306a36Sopenharmony_ci }; 233862306a36Sopenharmony_ci 233962306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 234062306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 234162306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 234262306a36Sopenharmony_ci if (args->lr_args) 234362306a36Sopenharmony_ci encode_layoutreturn(xdr, args->lr_args, &hdr); 234462306a36Sopenharmony_ci if (args->bitmask != NULL) 234562306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 234662306a36Sopenharmony_ci encode_close(xdr, args, &hdr); 234762306a36Sopenharmony_ci encode_nops(&hdr); 234862306a36Sopenharmony_ci} 234962306a36Sopenharmony_ci 235062306a36Sopenharmony_ci/* 235162306a36Sopenharmony_ci * Encode an OPEN request 235262306a36Sopenharmony_ci */ 235362306a36Sopenharmony_cistatic void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, 235462306a36Sopenharmony_ci const void *data) 235562306a36Sopenharmony_ci{ 235662306a36Sopenharmony_ci const struct nfs_openargs *args = data; 235762306a36Sopenharmony_ci struct compound_hdr hdr = { 235862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 235962306a36Sopenharmony_ci }; 236062306a36Sopenharmony_ci 236162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 236262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 236362306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 236462306a36Sopenharmony_ci encode_open(xdr, args, &hdr); 236562306a36Sopenharmony_ci encode_getfh(xdr, &hdr); 236662306a36Sopenharmony_ci if (args->access) 236762306a36Sopenharmony_ci encode_access(xdr, args->access, &hdr); 236862306a36Sopenharmony_ci encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr); 236962306a36Sopenharmony_ci if (args->lg_args) { 237062306a36Sopenharmony_ci encode_layoutget(xdr, args->lg_args, &hdr); 237162306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->lg_args->layout.pages, 0, 237262306a36Sopenharmony_ci args->lg_args->layout.pglen, 237362306a36Sopenharmony_ci hdr.replen - pagepad_maxsz); 237462306a36Sopenharmony_ci } 237562306a36Sopenharmony_ci encode_nops(&hdr); 237662306a36Sopenharmony_ci} 237762306a36Sopenharmony_ci 237862306a36Sopenharmony_ci/* 237962306a36Sopenharmony_ci * Encode an OPEN_CONFIRM request 238062306a36Sopenharmony_ci */ 238162306a36Sopenharmony_cistatic void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, 238262306a36Sopenharmony_ci struct xdr_stream *xdr, 238362306a36Sopenharmony_ci const void *data) 238462306a36Sopenharmony_ci{ 238562306a36Sopenharmony_ci const struct nfs_open_confirmargs *args = data; 238662306a36Sopenharmony_ci struct compound_hdr hdr = { 238762306a36Sopenharmony_ci .nops = 0, 238862306a36Sopenharmony_ci }; 238962306a36Sopenharmony_ci 239062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 239162306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 239262306a36Sopenharmony_ci encode_open_confirm(xdr, args, &hdr); 239362306a36Sopenharmony_ci encode_nops(&hdr); 239462306a36Sopenharmony_ci} 239562306a36Sopenharmony_ci 239662306a36Sopenharmony_ci/* 239762306a36Sopenharmony_ci * Encode an OPEN request with no attributes. 239862306a36Sopenharmony_ci */ 239962306a36Sopenharmony_cistatic void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, 240062306a36Sopenharmony_ci struct xdr_stream *xdr, 240162306a36Sopenharmony_ci const void *data) 240262306a36Sopenharmony_ci{ 240362306a36Sopenharmony_ci const struct nfs_openargs *args = data; 240462306a36Sopenharmony_ci struct compound_hdr hdr = { 240562306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 240662306a36Sopenharmony_ci }; 240762306a36Sopenharmony_ci 240862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 240962306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 241062306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 241162306a36Sopenharmony_ci encode_open(xdr, args, &hdr); 241262306a36Sopenharmony_ci if (args->access) 241362306a36Sopenharmony_ci encode_access(xdr, args->access, &hdr); 241462306a36Sopenharmony_ci encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr); 241562306a36Sopenharmony_ci if (args->lg_args) { 241662306a36Sopenharmony_ci encode_layoutget(xdr, args->lg_args, &hdr); 241762306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->lg_args->layout.pages, 0, 241862306a36Sopenharmony_ci args->lg_args->layout.pglen, 241962306a36Sopenharmony_ci hdr.replen - pagepad_maxsz); 242062306a36Sopenharmony_ci } 242162306a36Sopenharmony_ci encode_nops(&hdr); 242262306a36Sopenharmony_ci} 242362306a36Sopenharmony_ci 242462306a36Sopenharmony_ci/* 242562306a36Sopenharmony_ci * Encode an OPEN_DOWNGRADE request 242662306a36Sopenharmony_ci */ 242762306a36Sopenharmony_cistatic void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, 242862306a36Sopenharmony_ci struct xdr_stream *xdr, 242962306a36Sopenharmony_ci const void *data) 243062306a36Sopenharmony_ci{ 243162306a36Sopenharmony_ci const struct nfs_closeargs *args = data; 243262306a36Sopenharmony_ci struct compound_hdr hdr = { 243362306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 243462306a36Sopenharmony_ci }; 243562306a36Sopenharmony_ci 243662306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 243762306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 243862306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 243962306a36Sopenharmony_ci if (args->lr_args) 244062306a36Sopenharmony_ci encode_layoutreturn(xdr, args->lr_args, &hdr); 244162306a36Sopenharmony_ci encode_open_downgrade(xdr, args, &hdr); 244262306a36Sopenharmony_ci encode_nops(&hdr); 244362306a36Sopenharmony_ci} 244462306a36Sopenharmony_ci 244562306a36Sopenharmony_ci/* 244662306a36Sopenharmony_ci * Encode a LOCK request 244762306a36Sopenharmony_ci */ 244862306a36Sopenharmony_cistatic void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr, 244962306a36Sopenharmony_ci const void *data) 245062306a36Sopenharmony_ci{ 245162306a36Sopenharmony_ci const struct nfs_lock_args *args = data; 245262306a36Sopenharmony_ci struct compound_hdr hdr = { 245362306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 245462306a36Sopenharmony_ci }; 245562306a36Sopenharmony_ci 245662306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 245762306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 245862306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 245962306a36Sopenharmony_ci encode_lock(xdr, args, &hdr); 246062306a36Sopenharmony_ci encode_nops(&hdr); 246162306a36Sopenharmony_ci} 246262306a36Sopenharmony_ci 246362306a36Sopenharmony_ci/* 246462306a36Sopenharmony_ci * Encode a LOCKT request 246562306a36Sopenharmony_ci */ 246662306a36Sopenharmony_cistatic void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr, 246762306a36Sopenharmony_ci const void *data) 246862306a36Sopenharmony_ci{ 246962306a36Sopenharmony_ci const struct nfs_lockt_args *args = data; 247062306a36Sopenharmony_ci struct compound_hdr hdr = { 247162306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 247262306a36Sopenharmony_ci }; 247362306a36Sopenharmony_ci 247462306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 247562306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 247662306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 247762306a36Sopenharmony_ci encode_lockt(xdr, args, &hdr); 247862306a36Sopenharmony_ci encode_nops(&hdr); 247962306a36Sopenharmony_ci} 248062306a36Sopenharmony_ci 248162306a36Sopenharmony_ci/* 248262306a36Sopenharmony_ci * Encode a LOCKU request 248362306a36Sopenharmony_ci */ 248462306a36Sopenharmony_cistatic void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr, 248562306a36Sopenharmony_ci const void *data) 248662306a36Sopenharmony_ci{ 248762306a36Sopenharmony_ci const struct nfs_locku_args *args = data; 248862306a36Sopenharmony_ci struct compound_hdr hdr = { 248962306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 249062306a36Sopenharmony_ci }; 249162306a36Sopenharmony_ci 249262306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 249362306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 249462306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 249562306a36Sopenharmony_ci encode_locku(xdr, args, &hdr); 249662306a36Sopenharmony_ci encode_nops(&hdr); 249762306a36Sopenharmony_ci} 249862306a36Sopenharmony_ci 249962306a36Sopenharmony_cistatic void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, 250062306a36Sopenharmony_ci struct xdr_stream *xdr, 250162306a36Sopenharmony_ci const void *data) 250262306a36Sopenharmony_ci{ 250362306a36Sopenharmony_ci const struct nfs_release_lockowner_args *args = data; 250462306a36Sopenharmony_ci struct compound_hdr hdr = { 250562306a36Sopenharmony_ci .minorversion = 0, 250662306a36Sopenharmony_ci }; 250762306a36Sopenharmony_ci 250862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 250962306a36Sopenharmony_ci encode_release_lockowner(xdr, &args->lock_owner, &hdr); 251062306a36Sopenharmony_ci encode_nops(&hdr); 251162306a36Sopenharmony_ci} 251262306a36Sopenharmony_ci 251362306a36Sopenharmony_ci/* 251462306a36Sopenharmony_ci * Encode a READLINK request 251562306a36Sopenharmony_ci */ 251662306a36Sopenharmony_cistatic void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr, 251762306a36Sopenharmony_ci const void *data) 251862306a36Sopenharmony_ci{ 251962306a36Sopenharmony_ci const struct nfs4_readlink *args = data; 252062306a36Sopenharmony_ci struct compound_hdr hdr = { 252162306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 252262306a36Sopenharmony_ci }; 252362306a36Sopenharmony_ci 252462306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 252562306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 252662306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 252762306a36Sopenharmony_ci encode_readlink(xdr, args, req, &hdr); 252862306a36Sopenharmony_ci 252962306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->pages, args->pgbase, 253062306a36Sopenharmony_ci args->pglen, hdr.replen - pagepad_maxsz); 253162306a36Sopenharmony_ci encode_nops(&hdr); 253262306a36Sopenharmony_ci} 253362306a36Sopenharmony_ci 253462306a36Sopenharmony_ci/* 253562306a36Sopenharmony_ci * Encode a READDIR request 253662306a36Sopenharmony_ci */ 253762306a36Sopenharmony_cistatic void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr, 253862306a36Sopenharmony_ci const void *data) 253962306a36Sopenharmony_ci{ 254062306a36Sopenharmony_ci const struct nfs4_readdir_arg *args = data; 254162306a36Sopenharmony_ci struct compound_hdr hdr = { 254262306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 254362306a36Sopenharmony_ci }; 254462306a36Sopenharmony_ci 254562306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 254662306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 254762306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 254862306a36Sopenharmony_ci encode_readdir(xdr, args, req, &hdr); 254962306a36Sopenharmony_ci 255062306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->pages, args->pgbase, 255162306a36Sopenharmony_ci args->count, hdr.replen - pagepad_maxsz); 255262306a36Sopenharmony_ci encode_nops(&hdr); 255362306a36Sopenharmony_ci} 255462306a36Sopenharmony_ci 255562306a36Sopenharmony_ci/* 255662306a36Sopenharmony_ci * Encode a READ request 255762306a36Sopenharmony_ci */ 255862306a36Sopenharmony_cistatic void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr, 255962306a36Sopenharmony_ci const void *data) 256062306a36Sopenharmony_ci{ 256162306a36Sopenharmony_ci const struct nfs_pgio_args *args = data; 256262306a36Sopenharmony_ci struct compound_hdr hdr = { 256362306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 256462306a36Sopenharmony_ci }; 256562306a36Sopenharmony_ci 256662306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 256762306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 256862306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 256962306a36Sopenharmony_ci encode_read(xdr, args, &hdr); 257062306a36Sopenharmony_ci 257162306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->pages, args->pgbase, 257262306a36Sopenharmony_ci args->count, hdr.replen - pagepad_maxsz); 257362306a36Sopenharmony_ci req->rq_rcv_buf.flags |= XDRBUF_READ; 257462306a36Sopenharmony_ci encode_nops(&hdr); 257562306a36Sopenharmony_ci} 257662306a36Sopenharmony_ci 257762306a36Sopenharmony_ci/* 257862306a36Sopenharmony_ci * Encode an SETATTR request 257962306a36Sopenharmony_ci */ 258062306a36Sopenharmony_cistatic void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr, 258162306a36Sopenharmony_ci const void *data) 258262306a36Sopenharmony_ci{ 258362306a36Sopenharmony_ci const struct nfs_setattrargs *args = data; 258462306a36Sopenharmony_ci struct compound_hdr hdr = { 258562306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 258662306a36Sopenharmony_ci }; 258762306a36Sopenharmony_ci 258862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 258962306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 259062306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 259162306a36Sopenharmony_ci encode_setattr(xdr, args, args->server, &hdr); 259262306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 259362306a36Sopenharmony_ci encode_nops(&hdr); 259462306a36Sopenharmony_ci} 259562306a36Sopenharmony_ci 259662306a36Sopenharmony_ci/* 259762306a36Sopenharmony_ci * Encode a GETACL request 259862306a36Sopenharmony_ci */ 259962306a36Sopenharmony_cistatic void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, 260062306a36Sopenharmony_ci const void *data) 260162306a36Sopenharmony_ci{ 260262306a36Sopenharmony_ci const struct nfs_getaclargs *args = data; 260362306a36Sopenharmony_ci struct compound_hdr hdr = { 260462306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 260562306a36Sopenharmony_ci }; 260662306a36Sopenharmony_ci __u32 nfs4_acl_bitmap[2]; 260762306a36Sopenharmony_ci uint32_t replen; 260862306a36Sopenharmony_ci 260962306a36Sopenharmony_ci nfs4_acltype_to_bitmap(args->acl_type, nfs4_acl_bitmap); 261062306a36Sopenharmony_ci 261162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 261262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 261362306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 261462306a36Sopenharmony_ci replen = hdr.replen + op_decode_hdr_maxsz; 261562306a36Sopenharmony_ci encode_getattr(xdr, nfs4_acl_bitmap, NULL, 261662306a36Sopenharmony_ci ARRAY_SIZE(nfs4_acl_bitmap), &hdr); 261762306a36Sopenharmony_ci 261862306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->acl_pages, 0, 261962306a36Sopenharmony_ci args->acl_len, replen); 262062306a36Sopenharmony_ci encode_nops(&hdr); 262162306a36Sopenharmony_ci} 262262306a36Sopenharmony_ci 262362306a36Sopenharmony_ci/* 262462306a36Sopenharmony_ci * Encode a WRITE request 262562306a36Sopenharmony_ci */ 262662306a36Sopenharmony_cistatic void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr, 262762306a36Sopenharmony_ci const void *data) 262862306a36Sopenharmony_ci{ 262962306a36Sopenharmony_ci const struct nfs_pgio_args *args = data; 263062306a36Sopenharmony_ci struct compound_hdr hdr = { 263162306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 263262306a36Sopenharmony_ci }; 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 263562306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 263662306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 263762306a36Sopenharmony_ci encode_write(xdr, args, &hdr); 263862306a36Sopenharmony_ci req->rq_snd_buf.flags |= XDRBUF_WRITE; 263962306a36Sopenharmony_ci if (args->bitmask) 264062306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 264162306a36Sopenharmony_ci encode_nops(&hdr); 264262306a36Sopenharmony_ci} 264362306a36Sopenharmony_ci 264462306a36Sopenharmony_ci/* 264562306a36Sopenharmony_ci * a COMMIT request 264662306a36Sopenharmony_ci */ 264762306a36Sopenharmony_cistatic void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr, 264862306a36Sopenharmony_ci const void *data) 264962306a36Sopenharmony_ci{ 265062306a36Sopenharmony_ci const struct nfs_commitargs *args = data; 265162306a36Sopenharmony_ci struct compound_hdr hdr = { 265262306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 265362306a36Sopenharmony_ci }; 265462306a36Sopenharmony_ci 265562306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 265662306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 265762306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 265862306a36Sopenharmony_ci encode_commit(xdr, args, &hdr); 265962306a36Sopenharmony_ci encode_nops(&hdr); 266062306a36Sopenharmony_ci} 266162306a36Sopenharmony_ci 266262306a36Sopenharmony_ci/* 266362306a36Sopenharmony_ci * FSINFO request 266462306a36Sopenharmony_ci */ 266562306a36Sopenharmony_cistatic void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, 266662306a36Sopenharmony_ci const void *data) 266762306a36Sopenharmony_ci{ 266862306a36Sopenharmony_ci const struct nfs4_fsinfo_arg *args = data; 266962306a36Sopenharmony_ci struct compound_hdr hdr = { 267062306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 267162306a36Sopenharmony_ci }; 267262306a36Sopenharmony_ci 267362306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 267462306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 267562306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 267662306a36Sopenharmony_ci encode_fsinfo(xdr, args->bitmask, &hdr); 267762306a36Sopenharmony_ci encode_nops(&hdr); 267862306a36Sopenharmony_ci} 267962306a36Sopenharmony_ci 268062306a36Sopenharmony_ci/* 268162306a36Sopenharmony_ci * a PATHCONF request 268262306a36Sopenharmony_ci */ 268362306a36Sopenharmony_cistatic void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, 268462306a36Sopenharmony_ci const void *data) 268562306a36Sopenharmony_ci{ 268662306a36Sopenharmony_ci const struct nfs4_pathconf_arg *args = data; 268762306a36Sopenharmony_ci struct compound_hdr hdr = { 268862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 268962306a36Sopenharmony_ci }; 269062306a36Sopenharmony_ci 269162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 269262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 269362306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 269462306a36Sopenharmony_ci encode_getattr(xdr, nfs4_pathconf_bitmap, args->bitmask, 269562306a36Sopenharmony_ci ARRAY_SIZE(nfs4_pathconf_bitmap), &hdr); 269662306a36Sopenharmony_ci encode_nops(&hdr); 269762306a36Sopenharmony_ci} 269862306a36Sopenharmony_ci 269962306a36Sopenharmony_ci/* 270062306a36Sopenharmony_ci * a STATFS request 270162306a36Sopenharmony_ci */ 270262306a36Sopenharmony_cistatic void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, 270362306a36Sopenharmony_ci const void *data) 270462306a36Sopenharmony_ci{ 270562306a36Sopenharmony_ci const struct nfs4_statfs_arg *args = data; 270662306a36Sopenharmony_ci struct compound_hdr hdr = { 270762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 270862306a36Sopenharmony_ci }; 270962306a36Sopenharmony_ci 271062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 271162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 271262306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 271362306a36Sopenharmony_ci encode_getattr(xdr, nfs4_statfs_bitmap, args->bitmask, 271462306a36Sopenharmony_ci ARRAY_SIZE(nfs4_statfs_bitmap), &hdr); 271562306a36Sopenharmony_ci encode_nops(&hdr); 271662306a36Sopenharmony_ci} 271762306a36Sopenharmony_ci 271862306a36Sopenharmony_ci/* 271962306a36Sopenharmony_ci * GETATTR_BITMAP request 272062306a36Sopenharmony_ci */ 272162306a36Sopenharmony_cistatic void nfs4_xdr_enc_server_caps(struct rpc_rqst *req, 272262306a36Sopenharmony_ci struct xdr_stream *xdr, 272362306a36Sopenharmony_ci const void *data) 272462306a36Sopenharmony_ci{ 272562306a36Sopenharmony_ci const struct nfs4_server_caps_arg *args = data; 272662306a36Sopenharmony_ci const u32 *bitmask = args->bitmask; 272762306a36Sopenharmony_ci struct compound_hdr hdr = { 272862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 272962306a36Sopenharmony_ci }; 273062306a36Sopenharmony_ci 273162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 273262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 273362306a36Sopenharmony_ci encode_putfh(xdr, args->fhandle, &hdr); 273462306a36Sopenharmony_ci encode_getattr(xdr, bitmask, NULL, 3, &hdr); 273562306a36Sopenharmony_ci encode_nops(&hdr); 273662306a36Sopenharmony_ci} 273762306a36Sopenharmony_ci 273862306a36Sopenharmony_ci/* 273962306a36Sopenharmony_ci * a RENEW request 274062306a36Sopenharmony_ci */ 274162306a36Sopenharmony_cistatic void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr, 274262306a36Sopenharmony_ci const void *data) 274362306a36Sopenharmony_ci 274462306a36Sopenharmony_ci{ 274562306a36Sopenharmony_ci const struct nfs_client *clp = data; 274662306a36Sopenharmony_ci struct compound_hdr hdr = { 274762306a36Sopenharmony_ci .nops = 0, 274862306a36Sopenharmony_ci }; 274962306a36Sopenharmony_ci 275062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 275162306a36Sopenharmony_ci encode_renew(xdr, clp->cl_clientid, &hdr); 275262306a36Sopenharmony_ci encode_nops(&hdr); 275362306a36Sopenharmony_ci} 275462306a36Sopenharmony_ci 275562306a36Sopenharmony_ci/* 275662306a36Sopenharmony_ci * a SETCLIENTID request 275762306a36Sopenharmony_ci */ 275862306a36Sopenharmony_cistatic void nfs4_xdr_enc_setclientid(struct rpc_rqst *req, 275962306a36Sopenharmony_ci struct xdr_stream *xdr, 276062306a36Sopenharmony_ci const void *data) 276162306a36Sopenharmony_ci{ 276262306a36Sopenharmony_ci const struct nfs4_setclientid *sc = data; 276362306a36Sopenharmony_ci struct compound_hdr hdr = { 276462306a36Sopenharmony_ci .nops = 0, 276562306a36Sopenharmony_ci }; 276662306a36Sopenharmony_ci 276762306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 276862306a36Sopenharmony_ci encode_setclientid(xdr, sc, &hdr); 276962306a36Sopenharmony_ci encode_nops(&hdr); 277062306a36Sopenharmony_ci} 277162306a36Sopenharmony_ci 277262306a36Sopenharmony_ci/* 277362306a36Sopenharmony_ci * a SETCLIENTID_CONFIRM request 277462306a36Sopenharmony_ci */ 277562306a36Sopenharmony_cistatic void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, 277662306a36Sopenharmony_ci struct xdr_stream *xdr, 277762306a36Sopenharmony_ci const void *data) 277862306a36Sopenharmony_ci{ 277962306a36Sopenharmony_ci const struct nfs4_setclientid_res *arg = data; 278062306a36Sopenharmony_ci struct compound_hdr hdr = { 278162306a36Sopenharmony_ci .nops = 0, 278262306a36Sopenharmony_ci }; 278362306a36Sopenharmony_ci 278462306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 278562306a36Sopenharmony_ci encode_setclientid_confirm(xdr, arg, &hdr); 278662306a36Sopenharmony_ci encode_nops(&hdr); 278762306a36Sopenharmony_ci} 278862306a36Sopenharmony_ci 278962306a36Sopenharmony_ci/* 279062306a36Sopenharmony_ci * DELEGRETURN request 279162306a36Sopenharmony_ci */ 279262306a36Sopenharmony_cistatic void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, 279362306a36Sopenharmony_ci struct xdr_stream *xdr, 279462306a36Sopenharmony_ci const void *data) 279562306a36Sopenharmony_ci{ 279662306a36Sopenharmony_ci const struct nfs4_delegreturnargs *args = data; 279762306a36Sopenharmony_ci struct compound_hdr hdr = { 279862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 279962306a36Sopenharmony_ci }; 280062306a36Sopenharmony_ci 280162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 280262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 280362306a36Sopenharmony_ci encode_putfh(xdr, args->fhandle, &hdr); 280462306a36Sopenharmony_ci if (args->lr_args) 280562306a36Sopenharmony_ci encode_layoutreturn(xdr, args->lr_args, &hdr); 280662306a36Sopenharmony_ci if (args->bitmask) 280762306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 280862306a36Sopenharmony_ci encode_delegreturn(xdr, args->stateid, &hdr); 280962306a36Sopenharmony_ci encode_nops(&hdr); 281062306a36Sopenharmony_ci} 281162306a36Sopenharmony_ci 281262306a36Sopenharmony_ci/* 281362306a36Sopenharmony_ci * Encode FS_LOCATIONS request 281462306a36Sopenharmony_ci */ 281562306a36Sopenharmony_cistatic void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, 281662306a36Sopenharmony_ci struct xdr_stream *xdr, 281762306a36Sopenharmony_ci const void *data) 281862306a36Sopenharmony_ci{ 281962306a36Sopenharmony_ci const struct nfs4_fs_locations_arg *args = data; 282062306a36Sopenharmony_ci struct compound_hdr hdr = { 282162306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 282262306a36Sopenharmony_ci }; 282362306a36Sopenharmony_ci uint32_t replen; 282462306a36Sopenharmony_ci 282562306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 282662306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 282762306a36Sopenharmony_ci if (args->migration) { 282862306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 282962306a36Sopenharmony_ci replen = hdr.replen; 283062306a36Sopenharmony_ci encode_fs_locations(xdr, args->bitmask, &hdr); 283162306a36Sopenharmony_ci if (args->renew) 283262306a36Sopenharmony_ci encode_renew(xdr, args->clientid, &hdr); 283362306a36Sopenharmony_ci } else { 283462306a36Sopenharmony_ci encode_putfh(xdr, args->dir_fh, &hdr); 283562306a36Sopenharmony_ci encode_lookup(xdr, args->name, &hdr); 283662306a36Sopenharmony_ci replen = hdr.replen; 283762306a36Sopenharmony_ci encode_fs_locations(xdr, args->bitmask, &hdr); 283862306a36Sopenharmony_ci } 283962306a36Sopenharmony_ci 284062306a36Sopenharmony_ci rpc_prepare_reply_pages(req, (struct page **)&args->page, 0, 284162306a36Sopenharmony_ci PAGE_SIZE, replen); 284262306a36Sopenharmony_ci encode_nops(&hdr); 284362306a36Sopenharmony_ci} 284462306a36Sopenharmony_ci 284562306a36Sopenharmony_ci/* 284662306a36Sopenharmony_ci * Encode SECINFO request 284762306a36Sopenharmony_ci */ 284862306a36Sopenharmony_cistatic void nfs4_xdr_enc_secinfo(struct rpc_rqst *req, 284962306a36Sopenharmony_ci struct xdr_stream *xdr, 285062306a36Sopenharmony_ci const void *data) 285162306a36Sopenharmony_ci{ 285262306a36Sopenharmony_ci const struct nfs4_secinfo_arg *args = data; 285362306a36Sopenharmony_ci struct compound_hdr hdr = { 285462306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 285562306a36Sopenharmony_ci }; 285662306a36Sopenharmony_ci 285762306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 285862306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 285962306a36Sopenharmony_ci encode_putfh(xdr, args->dir_fh, &hdr); 286062306a36Sopenharmony_ci encode_secinfo(xdr, args->name, &hdr); 286162306a36Sopenharmony_ci encode_nops(&hdr); 286262306a36Sopenharmony_ci} 286362306a36Sopenharmony_ci 286462306a36Sopenharmony_ci/* 286562306a36Sopenharmony_ci * Encode FSID_PRESENT request 286662306a36Sopenharmony_ci */ 286762306a36Sopenharmony_cistatic void nfs4_xdr_enc_fsid_present(struct rpc_rqst *req, 286862306a36Sopenharmony_ci struct xdr_stream *xdr, 286962306a36Sopenharmony_ci const void *data) 287062306a36Sopenharmony_ci{ 287162306a36Sopenharmony_ci const struct nfs4_fsid_present_arg *args = data; 287262306a36Sopenharmony_ci struct compound_hdr hdr = { 287362306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 287462306a36Sopenharmony_ci }; 287562306a36Sopenharmony_ci 287662306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 287762306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 287862306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 287962306a36Sopenharmony_ci encode_getfh(xdr, &hdr); 288062306a36Sopenharmony_ci if (args->renew) 288162306a36Sopenharmony_ci encode_renew(xdr, args->clientid, &hdr); 288262306a36Sopenharmony_ci encode_nops(&hdr); 288362306a36Sopenharmony_ci} 288462306a36Sopenharmony_ci 288562306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 288662306a36Sopenharmony_ci/* 288762306a36Sopenharmony_ci * BIND_CONN_TO_SESSION request 288862306a36Sopenharmony_ci */ 288962306a36Sopenharmony_cistatic void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req, 289062306a36Sopenharmony_ci struct xdr_stream *xdr, 289162306a36Sopenharmony_ci const void *data) 289262306a36Sopenharmony_ci{ 289362306a36Sopenharmony_ci const struct nfs41_bind_conn_to_session_args *args = data; 289462306a36Sopenharmony_ci struct compound_hdr hdr = { 289562306a36Sopenharmony_ci .minorversion = args->client->cl_mvops->minor_version, 289662306a36Sopenharmony_ci }; 289762306a36Sopenharmony_ci 289862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 289962306a36Sopenharmony_ci encode_bind_conn_to_session(xdr, args, &hdr); 290062306a36Sopenharmony_ci encode_nops(&hdr); 290162306a36Sopenharmony_ci} 290262306a36Sopenharmony_ci 290362306a36Sopenharmony_ci/* 290462306a36Sopenharmony_ci * EXCHANGE_ID request 290562306a36Sopenharmony_ci */ 290662306a36Sopenharmony_cistatic void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, 290762306a36Sopenharmony_ci struct xdr_stream *xdr, 290862306a36Sopenharmony_ci const void *data) 290962306a36Sopenharmony_ci{ 291062306a36Sopenharmony_ci const struct nfs41_exchange_id_args *args = data; 291162306a36Sopenharmony_ci struct compound_hdr hdr = { 291262306a36Sopenharmony_ci .minorversion = args->client->cl_mvops->minor_version, 291362306a36Sopenharmony_ci }; 291462306a36Sopenharmony_ci 291562306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 291662306a36Sopenharmony_ci encode_exchange_id(xdr, args, &hdr); 291762306a36Sopenharmony_ci encode_nops(&hdr); 291862306a36Sopenharmony_ci} 291962306a36Sopenharmony_ci 292062306a36Sopenharmony_ci/* 292162306a36Sopenharmony_ci * a CREATE_SESSION request 292262306a36Sopenharmony_ci */ 292362306a36Sopenharmony_cistatic void nfs4_xdr_enc_create_session(struct rpc_rqst *req, 292462306a36Sopenharmony_ci struct xdr_stream *xdr, 292562306a36Sopenharmony_ci const void *data) 292662306a36Sopenharmony_ci{ 292762306a36Sopenharmony_ci const struct nfs41_create_session_args *args = data; 292862306a36Sopenharmony_ci struct compound_hdr hdr = { 292962306a36Sopenharmony_ci .minorversion = args->client->cl_mvops->minor_version, 293062306a36Sopenharmony_ci }; 293162306a36Sopenharmony_ci 293262306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 293362306a36Sopenharmony_ci encode_create_session(xdr, args, &hdr); 293462306a36Sopenharmony_ci encode_nops(&hdr); 293562306a36Sopenharmony_ci} 293662306a36Sopenharmony_ci 293762306a36Sopenharmony_ci/* 293862306a36Sopenharmony_ci * a DESTROY_SESSION request 293962306a36Sopenharmony_ci */ 294062306a36Sopenharmony_cistatic void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, 294162306a36Sopenharmony_ci struct xdr_stream *xdr, 294262306a36Sopenharmony_ci const void *data) 294362306a36Sopenharmony_ci{ 294462306a36Sopenharmony_ci const struct nfs4_session *session = data; 294562306a36Sopenharmony_ci struct compound_hdr hdr = { 294662306a36Sopenharmony_ci .minorversion = session->clp->cl_mvops->minor_version, 294762306a36Sopenharmony_ci }; 294862306a36Sopenharmony_ci 294962306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 295062306a36Sopenharmony_ci encode_destroy_session(xdr, session, &hdr); 295162306a36Sopenharmony_ci encode_nops(&hdr); 295262306a36Sopenharmony_ci} 295362306a36Sopenharmony_ci 295462306a36Sopenharmony_ci/* 295562306a36Sopenharmony_ci * a DESTROY_CLIENTID request 295662306a36Sopenharmony_ci */ 295762306a36Sopenharmony_cistatic void nfs4_xdr_enc_destroy_clientid(struct rpc_rqst *req, 295862306a36Sopenharmony_ci struct xdr_stream *xdr, 295962306a36Sopenharmony_ci const void *data) 296062306a36Sopenharmony_ci{ 296162306a36Sopenharmony_ci const struct nfs_client *clp = data; 296262306a36Sopenharmony_ci struct compound_hdr hdr = { 296362306a36Sopenharmony_ci .minorversion = clp->cl_mvops->minor_version, 296462306a36Sopenharmony_ci }; 296562306a36Sopenharmony_ci 296662306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 296762306a36Sopenharmony_ci encode_destroy_clientid(xdr, clp->cl_clientid, &hdr); 296862306a36Sopenharmony_ci encode_nops(&hdr); 296962306a36Sopenharmony_ci} 297062306a36Sopenharmony_ci 297162306a36Sopenharmony_ci/* 297262306a36Sopenharmony_ci * a SEQUENCE request 297362306a36Sopenharmony_ci */ 297462306a36Sopenharmony_cistatic void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr, 297562306a36Sopenharmony_ci const void *data) 297662306a36Sopenharmony_ci{ 297762306a36Sopenharmony_ci const struct nfs4_sequence_args *args = data; 297862306a36Sopenharmony_ci struct compound_hdr hdr = { 297962306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(args), 298062306a36Sopenharmony_ci }; 298162306a36Sopenharmony_ci 298262306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 298362306a36Sopenharmony_ci encode_sequence(xdr, args, &hdr); 298462306a36Sopenharmony_ci encode_nops(&hdr); 298562306a36Sopenharmony_ci} 298662306a36Sopenharmony_ci 298762306a36Sopenharmony_ci#endif 298862306a36Sopenharmony_ci 298962306a36Sopenharmony_ci/* 299062306a36Sopenharmony_ci * a GET_LEASE_TIME request 299162306a36Sopenharmony_ci */ 299262306a36Sopenharmony_cistatic void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, 299362306a36Sopenharmony_ci struct xdr_stream *xdr, 299462306a36Sopenharmony_ci const void *data) 299562306a36Sopenharmony_ci{ 299662306a36Sopenharmony_ci const struct nfs4_get_lease_time_args *args = data; 299762306a36Sopenharmony_ci struct compound_hdr hdr = { 299862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), 299962306a36Sopenharmony_ci }; 300062306a36Sopenharmony_ci const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME }; 300162306a36Sopenharmony_ci 300262306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 300362306a36Sopenharmony_ci encode_sequence(xdr, &args->la_seq_args, &hdr); 300462306a36Sopenharmony_ci encode_putrootfh(xdr, &hdr); 300562306a36Sopenharmony_ci encode_fsinfo(xdr, lease_bitmap, &hdr); 300662306a36Sopenharmony_ci encode_nops(&hdr); 300762306a36Sopenharmony_ci} 300862306a36Sopenharmony_ci 300962306a36Sopenharmony_ci#ifdef CONFIG_NFS_V4_1 301062306a36Sopenharmony_ci 301162306a36Sopenharmony_ci/* 301262306a36Sopenharmony_ci * a RECLAIM_COMPLETE request 301362306a36Sopenharmony_ci */ 301462306a36Sopenharmony_cistatic void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, 301562306a36Sopenharmony_ci struct xdr_stream *xdr, 301662306a36Sopenharmony_ci const void *data) 301762306a36Sopenharmony_ci{ 301862306a36Sopenharmony_ci const struct nfs41_reclaim_complete_args *args = data; 301962306a36Sopenharmony_ci struct compound_hdr hdr = { 302062306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args) 302162306a36Sopenharmony_ci }; 302262306a36Sopenharmony_ci 302362306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 302462306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 302562306a36Sopenharmony_ci encode_reclaim_complete(xdr, args, &hdr); 302662306a36Sopenharmony_ci encode_nops(&hdr); 302762306a36Sopenharmony_ci} 302862306a36Sopenharmony_ci 302962306a36Sopenharmony_ci/* 303062306a36Sopenharmony_ci * Encode GETDEVICEINFO request 303162306a36Sopenharmony_ci */ 303262306a36Sopenharmony_cistatic void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, 303362306a36Sopenharmony_ci struct xdr_stream *xdr, 303462306a36Sopenharmony_ci const void *data) 303562306a36Sopenharmony_ci{ 303662306a36Sopenharmony_ci const struct nfs4_getdeviceinfo_args *args = data; 303762306a36Sopenharmony_ci struct compound_hdr hdr = { 303862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 303962306a36Sopenharmony_ci }; 304062306a36Sopenharmony_ci uint32_t replen; 304162306a36Sopenharmony_ci 304262306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 304362306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 304462306a36Sopenharmony_ci 304562306a36Sopenharmony_ci replen = hdr.replen + op_decode_hdr_maxsz + 2; 304662306a36Sopenharmony_ci 304762306a36Sopenharmony_ci encode_getdeviceinfo(xdr, args, &hdr); 304862306a36Sopenharmony_ci 304962306a36Sopenharmony_ci /* set up reply kvec. device_addr4 opaque data is read into the 305062306a36Sopenharmony_ci * pages */ 305162306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->pdev->pages, args->pdev->pgbase, 305262306a36Sopenharmony_ci args->pdev->pglen, replen); 305362306a36Sopenharmony_ci encode_nops(&hdr); 305462306a36Sopenharmony_ci} 305562306a36Sopenharmony_ci 305662306a36Sopenharmony_ci/* 305762306a36Sopenharmony_ci * Encode LAYOUTGET request 305862306a36Sopenharmony_ci */ 305962306a36Sopenharmony_cistatic void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, 306062306a36Sopenharmony_ci struct xdr_stream *xdr, 306162306a36Sopenharmony_ci const void *data) 306262306a36Sopenharmony_ci{ 306362306a36Sopenharmony_ci const struct nfs4_layoutget_args *args = data; 306462306a36Sopenharmony_ci struct compound_hdr hdr = { 306562306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 306662306a36Sopenharmony_ci }; 306762306a36Sopenharmony_ci 306862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 306962306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 307062306a36Sopenharmony_ci encode_putfh(xdr, NFS_FH(args->inode), &hdr); 307162306a36Sopenharmony_ci encode_layoutget(xdr, args, &hdr); 307262306a36Sopenharmony_ci 307362306a36Sopenharmony_ci rpc_prepare_reply_pages(req, args->layout.pages, 0, 307462306a36Sopenharmony_ci args->layout.pglen, hdr.replen - pagepad_maxsz); 307562306a36Sopenharmony_ci encode_nops(&hdr); 307662306a36Sopenharmony_ci} 307762306a36Sopenharmony_ci 307862306a36Sopenharmony_ci/* 307962306a36Sopenharmony_ci * Encode LAYOUTCOMMIT request 308062306a36Sopenharmony_ci */ 308162306a36Sopenharmony_cistatic void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, 308262306a36Sopenharmony_ci struct xdr_stream *xdr, 308362306a36Sopenharmony_ci const void *priv) 308462306a36Sopenharmony_ci{ 308562306a36Sopenharmony_ci const struct nfs4_layoutcommit_args *args = priv; 308662306a36Sopenharmony_ci struct nfs4_layoutcommit_data *data = 308762306a36Sopenharmony_ci container_of(args, struct nfs4_layoutcommit_data, args); 308862306a36Sopenharmony_ci struct compound_hdr hdr = { 308962306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 309062306a36Sopenharmony_ci }; 309162306a36Sopenharmony_ci 309262306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 309362306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 309462306a36Sopenharmony_ci encode_putfh(xdr, NFS_FH(args->inode), &hdr); 309562306a36Sopenharmony_ci encode_layoutcommit(xdr, data->args.inode, args, &hdr); 309662306a36Sopenharmony_ci encode_getfattr(xdr, args->bitmask, &hdr); 309762306a36Sopenharmony_ci encode_nops(&hdr); 309862306a36Sopenharmony_ci} 309962306a36Sopenharmony_ci 310062306a36Sopenharmony_ci/* 310162306a36Sopenharmony_ci * Encode LAYOUTRETURN request 310262306a36Sopenharmony_ci */ 310362306a36Sopenharmony_cistatic void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, 310462306a36Sopenharmony_ci struct xdr_stream *xdr, 310562306a36Sopenharmony_ci const void *data) 310662306a36Sopenharmony_ci{ 310762306a36Sopenharmony_ci const struct nfs4_layoutreturn_args *args = data; 310862306a36Sopenharmony_ci struct compound_hdr hdr = { 310962306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 311062306a36Sopenharmony_ci }; 311162306a36Sopenharmony_ci 311262306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 311362306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 311462306a36Sopenharmony_ci encode_putfh(xdr, NFS_FH(args->inode), &hdr); 311562306a36Sopenharmony_ci encode_layoutreturn(xdr, args, &hdr); 311662306a36Sopenharmony_ci encode_nops(&hdr); 311762306a36Sopenharmony_ci} 311862306a36Sopenharmony_ci 311962306a36Sopenharmony_ci/* 312062306a36Sopenharmony_ci * Encode SECINFO_NO_NAME request 312162306a36Sopenharmony_ci */ 312262306a36Sopenharmony_cistatic void nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, 312362306a36Sopenharmony_ci struct xdr_stream *xdr, 312462306a36Sopenharmony_ci const void *data) 312562306a36Sopenharmony_ci{ 312662306a36Sopenharmony_ci const struct nfs41_secinfo_no_name_args *args = data; 312762306a36Sopenharmony_ci struct compound_hdr hdr = { 312862306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 312962306a36Sopenharmony_ci }; 313062306a36Sopenharmony_ci 313162306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 313262306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 313362306a36Sopenharmony_ci encode_putrootfh(xdr, &hdr); 313462306a36Sopenharmony_ci encode_secinfo_no_name(xdr, args, &hdr); 313562306a36Sopenharmony_ci encode_nops(&hdr); 313662306a36Sopenharmony_ci} 313762306a36Sopenharmony_ci 313862306a36Sopenharmony_ci/* 313962306a36Sopenharmony_ci * Encode TEST_STATEID request 314062306a36Sopenharmony_ci */ 314162306a36Sopenharmony_cistatic void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req, 314262306a36Sopenharmony_ci struct xdr_stream *xdr, 314362306a36Sopenharmony_ci const void *data) 314462306a36Sopenharmony_ci{ 314562306a36Sopenharmony_ci const struct nfs41_test_stateid_args *args = data; 314662306a36Sopenharmony_ci struct compound_hdr hdr = { 314762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 314862306a36Sopenharmony_ci }; 314962306a36Sopenharmony_ci 315062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 315162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 315262306a36Sopenharmony_ci encode_test_stateid(xdr, args, &hdr); 315362306a36Sopenharmony_ci encode_nops(&hdr); 315462306a36Sopenharmony_ci} 315562306a36Sopenharmony_ci 315662306a36Sopenharmony_ci/* 315762306a36Sopenharmony_ci * Encode FREE_STATEID request 315862306a36Sopenharmony_ci */ 315962306a36Sopenharmony_cistatic void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req, 316062306a36Sopenharmony_ci struct xdr_stream *xdr, 316162306a36Sopenharmony_ci const void *data) 316262306a36Sopenharmony_ci{ 316362306a36Sopenharmony_ci const struct nfs41_free_stateid_args *args = data; 316462306a36Sopenharmony_ci struct compound_hdr hdr = { 316562306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 316662306a36Sopenharmony_ci }; 316762306a36Sopenharmony_ci 316862306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 316962306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 317062306a36Sopenharmony_ci encode_free_stateid(xdr, args, &hdr); 317162306a36Sopenharmony_ci encode_nops(&hdr); 317262306a36Sopenharmony_ci} 317362306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 317462306a36Sopenharmony_ci 317562306a36Sopenharmony_cistatic int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) 317662306a36Sopenharmony_ci{ 317762306a36Sopenharmony_ci ssize_t ret = xdr_stream_decode_opaque_inline(xdr, (void **)string, 317862306a36Sopenharmony_ci NFS4_OPAQUE_LIMIT); 317962306a36Sopenharmony_ci if (unlikely(ret < 0)) 318062306a36Sopenharmony_ci return -EIO; 318162306a36Sopenharmony_ci *len = ret; 318262306a36Sopenharmony_ci return 0; 318362306a36Sopenharmony_ci} 318462306a36Sopenharmony_ci 318562306a36Sopenharmony_cistatic int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) 318662306a36Sopenharmony_ci{ 318762306a36Sopenharmony_ci ssize_t ret; 318862306a36Sopenharmony_ci void *ptr; 318962306a36Sopenharmony_ci u32 tmp; 319062306a36Sopenharmony_ci 319162306a36Sopenharmony_ci if (xdr_stream_decode_u32(xdr, &tmp) < 0) 319262306a36Sopenharmony_ci return -EIO; 319362306a36Sopenharmony_ci hdr->status = tmp; 319462306a36Sopenharmony_ci 319562306a36Sopenharmony_ci ret = xdr_stream_decode_opaque_inline(xdr, &ptr, NFS4_OPAQUE_LIMIT); 319662306a36Sopenharmony_ci if (ret < 0) 319762306a36Sopenharmony_ci return -EIO; 319862306a36Sopenharmony_ci hdr->taglen = ret; 319962306a36Sopenharmony_ci hdr->tag = ptr; 320062306a36Sopenharmony_ci 320162306a36Sopenharmony_ci if (xdr_stream_decode_u32(xdr, &tmp) < 0) 320262306a36Sopenharmony_ci return -EIO; 320362306a36Sopenharmony_ci hdr->nops = tmp; 320462306a36Sopenharmony_ci if (unlikely(hdr->nops < 1)) 320562306a36Sopenharmony_ci return nfs4_stat_to_errno(hdr->status); 320662306a36Sopenharmony_ci return 0; 320762306a36Sopenharmony_ci} 320862306a36Sopenharmony_ci 320962306a36Sopenharmony_cistatic bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected, 321062306a36Sopenharmony_ci int *nfs_retval) 321162306a36Sopenharmony_ci{ 321262306a36Sopenharmony_ci __be32 *p; 321362306a36Sopenharmony_ci uint32_t opnum; 321462306a36Sopenharmony_ci int32_t nfserr; 321562306a36Sopenharmony_ci 321662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 321762306a36Sopenharmony_ci if (unlikely(!p)) 321862306a36Sopenharmony_ci goto out_overflow; 321962306a36Sopenharmony_ci opnum = be32_to_cpup(p++); 322062306a36Sopenharmony_ci if (unlikely(opnum != expected)) 322162306a36Sopenharmony_ci goto out_bad_operation; 322262306a36Sopenharmony_ci if (unlikely(*p != cpu_to_be32(NFS_OK))) 322362306a36Sopenharmony_ci goto out_status; 322462306a36Sopenharmony_ci *nfs_retval = 0; 322562306a36Sopenharmony_ci return true; 322662306a36Sopenharmony_ciout_status: 322762306a36Sopenharmony_ci nfserr = be32_to_cpup(p); 322862306a36Sopenharmony_ci trace_nfs4_xdr_status(xdr, opnum, nfserr); 322962306a36Sopenharmony_ci *nfs_retval = nfs4_stat_to_errno(nfserr); 323062306a36Sopenharmony_ci return true; 323162306a36Sopenharmony_ciout_bad_operation: 323262306a36Sopenharmony_ci trace_nfs4_xdr_bad_operation(xdr, opnum, expected); 323362306a36Sopenharmony_ci *nfs_retval = -EREMOTEIO; 323462306a36Sopenharmony_ci return false; 323562306a36Sopenharmony_ciout_overflow: 323662306a36Sopenharmony_ci *nfs_retval = -EIO; 323762306a36Sopenharmony_ci return false; 323862306a36Sopenharmony_ci} 323962306a36Sopenharmony_ci 324062306a36Sopenharmony_cistatic int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) 324162306a36Sopenharmony_ci{ 324262306a36Sopenharmony_ci int retval; 324362306a36Sopenharmony_ci 324462306a36Sopenharmony_ci __decode_op_hdr(xdr, expected, &retval); 324562306a36Sopenharmony_ci return retval; 324662306a36Sopenharmony_ci} 324762306a36Sopenharmony_ci 324862306a36Sopenharmony_ci/* Dummy routine */ 324962306a36Sopenharmony_cistatic int decode_ace(struct xdr_stream *xdr, void *ace) 325062306a36Sopenharmony_ci{ 325162306a36Sopenharmony_ci __be32 *p; 325262306a36Sopenharmony_ci unsigned int strlen; 325362306a36Sopenharmony_ci char *str; 325462306a36Sopenharmony_ci 325562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 12); 325662306a36Sopenharmony_ci if (unlikely(!p)) 325762306a36Sopenharmony_ci return -EIO; 325862306a36Sopenharmony_ci return decode_opaque_inline(xdr, &strlen, &str); 325962306a36Sopenharmony_ci} 326062306a36Sopenharmony_ci 326162306a36Sopenharmony_cistatic ssize_t 326262306a36Sopenharmony_cidecode_bitmap4(struct xdr_stream *xdr, uint32_t *bitmap, size_t sz) 326362306a36Sopenharmony_ci{ 326462306a36Sopenharmony_ci ssize_t ret; 326562306a36Sopenharmony_ci 326662306a36Sopenharmony_ci ret = xdr_stream_decode_uint32_array(xdr, bitmap, sz); 326762306a36Sopenharmony_ci if (likely(ret >= 0)) 326862306a36Sopenharmony_ci return ret; 326962306a36Sopenharmony_ci if (ret != -EMSGSIZE) 327062306a36Sopenharmony_ci return -EIO; 327162306a36Sopenharmony_ci return sz; 327262306a36Sopenharmony_ci} 327362306a36Sopenharmony_ci 327462306a36Sopenharmony_cistatic int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) 327562306a36Sopenharmony_ci{ 327662306a36Sopenharmony_ci ssize_t ret; 327762306a36Sopenharmony_ci ret = decode_bitmap4(xdr, bitmap, 3); 327862306a36Sopenharmony_ci return ret < 0 ? ret : 0; 327962306a36Sopenharmony_ci} 328062306a36Sopenharmony_ci 328162306a36Sopenharmony_cistatic int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, unsigned int *savep) 328262306a36Sopenharmony_ci{ 328362306a36Sopenharmony_ci __be32 *p; 328462306a36Sopenharmony_ci 328562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 328662306a36Sopenharmony_ci if (unlikely(!p)) 328762306a36Sopenharmony_ci return -EIO; 328862306a36Sopenharmony_ci *attrlen = be32_to_cpup(p); 328962306a36Sopenharmony_ci *savep = xdr_stream_pos(xdr); 329062306a36Sopenharmony_ci return 0; 329162306a36Sopenharmony_ci} 329262306a36Sopenharmony_ci 329362306a36Sopenharmony_cistatic int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) 329462306a36Sopenharmony_ci{ 329562306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) { 329662306a36Sopenharmony_ci int ret; 329762306a36Sopenharmony_ci ret = decode_attr_bitmap(xdr, bitmask); 329862306a36Sopenharmony_ci if (unlikely(ret < 0)) 329962306a36Sopenharmony_ci return ret; 330062306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS; 330162306a36Sopenharmony_ci } else 330262306a36Sopenharmony_ci bitmask[0] = bitmask[1] = bitmask[2] = 0; 330362306a36Sopenharmony_ci dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__, 330462306a36Sopenharmony_ci bitmask[0], bitmask[1], bitmask[2]); 330562306a36Sopenharmony_ci return 0; 330662306a36Sopenharmony_ci} 330762306a36Sopenharmony_ci 330862306a36Sopenharmony_cistatic int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type) 330962306a36Sopenharmony_ci{ 331062306a36Sopenharmony_ci __be32 *p; 331162306a36Sopenharmony_ci int ret = 0; 331262306a36Sopenharmony_ci 331362306a36Sopenharmony_ci *type = 0; 331462306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) 331562306a36Sopenharmony_ci return -EIO; 331662306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { 331762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 331862306a36Sopenharmony_ci if (unlikely(!p)) 331962306a36Sopenharmony_ci return -EIO; 332062306a36Sopenharmony_ci *type = be32_to_cpup(p); 332162306a36Sopenharmony_ci if (*type < NF4REG || *type > NF4NAMEDATTR) { 332262306a36Sopenharmony_ci dprintk("%s: bad type %d\n", __func__, *type); 332362306a36Sopenharmony_ci return -EIO; 332462306a36Sopenharmony_ci } 332562306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_TYPE; 332662306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_TYPE; 332762306a36Sopenharmony_ci } 332862306a36Sopenharmony_ci dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); 332962306a36Sopenharmony_ci return ret; 333062306a36Sopenharmony_ci} 333162306a36Sopenharmony_ci 333262306a36Sopenharmony_cistatic int decode_attr_fh_expire_type(struct xdr_stream *xdr, 333362306a36Sopenharmony_ci uint32_t *bitmap, uint32_t *type) 333462306a36Sopenharmony_ci{ 333562306a36Sopenharmony_ci __be32 *p; 333662306a36Sopenharmony_ci 333762306a36Sopenharmony_ci *type = 0; 333862306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FH_EXPIRE_TYPE - 1U))) 333962306a36Sopenharmony_ci return -EIO; 334062306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_FH_EXPIRE_TYPE)) { 334162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 334262306a36Sopenharmony_ci if (unlikely(!p)) 334362306a36Sopenharmony_ci return -EIO; 334462306a36Sopenharmony_ci *type = be32_to_cpup(p); 334562306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FH_EXPIRE_TYPE; 334662306a36Sopenharmony_ci } 334762306a36Sopenharmony_ci dprintk("%s: expire type=0x%x\n", __func__, *type); 334862306a36Sopenharmony_ci return 0; 334962306a36Sopenharmony_ci} 335062306a36Sopenharmony_ci 335162306a36Sopenharmony_cistatic int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) 335262306a36Sopenharmony_ci{ 335362306a36Sopenharmony_ci __be32 *p; 335462306a36Sopenharmony_ci int ret = 0; 335562306a36Sopenharmony_ci 335662306a36Sopenharmony_ci *change = 0; 335762306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) 335862306a36Sopenharmony_ci return -EIO; 335962306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { 336062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 336162306a36Sopenharmony_ci if (unlikely(!p)) 336262306a36Sopenharmony_ci return -EIO; 336362306a36Sopenharmony_ci xdr_decode_hyper(p, change); 336462306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_CHANGE; 336562306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_CHANGE; 336662306a36Sopenharmony_ci } 336762306a36Sopenharmony_ci dprintk("%s: change attribute=%Lu\n", __func__, 336862306a36Sopenharmony_ci (unsigned long long)*change); 336962306a36Sopenharmony_ci return ret; 337062306a36Sopenharmony_ci} 337162306a36Sopenharmony_ci 337262306a36Sopenharmony_cistatic int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) 337362306a36Sopenharmony_ci{ 337462306a36Sopenharmony_ci __be32 *p; 337562306a36Sopenharmony_ci int ret = 0; 337662306a36Sopenharmony_ci 337762306a36Sopenharmony_ci *size = 0; 337862306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) 337962306a36Sopenharmony_ci return -EIO; 338062306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { 338162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 338262306a36Sopenharmony_ci if (unlikely(!p)) 338362306a36Sopenharmony_ci return -EIO; 338462306a36Sopenharmony_ci xdr_decode_hyper(p, size); 338562306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_SIZE; 338662306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_SIZE; 338762306a36Sopenharmony_ci } 338862306a36Sopenharmony_ci dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); 338962306a36Sopenharmony_ci return ret; 339062306a36Sopenharmony_ci} 339162306a36Sopenharmony_ci 339262306a36Sopenharmony_cistatic int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 339362306a36Sopenharmony_ci{ 339462306a36Sopenharmony_ci __be32 *p; 339562306a36Sopenharmony_ci 339662306a36Sopenharmony_ci *res = 0; 339762306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) 339862306a36Sopenharmony_ci return -EIO; 339962306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { 340062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 340162306a36Sopenharmony_ci if (unlikely(!p)) 340262306a36Sopenharmony_ci return -EIO; 340362306a36Sopenharmony_ci *res = be32_to_cpup(p); 340462306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; 340562306a36Sopenharmony_ci } 340662306a36Sopenharmony_ci dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); 340762306a36Sopenharmony_ci return 0; 340862306a36Sopenharmony_ci} 340962306a36Sopenharmony_ci 341062306a36Sopenharmony_cistatic int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 341162306a36Sopenharmony_ci{ 341262306a36Sopenharmony_ci __be32 *p; 341362306a36Sopenharmony_ci 341462306a36Sopenharmony_ci *res = 0; 341562306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) 341662306a36Sopenharmony_ci return -EIO; 341762306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { 341862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 341962306a36Sopenharmony_ci if (unlikely(!p)) 342062306a36Sopenharmony_ci return -EIO; 342162306a36Sopenharmony_ci *res = be32_to_cpup(p); 342262306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; 342362306a36Sopenharmony_ci } 342462306a36Sopenharmony_ci dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); 342562306a36Sopenharmony_ci return 0; 342662306a36Sopenharmony_ci} 342762306a36Sopenharmony_ci 342862306a36Sopenharmony_cistatic int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) 342962306a36Sopenharmony_ci{ 343062306a36Sopenharmony_ci __be32 *p; 343162306a36Sopenharmony_ci int ret = 0; 343262306a36Sopenharmony_ci 343362306a36Sopenharmony_ci fsid->major = 0; 343462306a36Sopenharmony_ci fsid->minor = 0; 343562306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U))) 343662306a36Sopenharmony_ci return -EIO; 343762306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { 343862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 16); 343962306a36Sopenharmony_ci if (unlikely(!p)) 344062306a36Sopenharmony_ci return -EIO; 344162306a36Sopenharmony_ci p = xdr_decode_hyper(p, &fsid->major); 344262306a36Sopenharmony_ci xdr_decode_hyper(p, &fsid->minor); 344362306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FSID; 344462306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_FSID; 344562306a36Sopenharmony_ci } 344662306a36Sopenharmony_ci dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __func__, 344762306a36Sopenharmony_ci (unsigned long long)fsid->major, 344862306a36Sopenharmony_ci (unsigned long long)fsid->minor); 344962306a36Sopenharmony_ci return ret; 345062306a36Sopenharmony_ci} 345162306a36Sopenharmony_ci 345262306a36Sopenharmony_cistatic int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 345362306a36Sopenharmony_ci{ 345462306a36Sopenharmony_ci __be32 *p; 345562306a36Sopenharmony_ci 345662306a36Sopenharmony_ci *res = 60; 345762306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) 345862306a36Sopenharmony_ci return -EIO; 345962306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { 346062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 346162306a36Sopenharmony_ci if (unlikely(!p)) 346262306a36Sopenharmony_ci return -EIO; 346362306a36Sopenharmony_ci *res = be32_to_cpup(p); 346462306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; 346562306a36Sopenharmony_ci } 346662306a36Sopenharmony_ci dprintk("%s: lease time=%u\n", __func__, (unsigned int)*res); 346762306a36Sopenharmony_ci return 0; 346862306a36Sopenharmony_ci} 346962306a36Sopenharmony_ci 347062306a36Sopenharmony_cistatic int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res) 347162306a36Sopenharmony_ci{ 347262306a36Sopenharmony_ci __be32 *p; 347362306a36Sopenharmony_ci 347462306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_RDATTR_ERROR - 1U))) 347562306a36Sopenharmony_ci return -EIO; 347662306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) { 347762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 347862306a36Sopenharmony_ci if (unlikely(!p)) 347962306a36Sopenharmony_ci return -EIO; 348062306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; 348162306a36Sopenharmony_ci *res = -be32_to_cpup(p); 348262306a36Sopenharmony_ci } 348362306a36Sopenharmony_ci return 0; 348462306a36Sopenharmony_ci} 348562306a36Sopenharmony_ci 348662306a36Sopenharmony_cistatic int decode_attr_exclcreat_supported(struct xdr_stream *xdr, 348762306a36Sopenharmony_ci uint32_t *bitmap, uint32_t *bitmask) 348862306a36Sopenharmony_ci{ 348962306a36Sopenharmony_ci if (likely(bitmap[2] & FATTR4_WORD2_SUPPATTR_EXCLCREAT)) { 349062306a36Sopenharmony_ci int ret; 349162306a36Sopenharmony_ci ret = decode_attr_bitmap(xdr, bitmask); 349262306a36Sopenharmony_ci if (unlikely(ret < 0)) 349362306a36Sopenharmony_ci return ret; 349462306a36Sopenharmony_ci bitmap[2] &= ~FATTR4_WORD2_SUPPATTR_EXCLCREAT; 349562306a36Sopenharmony_ci } else 349662306a36Sopenharmony_ci bitmask[0] = bitmask[1] = bitmask[2] = 0; 349762306a36Sopenharmony_ci dprintk("%s: bitmask=%08x:%08x:%08x\n", __func__, 349862306a36Sopenharmony_ci bitmask[0], bitmask[1], bitmask[2]); 349962306a36Sopenharmony_ci return 0; 350062306a36Sopenharmony_ci} 350162306a36Sopenharmony_ci 350262306a36Sopenharmony_cistatic int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fh *fh) 350362306a36Sopenharmony_ci{ 350462306a36Sopenharmony_ci __be32 *p; 350562306a36Sopenharmony_ci u32 len; 350662306a36Sopenharmony_ci 350762306a36Sopenharmony_ci if (fh != NULL) 350862306a36Sopenharmony_ci memset(fh, 0, sizeof(*fh)); 350962306a36Sopenharmony_ci 351062306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEHANDLE - 1U))) 351162306a36Sopenharmony_ci return -EIO; 351262306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) { 351362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 351462306a36Sopenharmony_ci if (unlikely(!p)) 351562306a36Sopenharmony_ci return -EIO; 351662306a36Sopenharmony_ci len = be32_to_cpup(p); 351762306a36Sopenharmony_ci if (len > NFS4_FHSIZE || len == 0) { 351862306a36Sopenharmony_ci trace_nfs4_xdr_bad_filehandle(xdr, OP_READDIR, 351962306a36Sopenharmony_ci NFS4ERR_BADHANDLE); 352062306a36Sopenharmony_ci return -EREMOTEIO; 352162306a36Sopenharmony_ci } 352262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, len); 352362306a36Sopenharmony_ci if (unlikely(!p)) 352462306a36Sopenharmony_ci return -EIO; 352562306a36Sopenharmony_ci if (fh != NULL) { 352662306a36Sopenharmony_ci memcpy(fh->data, p, len); 352762306a36Sopenharmony_ci fh->size = len; 352862306a36Sopenharmony_ci } 352962306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE; 353062306a36Sopenharmony_ci } 353162306a36Sopenharmony_ci return 0; 353262306a36Sopenharmony_ci} 353362306a36Sopenharmony_ci 353462306a36Sopenharmony_cistatic int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 353562306a36Sopenharmony_ci{ 353662306a36Sopenharmony_ci __be32 *p; 353762306a36Sopenharmony_ci 353862306a36Sopenharmony_ci *res = 0; 353962306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) 354062306a36Sopenharmony_ci return -EIO; 354162306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { 354262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 354362306a36Sopenharmony_ci if (unlikely(!p)) 354462306a36Sopenharmony_ci return -EIO; 354562306a36Sopenharmony_ci *res = be32_to_cpup(p); 354662306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; 354762306a36Sopenharmony_ci } 354862306a36Sopenharmony_ci dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); 354962306a36Sopenharmony_ci return 0; 355062306a36Sopenharmony_ci} 355162306a36Sopenharmony_ci 355262306a36Sopenharmony_cistatic int decode_attr_case_insensitive(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 355362306a36Sopenharmony_ci{ 355462306a36Sopenharmony_ci __be32 *p; 355562306a36Sopenharmony_ci 355662306a36Sopenharmony_ci *res = 0; 355762306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_INSENSITIVE - 1U))) 355862306a36Sopenharmony_ci return -EIO; 355962306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_CASE_INSENSITIVE)) { 356062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 356162306a36Sopenharmony_ci if (unlikely(!p)) 356262306a36Sopenharmony_ci return -EIO; 356362306a36Sopenharmony_ci *res = be32_to_cpup(p); 356462306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_CASE_INSENSITIVE; 356562306a36Sopenharmony_ci } 356662306a36Sopenharmony_ci dprintk("%s: case_insensitive=%s\n", __func__, *res == 0 ? "false" : "true"); 356762306a36Sopenharmony_ci return 0; 356862306a36Sopenharmony_ci} 356962306a36Sopenharmony_ci 357062306a36Sopenharmony_cistatic int decode_attr_case_preserving(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 357162306a36Sopenharmony_ci{ 357262306a36Sopenharmony_ci __be32 *p; 357362306a36Sopenharmony_ci 357462306a36Sopenharmony_ci *res = 0; 357562306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_CASE_PRESERVING - 1U))) 357662306a36Sopenharmony_ci return -EIO; 357762306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_CASE_PRESERVING)) { 357862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 357962306a36Sopenharmony_ci if (unlikely(!p)) 358062306a36Sopenharmony_ci return -EIO; 358162306a36Sopenharmony_ci *res = be32_to_cpup(p); 358262306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_CASE_PRESERVING; 358362306a36Sopenharmony_ci } 358462306a36Sopenharmony_ci dprintk("%s: case_preserving=%s\n", __func__, *res == 0 ? "false" : "true"); 358562306a36Sopenharmony_ci return 0; 358662306a36Sopenharmony_ci} 358762306a36Sopenharmony_ci 358862306a36Sopenharmony_cistatic int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) 358962306a36Sopenharmony_ci{ 359062306a36Sopenharmony_ci __be32 *p; 359162306a36Sopenharmony_ci int ret = 0; 359262306a36Sopenharmony_ci 359362306a36Sopenharmony_ci *fileid = 0; 359462306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) 359562306a36Sopenharmony_ci return -EIO; 359662306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { 359762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 359862306a36Sopenharmony_ci if (unlikely(!p)) 359962306a36Sopenharmony_ci return -EIO; 360062306a36Sopenharmony_ci xdr_decode_hyper(p, fileid); 360162306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FILEID; 360262306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_FILEID; 360362306a36Sopenharmony_ci } 360462306a36Sopenharmony_ci dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); 360562306a36Sopenharmony_ci return ret; 360662306a36Sopenharmony_ci} 360762306a36Sopenharmony_ci 360862306a36Sopenharmony_cistatic int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) 360962306a36Sopenharmony_ci{ 361062306a36Sopenharmony_ci __be32 *p; 361162306a36Sopenharmony_ci int ret = 0; 361262306a36Sopenharmony_ci 361362306a36Sopenharmony_ci *fileid = 0; 361462306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) 361562306a36Sopenharmony_ci return -EIO; 361662306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { 361762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 361862306a36Sopenharmony_ci if (unlikely(!p)) 361962306a36Sopenharmony_ci return -EIO; 362062306a36Sopenharmony_ci xdr_decode_hyper(p, fileid); 362162306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; 362262306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID; 362362306a36Sopenharmony_ci } 362462306a36Sopenharmony_ci dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); 362562306a36Sopenharmony_ci return ret; 362662306a36Sopenharmony_ci} 362762306a36Sopenharmony_ci 362862306a36Sopenharmony_cistatic int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 362962306a36Sopenharmony_ci{ 363062306a36Sopenharmony_ci __be32 *p; 363162306a36Sopenharmony_ci int status = 0; 363262306a36Sopenharmony_ci 363362306a36Sopenharmony_ci *res = 0; 363462306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U))) 363562306a36Sopenharmony_ci return -EIO; 363662306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { 363762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 363862306a36Sopenharmony_ci if (unlikely(!p)) 363962306a36Sopenharmony_ci return -EIO; 364062306a36Sopenharmony_ci xdr_decode_hyper(p, res); 364162306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; 364262306a36Sopenharmony_ci } 364362306a36Sopenharmony_ci dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); 364462306a36Sopenharmony_ci return status; 364562306a36Sopenharmony_ci} 364662306a36Sopenharmony_ci 364762306a36Sopenharmony_cistatic int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 364862306a36Sopenharmony_ci{ 364962306a36Sopenharmony_ci __be32 *p; 365062306a36Sopenharmony_ci int status = 0; 365162306a36Sopenharmony_ci 365262306a36Sopenharmony_ci *res = 0; 365362306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U))) 365462306a36Sopenharmony_ci return -EIO; 365562306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { 365662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 365762306a36Sopenharmony_ci if (unlikely(!p)) 365862306a36Sopenharmony_ci return -EIO; 365962306a36Sopenharmony_ci xdr_decode_hyper(p, res); 366062306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; 366162306a36Sopenharmony_ci } 366262306a36Sopenharmony_ci dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); 366362306a36Sopenharmony_ci return status; 366462306a36Sopenharmony_ci} 366562306a36Sopenharmony_ci 366662306a36Sopenharmony_cistatic int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 366762306a36Sopenharmony_ci{ 366862306a36Sopenharmony_ci __be32 *p; 366962306a36Sopenharmony_ci int status = 0; 367062306a36Sopenharmony_ci 367162306a36Sopenharmony_ci *res = 0; 367262306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U))) 367362306a36Sopenharmony_ci return -EIO; 367462306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { 367562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 367662306a36Sopenharmony_ci if (unlikely(!p)) 367762306a36Sopenharmony_ci return -EIO; 367862306a36Sopenharmony_ci xdr_decode_hyper(p, res); 367962306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; 368062306a36Sopenharmony_ci } 368162306a36Sopenharmony_ci dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); 368262306a36Sopenharmony_ci return status; 368362306a36Sopenharmony_ci} 368462306a36Sopenharmony_ci 368562306a36Sopenharmony_cistatic int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) 368662306a36Sopenharmony_ci{ 368762306a36Sopenharmony_ci u32 n; 368862306a36Sopenharmony_ci __be32 *p; 368962306a36Sopenharmony_ci int status = 0; 369062306a36Sopenharmony_ci 369162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 369262306a36Sopenharmony_ci if (unlikely(!p)) 369362306a36Sopenharmony_ci return -EIO; 369462306a36Sopenharmony_ci n = be32_to_cpup(p); 369562306a36Sopenharmony_ci if (n == 0) 369662306a36Sopenharmony_ci goto root_path; 369762306a36Sopenharmony_ci dprintk("pathname4: "); 369862306a36Sopenharmony_ci if (n > NFS4_PATHNAME_MAXCOMPONENTS) { 369962306a36Sopenharmony_ci dprintk("cannot parse %d components in path\n", n); 370062306a36Sopenharmony_ci goto out_eio; 370162306a36Sopenharmony_ci } 370262306a36Sopenharmony_ci for (path->ncomponents = 0; path->ncomponents < n; path->ncomponents++) { 370362306a36Sopenharmony_ci struct nfs4_string *component = &path->components[path->ncomponents]; 370462306a36Sopenharmony_ci status = decode_opaque_inline(xdr, &component->len, &component->data); 370562306a36Sopenharmony_ci if (unlikely(status != 0)) 370662306a36Sopenharmony_ci goto out_eio; 370762306a36Sopenharmony_ci ifdebug (XDR) 370862306a36Sopenharmony_ci pr_cont("%s%.*s ", 370962306a36Sopenharmony_ci (path->ncomponents != n ? "/ " : ""), 371062306a36Sopenharmony_ci component->len, component->data); 371162306a36Sopenharmony_ci } 371262306a36Sopenharmony_ciout: 371362306a36Sopenharmony_ci return status; 371462306a36Sopenharmony_ciroot_path: 371562306a36Sopenharmony_ci/* a root pathname is sent as a zero component4 */ 371662306a36Sopenharmony_ci path->ncomponents = 1; 371762306a36Sopenharmony_ci path->components[0].len=0; 371862306a36Sopenharmony_ci path->components[0].data=NULL; 371962306a36Sopenharmony_ci dprintk("pathname4: /\n"); 372062306a36Sopenharmony_ci goto out; 372162306a36Sopenharmony_ciout_eio: 372262306a36Sopenharmony_ci dprintk(" status %d", status); 372362306a36Sopenharmony_ci status = -EIO; 372462306a36Sopenharmony_ci goto out; 372562306a36Sopenharmony_ci} 372662306a36Sopenharmony_ci 372762306a36Sopenharmony_cistatic int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) 372862306a36Sopenharmony_ci{ 372962306a36Sopenharmony_ci int n; 373062306a36Sopenharmony_ci __be32 *p; 373162306a36Sopenharmony_ci int status = -EIO; 373262306a36Sopenharmony_ci 373362306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U))) 373462306a36Sopenharmony_ci goto out; 373562306a36Sopenharmony_ci status = 0; 373662306a36Sopenharmony_ci if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS))) 373762306a36Sopenharmony_ci goto out; 373862306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_FS_LOCATIONS; 373962306a36Sopenharmony_ci status = -EIO; 374062306a36Sopenharmony_ci /* Ignore borken servers that return unrequested attrs */ 374162306a36Sopenharmony_ci if (unlikely(res == NULL)) 374262306a36Sopenharmony_ci goto out; 374362306a36Sopenharmony_ci dprintk("%s: fsroot:\n", __func__); 374462306a36Sopenharmony_ci status = decode_pathname(xdr, &res->fs_path); 374562306a36Sopenharmony_ci if (unlikely(status != 0)) 374662306a36Sopenharmony_ci goto out; 374762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 374862306a36Sopenharmony_ci if (unlikely(!p)) 374962306a36Sopenharmony_ci goto out_eio; 375062306a36Sopenharmony_ci n = be32_to_cpup(p); 375162306a36Sopenharmony_ci for (res->nlocations = 0; res->nlocations < n; res->nlocations++) { 375262306a36Sopenharmony_ci u32 m; 375362306a36Sopenharmony_ci struct nfs4_fs_location *loc; 375462306a36Sopenharmony_ci 375562306a36Sopenharmony_ci if (res->nlocations == NFS4_FS_LOCATIONS_MAXENTRIES) 375662306a36Sopenharmony_ci break; 375762306a36Sopenharmony_ci loc = &res->locations[res->nlocations]; 375862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 375962306a36Sopenharmony_ci if (unlikely(!p)) 376062306a36Sopenharmony_ci goto out_eio; 376162306a36Sopenharmony_ci m = be32_to_cpup(p); 376262306a36Sopenharmony_ci 376362306a36Sopenharmony_ci dprintk("%s: servers:\n", __func__); 376462306a36Sopenharmony_ci for (loc->nservers = 0; loc->nservers < m; loc->nservers++) { 376562306a36Sopenharmony_ci struct nfs4_string *server; 376662306a36Sopenharmony_ci 376762306a36Sopenharmony_ci if (loc->nservers == NFS4_FS_LOCATION_MAXSERVERS) { 376862306a36Sopenharmony_ci unsigned int i; 376962306a36Sopenharmony_ci dprintk("%s: using first %u of %u servers " 377062306a36Sopenharmony_ci "returned for location %u\n", 377162306a36Sopenharmony_ci __func__, 377262306a36Sopenharmony_ci NFS4_FS_LOCATION_MAXSERVERS, 377362306a36Sopenharmony_ci m, res->nlocations); 377462306a36Sopenharmony_ci for (i = loc->nservers; i < m; i++) { 377562306a36Sopenharmony_ci unsigned int len; 377662306a36Sopenharmony_ci char *data; 377762306a36Sopenharmony_ci status = decode_opaque_inline(xdr, &len, &data); 377862306a36Sopenharmony_ci if (unlikely(status != 0)) 377962306a36Sopenharmony_ci goto out_eio; 378062306a36Sopenharmony_ci } 378162306a36Sopenharmony_ci break; 378262306a36Sopenharmony_ci } 378362306a36Sopenharmony_ci server = &loc->servers[loc->nservers]; 378462306a36Sopenharmony_ci status = decode_opaque_inline(xdr, &server->len, &server->data); 378562306a36Sopenharmony_ci if (unlikely(status != 0)) 378662306a36Sopenharmony_ci goto out_eio; 378762306a36Sopenharmony_ci dprintk("%s ", server->data); 378862306a36Sopenharmony_ci } 378962306a36Sopenharmony_ci status = decode_pathname(xdr, &loc->rootpath); 379062306a36Sopenharmony_ci if (unlikely(status != 0)) 379162306a36Sopenharmony_ci goto out_eio; 379262306a36Sopenharmony_ci } 379362306a36Sopenharmony_ci if (res->nlocations != 0) 379462306a36Sopenharmony_ci status = NFS_ATTR_FATTR_V4_LOCATIONS; 379562306a36Sopenharmony_ciout: 379662306a36Sopenharmony_ci dprintk("%s: fs_locations done, error = %d\n", __func__, status); 379762306a36Sopenharmony_ci return status; 379862306a36Sopenharmony_ciout_eio: 379962306a36Sopenharmony_ci status = -EIO; 380062306a36Sopenharmony_ci goto out; 380162306a36Sopenharmony_ci} 380262306a36Sopenharmony_ci 380362306a36Sopenharmony_cistatic int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 380462306a36Sopenharmony_ci{ 380562306a36Sopenharmony_ci __be32 *p; 380662306a36Sopenharmony_ci int status = 0; 380762306a36Sopenharmony_ci 380862306a36Sopenharmony_ci *res = 0; 380962306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U))) 381062306a36Sopenharmony_ci return -EIO; 381162306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { 381262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 381362306a36Sopenharmony_ci if (unlikely(!p)) 381462306a36Sopenharmony_ci return -EIO; 381562306a36Sopenharmony_ci xdr_decode_hyper(p, res); 381662306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; 381762306a36Sopenharmony_ci } 381862306a36Sopenharmony_ci dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); 381962306a36Sopenharmony_ci return status; 382062306a36Sopenharmony_ci} 382162306a36Sopenharmony_ci 382262306a36Sopenharmony_cistatic int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) 382362306a36Sopenharmony_ci{ 382462306a36Sopenharmony_ci __be32 *p; 382562306a36Sopenharmony_ci int status = 0; 382662306a36Sopenharmony_ci 382762306a36Sopenharmony_ci *maxlink = 1; 382862306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U))) 382962306a36Sopenharmony_ci return -EIO; 383062306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { 383162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 383262306a36Sopenharmony_ci if (unlikely(!p)) 383362306a36Sopenharmony_ci return -EIO; 383462306a36Sopenharmony_ci *maxlink = be32_to_cpup(p); 383562306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_MAXLINK; 383662306a36Sopenharmony_ci } 383762306a36Sopenharmony_ci dprintk("%s: maxlink=%u\n", __func__, *maxlink); 383862306a36Sopenharmony_ci return status; 383962306a36Sopenharmony_ci} 384062306a36Sopenharmony_ci 384162306a36Sopenharmony_cistatic int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) 384262306a36Sopenharmony_ci{ 384362306a36Sopenharmony_ci __be32 *p; 384462306a36Sopenharmony_ci int status = 0; 384562306a36Sopenharmony_ci 384662306a36Sopenharmony_ci *maxname = 1024; 384762306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U))) 384862306a36Sopenharmony_ci return -EIO; 384962306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { 385062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 385162306a36Sopenharmony_ci if (unlikely(!p)) 385262306a36Sopenharmony_ci return -EIO; 385362306a36Sopenharmony_ci *maxname = be32_to_cpup(p); 385462306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_MAXNAME; 385562306a36Sopenharmony_ci } 385662306a36Sopenharmony_ci dprintk("%s: maxname=%u\n", __func__, *maxname); 385762306a36Sopenharmony_ci return status; 385862306a36Sopenharmony_ci} 385962306a36Sopenharmony_ci 386062306a36Sopenharmony_cistatic int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 386162306a36Sopenharmony_ci{ 386262306a36Sopenharmony_ci __be32 *p; 386362306a36Sopenharmony_ci int status = 0; 386462306a36Sopenharmony_ci 386562306a36Sopenharmony_ci *res = 1024; 386662306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXREAD - 1U))) 386762306a36Sopenharmony_ci return -EIO; 386862306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) { 386962306a36Sopenharmony_ci uint64_t maxread; 387062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 387162306a36Sopenharmony_ci if (unlikely(!p)) 387262306a36Sopenharmony_ci return -EIO; 387362306a36Sopenharmony_ci xdr_decode_hyper(p, &maxread); 387462306a36Sopenharmony_ci if (maxread > 0x7FFFFFFF) 387562306a36Sopenharmony_ci maxread = 0x7FFFFFFF; 387662306a36Sopenharmony_ci *res = (uint32_t)maxread; 387762306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_MAXREAD; 387862306a36Sopenharmony_ci } 387962306a36Sopenharmony_ci dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); 388062306a36Sopenharmony_ci return status; 388162306a36Sopenharmony_ci} 388262306a36Sopenharmony_ci 388362306a36Sopenharmony_cistatic int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) 388462306a36Sopenharmony_ci{ 388562306a36Sopenharmony_ci __be32 *p; 388662306a36Sopenharmony_ci int status = 0; 388762306a36Sopenharmony_ci 388862306a36Sopenharmony_ci *res = 1024; 388962306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXWRITE - 1U))) 389062306a36Sopenharmony_ci return -EIO; 389162306a36Sopenharmony_ci if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) { 389262306a36Sopenharmony_ci uint64_t maxwrite; 389362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 389462306a36Sopenharmony_ci if (unlikely(!p)) 389562306a36Sopenharmony_ci return -EIO; 389662306a36Sopenharmony_ci xdr_decode_hyper(p, &maxwrite); 389762306a36Sopenharmony_ci if (maxwrite > 0x7FFFFFFF) 389862306a36Sopenharmony_ci maxwrite = 0x7FFFFFFF; 389962306a36Sopenharmony_ci *res = (uint32_t)maxwrite; 390062306a36Sopenharmony_ci bitmap[0] &= ~FATTR4_WORD0_MAXWRITE; 390162306a36Sopenharmony_ci } 390262306a36Sopenharmony_ci dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); 390362306a36Sopenharmony_ci return status; 390462306a36Sopenharmony_ci} 390562306a36Sopenharmony_ci 390662306a36Sopenharmony_cistatic int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) 390762306a36Sopenharmony_ci{ 390862306a36Sopenharmony_ci uint32_t tmp; 390962306a36Sopenharmony_ci __be32 *p; 391062306a36Sopenharmony_ci int ret = 0; 391162306a36Sopenharmony_ci 391262306a36Sopenharmony_ci *mode = 0; 391362306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U))) 391462306a36Sopenharmony_ci return -EIO; 391562306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { 391662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 391762306a36Sopenharmony_ci if (unlikely(!p)) 391862306a36Sopenharmony_ci return -EIO; 391962306a36Sopenharmony_ci tmp = be32_to_cpup(p); 392062306a36Sopenharmony_ci *mode = tmp & ~S_IFMT; 392162306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_MODE; 392262306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_MODE; 392362306a36Sopenharmony_ci } 392462306a36Sopenharmony_ci dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); 392562306a36Sopenharmony_ci return ret; 392662306a36Sopenharmony_ci} 392762306a36Sopenharmony_ci 392862306a36Sopenharmony_cistatic int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) 392962306a36Sopenharmony_ci{ 393062306a36Sopenharmony_ci __be32 *p; 393162306a36Sopenharmony_ci int ret = 0; 393262306a36Sopenharmony_ci 393362306a36Sopenharmony_ci *nlink = 1; 393462306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U))) 393562306a36Sopenharmony_ci return -EIO; 393662306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { 393762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 393862306a36Sopenharmony_ci if (unlikely(!p)) 393962306a36Sopenharmony_ci return -EIO; 394062306a36Sopenharmony_ci *nlink = be32_to_cpup(p); 394162306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; 394262306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_NLINK; 394362306a36Sopenharmony_ci } 394462306a36Sopenharmony_ci dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); 394562306a36Sopenharmony_ci return ret; 394662306a36Sopenharmony_ci} 394762306a36Sopenharmony_ci 394862306a36Sopenharmony_cistatic ssize_t decode_nfs4_string(struct xdr_stream *xdr, 394962306a36Sopenharmony_ci struct nfs4_string *name, gfp_t gfp_flags) 395062306a36Sopenharmony_ci{ 395162306a36Sopenharmony_ci ssize_t ret; 395262306a36Sopenharmony_ci 395362306a36Sopenharmony_ci ret = xdr_stream_decode_string_dup(xdr, &name->data, 395462306a36Sopenharmony_ci XDR_MAX_NETOBJ, gfp_flags); 395562306a36Sopenharmony_ci name->len = 0; 395662306a36Sopenharmony_ci if (ret > 0) 395762306a36Sopenharmony_ci name->len = ret; 395862306a36Sopenharmony_ci return ret; 395962306a36Sopenharmony_ci} 396062306a36Sopenharmony_ci 396162306a36Sopenharmony_cistatic int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, 396262306a36Sopenharmony_ci const struct nfs_server *server, kuid_t *uid, 396362306a36Sopenharmony_ci struct nfs4_string *owner_name) 396462306a36Sopenharmony_ci{ 396562306a36Sopenharmony_ci ssize_t len; 396662306a36Sopenharmony_ci char *p; 396762306a36Sopenharmony_ci 396862306a36Sopenharmony_ci *uid = make_kuid(&init_user_ns, -2); 396962306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) 397062306a36Sopenharmony_ci return -EIO; 397162306a36Sopenharmony_ci if (!(bitmap[1] & FATTR4_WORD1_OWNER)) 397262306a36Sopenharmony_ci return 0; 397362306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_OWNER; 397462306a36Sopenharmony_ci 397562306a36Sopenharmony_ci if (owner_name != NULL) { 397662306a36Sopenharmony_ci len = decode_nfs4_string(xdr, owner_name, GFP_NOIO); 397762306a36Sopenharmony_ci if (len <= 0) 397862306a36Sopenharmony_ci goto out; 397962306a36Sopenharmony_ci dprintk("%s: name=%s\n", __func__, owner_name->data); 398062306a36Sopenharmony_ci return NFS_ATTR_FATTR_OWNER_NAME; 398162306a36Sopenharmony_ci } else { 398262306a36Sopenharmony_ci len = xdr_stream_decode_opaque_inline(xdr, (void **)&p, 398362306a36Sopenharmony_ci XDR_MAX_NETOBJ); 398462306a36Sopenharmony_ci if (len <= 0 || nfs_map_name_to_uid(server, p, len, uid) != 0) 398562306a36Sopenharmony_ci goto out; 398662306a36Sopenharmony_ci dprintk("%s: uid=%d\n", __func__, (int)from_kuid(&init_user_ns, *uid)); 398762306a36Sopenharmony_ci return NFS_ATTR_FATTR_OWNER; 398862306a36Sopenharmony_ci } 398962306a36Sopenharmony_ciout: 399062306a36Sopenharmony_ci if (len == -EBADMSG) 399162306a36Sopenharmony_ci return -EIO; 399262306a36Sopenharmony_ci return 0; 399362306a36Sopenharmony_ci} 399462306a36Sopenharmony_ci 399562306a36Sopenharmony_cistatic int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, 399662306a36Sopenharmony_ci const struct nfs_server *server, kgid_t *gid, 399762306a36Sopenharmony_ci struct nfs4_string *group_name) 399862306a36Sopenharmony_ci{ 399962306a36Sopenharmony_ci ssize_t len; 400062306a36Sopenharmony_ci char *p; 400162306a36Sopenharmony_ci 400262306a36Sopenharmony_ci *gid = make_kgid(&init_user_ns, -2); 400362306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) 400462306a36Sopenharmony_ci return -EIO; 400562306a36Sopenharmony_ci if (!(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) 400662306a36Sopenharmony_ci return 0; 400762306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP; 400862306a36Sopenharmony_ci 400962306a36Sopenharmony_ci if (group_name != NULL) { 401062306a36Sopenharmony_ci len = decode_nfs4_string(xdr, group_name, GFP_NOIO); 401162306a36Sopenharmony_ci if (len <= 0) 401262306a36Sopenharmony_ci goto out; 401362306a36Sopenharmony_ci dprintk("%s: name=%s\n", __func__, group_name->data); 401462306a36Sopenharmony_ci return NFS_ATTR_FATTR_GROUP_NAME; 401562306a36Sopenharmony_ci } else { 401662306a36Sopenharmony_ci len = xdr_stream_decode_opaque_inline(xdr, (void **)&p, 401762306a36Sopenharmony_ci XDR_MAX_NETOBJ); 401862306a36Sopenharmony_ci if (len <= 0 || nfs_map_group_to_gid(server, p, len, gid) != 0) 401962306a36Sopenharmony_ci goto out; 402062306a36Sopenharmony_ci dprintk("%s: gid=%d\n", __func__, (int)from_kgid(&init_user_ns, *gid)); 402162306a36Sopenharmony_ci return NFS_ATTR_FATTR_GROUP; 402262306a36Sopenharmony_ci } 402362306a36Sopenharmony_ciout: 402462306a36Sopenharmony_ci if (len == -EBADMSG) 402562306a36Sopenharmony_ci return -EIO; 402662306a36Sopenharmony_ci return 0; 402762306a36Sopenharmony_ci} 402862306a36Sopenharmony_ci 402962306a36Sopenharmony_cistatic int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) 403062306a36Sopenharmony_ci{ 403162306a36Sopenharmony_ci uint32_t major = 0, minor = 0; 403262306a36Sopenharmony_ci __be32 *p; 403362306a36Sopenharmony_ci int ret = 0; 403462306a36Sopenharmony_ci 403562306a36Sopenharmony_ci *rdev = MKDEV(0,0); 403662306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U))) 403762306a36Sopenharmony_ci return -EIO; 403862306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) { 403962306a36Sopenharmony_ci dev_t tmp; 404062306a36Sopenharmony_ci 404162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 404262306a36Sopenharmony_ci if (unlikely(!p)) 404362306a36Sopenharmony_ci return -EIO; 404462306a36Sopenharmony_ci major = be32_to_cpup(p++); 404562306a36Sopenharmony_ci minor = be32_to_cpup(p); 404662306a36Sopenharmony_ci tmp = MKDEV(major, minor); 404762306a36Sopenharmony_ci if (MAJOR(tmp) == major && MINOR(tmp) == minor) 404862306a36Sopenharmony_ci *rdev = tmp; 404962306a36Sopenharmony_ci bitmap[1] &= ~ FATTR4_WORD1_RAWDEV; 405062306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_RDEV; 405162306a36Sopenharmony_ci } 405262306a36Sopenharmony_ci dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); 405362306a36Sopenharmony_ci return ret; 405462306a36Sopenharmony_ci} 405562306a36Sopenharmony_ci 405662306a36Sopenharmony_cistatic int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 405762306a36Sopenharmony_ci{ 405862306a36Sopenharmony_ci __be32 *p; 405962306a36Sopenharmony_ci int status = 0; 406062306a36Sopenharmony_ci 406162306a36Sopenharmony_ci *res = 0; 406262306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U))) 406362306a36Sopenharmony_ci return -EIO; 406462306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { 406562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 406662306a36Sopenharmony_ci if (unlikely(!p)) 406762306a36Sopenharmony_ci return -EIO; 406862306a36Sopenharmony_ci xdr_decode_hyper(p, res); 406962306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; 407062306a36Sopenharmony_ci } 407162306a36Sopenharmony_ci dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); 407262306a36Sopenharmony_ci return status; 407362306a36Sopenharmony_ci} 407462306a36Sopenharmony_ci 407562306a36Sopenharmony_cistatic int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 407662306a36Sopenharmony_ci{ 407762306a36Sopenharmony_ci __be32 *p; 407862306a36Sopenharmony_ci int status = 0; 407962306a36Sopenharmony_ci 408062306a36Sopenharmony_ci *res = 0; 408162306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U))) 408262306a36Sopenharmony_ci return -EIO; 408362306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { 408462306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 408562306a36Sopenharmony_ci if (unlikely(!p)) 408662306a36Sopenharmony_ci return -EIO; 408762306a36Sopenharmony_ci xdr_decode_hyper(p, res); 408862306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; 408962306a36Sopenharmony_ci } 409062306a36Sopenharmony_ci dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); 409162306a36Sopenharmony_ci return status; 409262306a36Sopenharmony_ci} 409362306a36Sopenharmony_ci 409462306a36Sopenharmony_cistatic int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) 409562306a36Sopenharmony_ci{ 409662306a36Sopenharmony_ci __be32 *p; 409762306a36Sopenharmony_ci int status = 0; 409862306a36Sopenharmony_ci 409962306a36Sopenharmony_ci *res = 0; 410062306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U))) 410162306a36Sopenharmony_ci return -EIO; 410262306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { 410362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 410462306a36Sopenharmony_ci if (unlikely(!p)) 410562306a36Sopenharmony_ci return -EIO; 410662306a36Sopenharmony_ci xdr_decode_hyper(p, res); 410762306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; 410862306a36Sopenharmony_ci } 410962306a36Sopenharmony_ci dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); 411062306a36Sopenharmony_ci return status; 411162306a36Sopenharmony_ci} 411262306a36Sopenharmony_ci 411362306a36Sopenharmony_cistatic int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) 411462306a36Sopenharmony_ci{ 411562306a36Sopenharmony_ci __be32 *p; 411662306a36Sopenharmony_ci int ret = 0; 411762306a36Sopenharmony_ci 411862306a36Sopenharmony_ci *used = 0; 411962306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U))) 412062306a36Sopenharmony_ci return -EIO; 412162306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { 412262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 412362306a36Sopenharmony_ci if (unlikely(!p)) 412462306a36Sopenharmony_ci return -EIO; 412562306a36Sopenharmony_ci xdr_decode_hyper(p, used); 412662306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; 412762306a36Sopenharmony_ci ret = NFS_ATTR_FATTR_SPACE_USED; 412862306a36Sopenharmony_ci } 412962306a36Sopenharmony_ci dprintk("%s: space used=%Lu\n", __func__, 413062306a36Sopenharmony_ci (unsigned long long)*used); 413162306a36Sopenharmony_ci return ret; 413262306a36Sopenharmony_ci} 413362306a36Sopenharmony_ci 413462306a36Sopenharmony_cistatic __be32 * 413562306a36Sopenharmony_cixdr_decode_nfstime4(__be32 *p, struct timespec64 *t) 413662306a36Sopenharmony_ci{ 413762306a36Sopenharmony_ci __u64 sec; 413862306a36Sopenharmony_ci 413962306a36Sopenharmony_ci p = xdr_decode_hyper(p, &sec); 414062306a36Sopenharmony_ci t-> tv_sec = sec; 414162306a36Sopenharmony_ci t->tv_nsec = be32_to_cpup(p++); 414262306a36Sopenharmony_ci return p; 414362306a36Sopenharmony_ci} 414462306a36Sopenharmony_ci 414562306a36Sopenharmony_cistatic int decode_attr_time(struct xdr_stream *xdr, struct timespec64 *time) 414662306a36Sopenharmony_ci{ 414762306a36Sopenharmony_ci __be32 *p; 414862306a36Sopenharmony_ci 414962306a36Sopenharmony_ci p = xdr_inline_decode(xdr, nfstime4_maxsz << 2); 415062306a36Sopenharmony_ci if (unlikely(!p)) 415162306a36Sopenharmony_ci return -EIO; 415262306a36Sopenharmony_ci xdr_decode_nfstime4(p, time); 415362306a36Sopenharmony_ci return 0; 415462306a36Sopenharmony_ci} 415562306a36Sopenharmony_ci 415662306a36Sopenharmony_cistatic int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time) 415762306a36Sopenharmony_ci{ 415862306a36Sopenharmony_ci int status = 0; 415962306a36Sopenharmony_ci 416062306a36Sopenharmony_ci time->tv_sec = 0; 416162306a36Sopenharmony_ci time->tv_nsec = 0; 416262306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_ACCESS - 1U))) 416362306a36Sopenharmony_ci return -EIO; 416462306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_TIME_ACCESS)) { 416562306a36Sopenharmony_ci status = decode_attr_time(xdr, time); 416662306a36Sopenharmony_ci if (status == 0) 416762306a36Sopenharmony_ci status = NFS_ATTR_FATTR_ATIME; 416862306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_TIME_ACCESS; 416962306a36Sopenharmony_ci } 417062306a36Sopenharmony_ci dprintk("%s: atime=%lld\n", __func__, time->tv_sec); 417162306a36Sopenharmony_ci return status; 417262306a36Sopenharmony_ci} 417362306a36Sopenharmony_ci 417462306a36Sopenharmony_cistatic int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time) 417562306a36Sopenharmony_ci{ 417662306a36Sopenharmony_ci int status = 0; 417762306a36Sopenharmony_ci 417862306a36Sopenharmony_ci time->tv_sec = 0; 417962306a36Sopenharmony_ci time->tv_nsec = 0; 418062306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_METADATA - 1U))) 418162306a36Sopenharmony_ci return -EIO; 418262306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) { 418362306a36Sopenharmony_ci status = decode_attr_time(xdr, time); 418462306a36Sopenharmony_ci if (status == 0) 418562306a36Sopenharmony_ci status = NFS_ATTR_FATTR_CTIME; 418662306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_TIME_METADATA; 418762306a36Sopenharmony_ci } 418862306a36Sopenharmony_ci dprintk("%s: ctime=%lld\n", __func__, time->tv_sec); 418962306a36Sopenharmony_ci return status; 419062306a36Sopenharmony_ci} 419162306a36Sopenharmony_ci 419262306a36Sopenharmony_cistatic int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap, 419362306a36Sopenharmony_ci struct timespec64 *time) 419462306a36Sopenharmony_ci{ 419562306a36Sopenharmony_ci int status = 0; 419662306a36Sopenharmony_ci 419762306a36Sopenharmony_ci time->tv_sec = 0; 419862306a36Sopenharmony_ci time->tv_nsec = 0; 419962306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_DELTA - 1U))) 420062306a36Sopenharmony_ci return -EIO; 420162306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_TIME_DELTA)) { 420262306a36Sopenharmony_ci status = decode_attr_time(xdr, time); 420362306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_TIME_DELTA; 420462306a36Sopenharmony_ci } 420562306a36Sopenharmony_ci dprintk("%s: time_delta=%lld %ld\n", __func__, time->tv_sec, 420662306a36Sopenharmony_ci time->tv_nsec); 420762306a36Sopenharmony_ci return status; 420862306a36Sopenharmony_ci} 420962306a36Sopenharmony_ci 421062306a36Sopenharmony_cistatic int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, 421162306a36Sopenharmony_ci struct nfs4_label *label) 421262306a36Sopenharmony_ci{ 421362306a36Sopenharmony_ci uint32_t pi = 0; 421462306a36Sopenharmony_ci uint32_t lfs = 0; 421562306a36Sopenharmony_ci __u32 len; 421662306a36Sopenharmony_ci __be32 *p; 421762306a36Sopenharmony_ci int status = 0; 421862306a36Sopenharmony_ci 421962306a36Sopenharmony_ci if (unlikely(bitmap[2] & (FATTR4_WORD2_SECURITY_LABEL - 1U))) 422062306a36Sopenharmony_ci return -EIO; 422162306a36Sopenharmony_ci if (likely(bitmap[2] & FATTR4_WORD2_SECURITY_LABEL)) { 422262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 422362306a36Sopenharmony_ci if (unlikely(!p)) 422462306a36Sopenharmony_ci return -EIO; 422562306a36Sopenharmony_ci lfs = be32_to_cpup(p++); 422662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 422762306a36Sopenharmony_ci if (unlikely(!p)) 422862306a36Sopenharmony_ci return -EIO; 422962306a36Sopenharmony_ci pi = be32_to_cpup(p++); 423062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 423162306a36Sopenharmony_ci if (unlikely(!p)) 423262306a36Sopenharmony_ci return -EIO; 423362306a36Sopenharmony_ci len = be32_to_cpup(p++); 423462306a36Sopenharmony_ci p = xdr_inline_decode(xdr, len); 423562306a36Sopenharmony_ci if (unlikely(!p)) 423662306a36Sopenharmony_ci return -EIO; 423762306a36Sopenharmony_ci bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL; 423862306a36Sopenharmony_ci if (len < NFS4_MAXLABELLEN) { 423962306a36Sopenharmony_ci if (label && label->len) { 424062306a36Sopenharmony_ci if (label->len < len) 424162306a36Sopenharmony_ci return -ERANGE; 424262306a36Sopenharmony_ci memcpy(label->label, p, len); 424362306a36Sopenharmony_ci label->len = len; 424462306a36Sopenharmony_ci label->pi = pi; 424562306a36Sopenharmony_ci label->lfs = lfs; 424662306a36Sopenharmony_ci status = NFS_ATTR_FATTR_V4_SECURITY_LABEL; 424762306a36Sopenharmony_ci } 424862306a36Sopenharmony_ci } else 424962306a36Sopenharmony_ci printk(KERN_WARNING "%s: label too long (%u)!\n", 425062306a36Sopenharmony_ci __func__, len); 425162306a36Sopenharmony_ci if (label && label->label) 425262306a36Sopenharmony_ci dprintk("%s: label=%.*s, len=%d, PI=%d, LFS=%d\n", 425362306a36Sopenharmony_ci __func__, label->len, (char *)label->label, 425462306a36Sopenharmony_ci label->len, label->pi, label->lfs); 425562306a36Sopenharmony_ci } 425662306a36Sopenharmony_ci return status; 425762306a36Sopenharmony_ci} 425862306a36Sopenharmony_ci 425962306a36Sopenharmony_cistatic int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time) 426062306a36Sopenharmony_ci{ 426162306a36Sopenharmony_ci int status = 0; 426262306a36Sopenharmony_ci 426362306a36Sopenharmony_ci time->tv_sec = 0; 426462306a36Sopenharmony_ci time->tv_nsec = 0; 426562306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_MODIFY - 1U))) 426662306a36Sopenharmony_ci return -EIO; 426762306a36Sopenharmony_ci if (likely(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) { 426862306a36Sopenharmony_ci status = decode_attr_time(xdr, time); 426962306a36Sopenharmony_ci if (status == 0) 427062306a36Sopenharmony_ci status = NFS_ATTR_FATTR_MTIME; 427162306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_TIME_MODIFY; 427262306a36Sopenharmony_ci } 427362306a36Sopenharmony_ci dprintk("%s: mtime=%lld\n", __func__, time->tv_sec); 427462306a36Sopenharmony_ci return status; 427562306a36Sopenharmony_ci} 427662306a36Sopenharmony_ci 427762306a36Sopenharmony_cistatic int decode_attr_xattrsupport(struct xdr_stream *xdr, uint32_t *bitmap, 427862306a36Sopenharmony_ci uint32_t *res) 427962306a36Sopenharmony_ci{ 428062306a36Sopenharmony_ci __be32 *p; 428162306a36Sopenharmony_ci 428262306a36Sopenharmony_ci *res = 0; 428362306a36Sopenharmony_ci if (unlikely(bitmap[2] & (FATTR4_WORD2_XATTR_SUPPORT - 1U))) 428462306a36Sopenharmony_ci return -EIO; 428562306a36Sopenharmony_ci if (likely(bitmap[2] & FATTR4_WORD2_XATTR_SUPPORT)) { 428662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 428762306a36Sopenharmony_ci if (unlikely(!p)) 428862306a36Sopenharmony_ci return -EIO; 428962306a36Sopenharmony_ci *res = be32_to_cpup(p); 429062306a36Sopenharmony_ci bitmap[2] &= ~FATTR4_WORD2_XATTR_SUPPORT; 429162306a36Sopenharmony_ci } 429262306a36Sopenharmony_ci dprintk("%s: XATTR support=%s\n", __func__, 429362306a36Sopenharmony_ci *res == 0 ? "false" : "true"); 429462306a36Sopenharmony_ci return 0; 429562306a36Sopenharmony_ci} 429662306a36Sopenharmony_ci 429762306a36Sopenharmony_cistatic int verify_attr_len(struct xdr_stream *xdr, unsigned int savep, uint32_t attrlen) 429862306a36Sopenharmony_ci{ 429962306a36Sopenharmony_ci unsigned int attrwords = XDR_QUADLEN(attrlen); 430062306a36Sopenharmony_ci unsigned int nwords = (xdr_stream_pos(xdr) - savep) >> 2; 430162306a36Sopenharmony_ci 430262306a36Sopenharmony_ci if (unlikely(attrwords != nwords)) { 430362306a36Sopenharmony_ci dprintk("%s: server returned incorrect attribute length: " 430462306a36Sopenharmony_ci "%u %c %u\n", 430562306a36Sopenharmony_ci __func__, 430662306a36Sopenharmony_ci attrwords << 2, 430762306a36Sopenharmony_ci (attrwords < nwords) ? '<' : '>', 430862306a36Sopenharmony_ci nwords << 2); 430962306a36Sopenharmony_ci return -EIO; 431062306a36Sopenharmony_ci } 431162306a36Sopenharmony_ci return 0; 431262306a36Sopenharmony_ci} 431362306a36Sopenharmony_ci 431462306a36Sopenharmony_cistatic int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) 431562306a36Sopenharmony_ci{ 431662306a36Sopenharmony_ci __be32 *p; 431762306a36Sopenharmony_ci 431862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 20); 431962306a36Sopenharmony_ci if (unlikely(!p)) 432062306a36Sopenharmony_ci return -EIO; 432162306a36Sopenharmony_ci cinfo->atomic = be32_to_cpup(p++); 432262306a36Sopenharmony_ci p = xdr_decode_hyper(p, &cinfo->before); 432362306a36Sopenharmony_ci xdr_decode_hyper(p, &cinfo->after); 432462306a36Sopenharmony_ci return 0; 432562306a36Sopenharmony_ci} 432662306a36Sopenharmony_ci 432762306a36Sopenharmony_cistatic int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access) 432862306a36Sopenharmony_ci{ 432962306a36Sopenharmony_ci __be32 *p; 433062306a36Sopenharmony_ci uint32_t supp, acc; 433162306a36Sopenharmony_ci int status; 433262306a36Sopenharmony_ci 433362306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_ACCESS); 433462306a36Sopenharmony_ci if (status) 433562306a36Sopenharmony_ci return status; 433662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 433762306a36Sopenharmony_ci if (unlikely(!p)) 433862306a36Sopenharmony_ci return -EIO; 433962306a36Sopenharmony_ci supp = be32_to_cpup(p++); 434062306a36Sopenharmony_ci acc = be32_to_cpup(p); 434162306a36Sopenharmony_ci *supported = supp; 434262306a36Sopenharmony_ci *access = acc; 434362306a36Sopenharmony_ci return 0; 434462306a36Sopenharmony_ci} 434562306a36Sopenharmony_ci 434662306a36Sopenharmony_cistatic int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len) 434762306a36Sopenharmony_ci{ 434862306a36Sopenharmony_ci ssize_t ret = xdr_stream_decode_opaque_fixed(xdr, buf, len); 434962306a36Sopenharmony_ci if (unlikely(ret < 0)) 435062306a36Sopenharmony_ci return -EIO; 435162306a36Sopenharmony_ci return 0; 435262306a36Sopenharmony_ci} 435362306a36Sopenharmony_ci 435462306a36Sopenharmony_cistatic int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 435562306a36Sopenharmony_ci{ 435662306a36Sopenharmony_ci return decode_opaque_fixed(xdr, stateid, NFS4_STATEID_SIZE); 435762306a36Sopenharmony_ci} 435862306a36Sopenharmony_ci 435962306a36Sopenharmony_cistatic int decode_open_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 436062306a36Sopenharmony_ci{ 436162306a36Sopenharmony_ci stateid->type = NFS4_OPEN_STATEID_TYPE; 436262306a36Sopenharmony_ci return decode_stateid(xdr, stateid); 436362306a36Sopenharmony_ci} 436462306a36Sopenharmony_ci 436562306a36Sopenharmony_cistatic int decode_lock_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 436662306a36Sopenharmony_ci{ 436762306a36Sopenharmony_ci stateid->type = NFS4_LOCK_STATEID_TYPE; 436862306a36Sopenharmony_ci return decode_stateid(xdr, stateid); 436962306a36Sopenharmony_ci} 437062306a36Sopenharmony_ci 437162306a36Sopenharmony_cistatic int decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 437262306a36Sopenharmony_ci{ 437362306a36Sopenharmony_ci stateid->type = NFS4_DELEGATION_STATEID_TYPE; 437462306a36Sopenharmony_ci return decode_stateid(xdr, stateid); 437562306a36Sopenharmony_ci} 437662306a36Sopenharmony_ci 437762306a36Sopenharmony_cistatic int decode_invalid_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 437862306a36Sopenharmony_ci{ 437962306a36Sopenharmony_ci nfs4_stateid dummy; 438062306a36Sopenharmony_ci 438162306a36Sopenharmony_ci nfs4_stateid_copy(stateid, &invalid_stateid); 438262306a36Sopenharmony_ci return decode_stateid(xdr, &dummy); 438362306a36Sopenharmony_ci} 438462306a36Sopenharmony_ci 438562306a36Sopenharmony_cistatic int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res) 438662306a36Sopenharmony_ci{ 438762306a36Sopenharmony_ci int status; 438862306a36Sopenharmony_ci 438962306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_CLOSE); 439062306a36Sopenharmony_ci if (status != -EIO) 439162306a36Sopenharmony_ci nfs_increment_open_seqid(status, res->seqid); 439262306a36Sopenharmony_ci if (!status) 439362306a36Sopenharmony_ci status = decode_invalid_stateid(xdr, &res->stateid); 439462306a36Sopenharmony_ci return status; 439562306a36Sopenharmony_ci} 439662306a36Sopenharmony_ci 439762306a36Sopenharmony_cistatic int decode_verifier(struct xdr_stream *xdr, void *verifier) 439862306a36Sopenharmony_ci{ 439962306a36Sopenharmony_ci return decode_opaque_fixed(xdr, verifier, NFS4_VERIFIER_SIZE); 440062306a36Sopenharmony_ci} 440162306a36Sopenharmony_ci 440262306a36Sopenharmony_cistatic int decode_write_verifier(struct xdr_stream *xdr, struct nfs_write_verifier *verifier) 440362306a36Sopenharmony_ci{ 440462306a36Sopenharmony_ci return decode_opaque_fixed(xdr, verifier->data, NFS4_VERIFIER_SIZE); 440562306a36Sopenharmony_ci} 440662306a36Sopenharmony_ci 440762306a36Sopenharmony_cistatic int decode_commit(struct xdr_stream *xdr, struct nfs_commitres *res) 440862306a36Sopenharmony_ci{ 440962306a36Sopenharmony_ci struct nfs_writeverf *verf = res->verf; 441062306a36Sopenharmony_ci int status; 441162306a36Sopenharmony_ci 441262306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_COMMIT); 441362306a36Sopenharmony_ci if (!status) 441462306a36Sopenharmony_ci status = decode_write_verifier(xdr, &verf->verifier); 441562306a36Sopenharmony_ci if (!status) 441662306a36Sopenharmony_ci verf->committed = NFS_FILE_SYNC; 441762306a36Sopenharmony_ci return status; 441862306a36Sopenharmony_ci} 441962306a36Sopenharmony_ci 442062306a36Sopenharmony_cistatic int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) 442162306a36Sopenharmony_ci{ 442262306a36Sopenharmony_ci __be32 *p; 442362306a36Sopenharmony_ci uint32_t bmlen; 442462306a36Sopenharmony_ci int status; 442562306a36Sopenharmony_ci 442662306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_CREATE); 442762306a36Sopenharmony_ci if (status) 442862306a36Sopenharmony_ci return status; 442962306a36Sopenharmony_ci if ((status = decode_change_info(xdr, cinfo))) 443062306a36Sopenharmony_ci return status; 443162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 443262306a36Sopenharmony_ci if (unlikely(!p)) 443362306a36Sopenharmony_ci return -EIO; 443462306a36Sopenharmony_ci bmlen = be32_to_cpup(p); 443562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, bmlen << 2); 443662306a36Sopenharmony_ci if (likely(p)) 443762306a36Sopenharmony_ci return 0; 443862306a36Sopenharmony_ci return -EIO; 443962306a36Sopenharmony_ci} 444062306a36Sopenharmony_ci 444162306a36Sopenharmony_cistatic int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) 444262306a36Sopenharmony_ci{ 444362306a36Sopenharmony_ci unsigned int savep; 444462306a36Sopenharmony_ci uint32_t attrlen, bitmap[3] = {0}; 444562306a36Sopenharmony_ci int status; 444662306a36Sopenharmony_ci 444762306a36Sopenharmony_ci if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 444862306a36Sopenharmony_ci goto xdr_error; 444962306a36Sopenharmony_ci if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 445062306a36Sopenharmony_ci goto xdr_error; 445162306a36Sopenharmony_ci if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 445262306a36Sopenharmony_ci goto xdr_error; 445362306a36Sopenharmony_ci if ((status = decode_attr_supported(xdr, bitmap, res->attr_bitmask)) != 0) 445462306a36Sopenharmony_ci goto xdr_error; 445562306a36Sopenharmony_ci if ((status = decode_attr_fh_expire_type(xdr, bitmap, 445662306a36Sopenharmony_ci &res->fh_expire_type)) != 0) 445762306a36Sopenharmony_ci goto xdr_error; 445862306a36Sopenharmony_ci if ((status = decode_attr_link_support(xdr, bitmap, &res->has_links)) != 0) 445962306a36Sopenharmony_ci goto xdr_error; 446062306a36Sopenharmony_ci if ((status = decode_attr_symlink_support(xdr, bitmap, &res->has_symlinks)) != 0) 446162306a36Sopenharmony_ci goto xdr_error; 446262306a36Sopenharmony_ci if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0) 446362306a36Sopenharmony_ci goto xdr_error; 446462306a36Sopenharmony_ci if ((status = decode_attr_case_insensitive(xdr, bitmap, &res->case_insensitive)) != 0) 446562306a36Sopenharmony_ci goto xdr_error; 446662306a36Sopenharmony_ci if ((status = decode_attr_case_preserving(xdr, bitmap, &res->case_preserving)) != 0) 446762306a36Sopenharmony_ci goto xdr_error; 446862306a36Sopenharmony_ci if ((status = decode_attr_exclcreat_supported(xdr, bitmap, 446962306a36Sopenharmony_ci res->exclcreat_bitmask)) != 0) 447062306a36Sopenharmony_ci goto xdr_error; 447162306a36Sopenharmony_ci status = verify_attr_len(xdr, savep, attrlen); 447262306a36Sopenharmony_cixdr_error: 447362306a36Sopenharmony_ci dprintk("%s: xdr returned %d!\n", __func__, -status); 447462306a36Sopenharmony_ci return status; 447562306a36Sopenharmony_ci} 447662306a36Sopenharmony_ci 447762306a36Sopenharmony_cistatic int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) 447862306a36Sopenharmony_ci{ 447962306a36Sopenharmony_ci unsigned int savep; 448062306a36Sopenharmony_ci uint32_t attrlen, bitmap[3] = {0}; 448162306a36Sopenharmony_ci int status; 448262306a36Sopenharmony_ci 448362306a36Sopenharmony_ci if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 448462306a36Sopenharmony_ci goto xdr_error; 448562306a36Sopenharmony_ci if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 448662306a36Sopenharmony_ci goto xdr_error; 448762306a36Sopenharmony_ci if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 448862306a36Sopenharmony_ci goto xdr_error; 448962306a36Sopenharmony_ci 449062306a36Sopenharmony_ci if ((status = decode_attr_files_avail(xdr, bitmap, &fsstat->afiles)) != 0) 449162306a36Sopenharmony_ci goto xdr_error; 449262306a36Sopenharmony_ci if ((status = decode_attr_files_free(xdr, bitmap, &fsstat->ffiles)) != 0) 449362306a36Sopenharmony_ci goto xdr_error; 449462306a36Sopenharmony_ci if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) 449562306a36Sopenharmony_ci goto xdr_error; 449662306a36Sopenharmony_ci 449762306a36Sopenharmony_ci status = -EIO; 449862306a36Sopenharmony_ci if (unlikely(bitmap[0])) 449962306a36Sopenharmony_ci goto xdr_error; 450062306a36Sopenharmony_ci 450162306a36Sopenharmony_ci if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) 450262306a36Sopenharmony_ci goto xdr_error; 450362306a36Sopenharmony_ci if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) 450462306a36Sopenharmony_ci goto xdr_error; 450562306a36Sopenharmony_ci if ((status = decode_attr_space_total(xdr, bitmap, &fsstat->tbytes)) != 0) 450662306a36Sopenharmony_ci goto xdr_error; 450762306a36Sopenharmony_ci 450862306a36Sopenharmony_ci status = verify_attr_len(xdr, savep, attrlen); 450962306a36Sopenharmony_cixdr_error: 451062306a36Sopenharmony_ci dprintk("%s: xdr returned %d!\n", __func__, -status); 451162306a36Sopenharmony_ci return status; 451262306a36Sopenharmony_ci} 451362306a36Sopenharmony_ci 451462306a36Sopenharmony_cistatic int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf) 451562306a36Sopenharmony_ci{ 451662306a36Sopenharmony_ci unsigned int savep; 451762306a36Sopenharmony_ci uint32_t attrlen, bitmap[3] = {0}; 451862306a36Sopenharmony_ci int status; 451962306a36Sopenharmony_ci 452062306a36Sopenharmony_ci if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 452162306a36Sopenharmony_ci goto xdr_error; 452262306a36Sopenharmony_ci if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 452362306a36Sopenharmony_ci goto xdr_error; 452462306a36Sopenharmony_ci if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 452562306a36Sopenharmony_ci goto xdr_error; 452662306a36Sopenharmony_ci 452762306a36Sopenharmony_ci if ((status = decode_attr_maxlink(xdr, bitmap, &pathconf->max_link)) != 0) 452862306a36Sopenharmony_ci goto xdr_error; 452962306a36Sopenharmony_ci if ((status = decode_attr_maxname(xdr, bitmap, &pathconf->max_namelen)) != 0) 453062306a36Sopenharmony_ci goto xdr_error; 453162306a36Sopenharmony_ci 453262306a36Sopenharmony_ci status = verify_attr_len(xdr, savep, attrlen); 453362306a36Sopenharmony_cixdr_error: 453462306a36Sopenharmony_ci dprintk("%s: xdr returned %d!\n", __func__, -status); 453562306a36Sopenharmony_ci return status; 453662306a36Sopenharmony_ci} 453762306a36Sopenharmony_ci 453862306a36Sopenharmony_cistatic int decode_threshold_hint(struct xdr_stream *xdr, 453962306a36Sopenharmony_ci uint32_t *bitmap, 454062306a36Sopenharmony_ci uint64_t *res, 454162306a36Sopenharmony_ci uint32_t hint_bit) 454262306a36Sopenharmony_ci{ 454362306a36Sopenharmony_ci __be32 *p; 454462306a36Sopenharmony_ci 454562306a36Sopenharmony_ci *res = 0; 454662306a36Sopenharmony_ci if (likely(bitmap[0] & hint_bit)) { 454762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 454862306a36Sopenharmony_ci if (unlikely(!p)) 454962306a36Sopenharmony_ci return -EIO; 455062306a36Sopenharmony_ci xdr_decode_hyper(p, res); 455162306a36Sopenharmony_ci } 455262306a36Sopenharmony_ci return 0; 455362306a36Sopenharmony_ci} 455462306a36Sopenharmony_ci 455562306a36Sopenharmony_cistatic int decode_first_threshold_item4(struct xdr_stream *xdr, 455662306a36Sopenharmony_ci struct nfs4_threshold *res) 455762306a36Sopenharmony_ci{ 455862306a36Sopenharmony_ci __be32 *p; 455962306a36Sopenharmony_ci unsigned int savep; 456062306a36Sopenharmony_ci uint32_t bitmap[3] = {0,}, attrlen; 456162306a36Sopenharmony_ci int status; 456262306a36Sopenharmony_ci 456362306a36Sopenharmony_ci /* layout type */ 456462306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 456562306a36Sopenharmony_ci if (unlikely(!p)) 456662306a36Sopenharmony_ci return -EIO; 456762306a36Sopenharmony_ci res->l_type = be32_to_cpup(p); 456862306a36Sopenharmony_ci 456962306a36Sopenharmony_ci /* thi_hintset bitmap */ 457062306a36Sopenharmony_ci status = decode_attr_bitmap(xdr, bitmap); 457162306a36Sopenharmony_ci if (status < 0) 457262306a36Sopenharmony_ci goto xdr_error; 457362306a36Sopenharmony_ci 457462306a36Sopenharmony_ci /* thi_hintlist length */ 457562306a36Sopenharmony_ci status = decode_attr_length(xdr, &attrlen, &savep); 457662306a36Sopenharmony_ci if (status < 0) 457762306a36Sopenharmony_ci goto xdr_error; 457862306a36Sopenharmony_ci /* thi_hintlist */ 457962306a36Sopenharmony_ci status = decode_threshold_hint(xdr, bitmap, &res->rd_sz, THRESHOLD_RD); 458062306a36Sopenharmony_ci if (status < 0) 458162306a36Sopenharmony_ci goto xdr_error; 458262306a36Sopenharmony_ci status = decode_threshold_hint(xdr, bitmap, &res->wr_sz, THRESHOLD_WR); 458362306a36Sopenharmony_ci if (status < 0) 458462306a36Sopenharmony_ci goto xdr_error; 458562306a36Sopenharmony_ci status = decode_threshold_hint(xdr, bitmap, &res->rd_io_sz, 458662306a36Sopenharmony_ci THRESHOLD_RD_IO); 458762306a36Sopenharmony_ci if (status < 0) 458862306a36Sopenharmony_ci goto xdr_error; 458962306a36Sopenharmony_ci status = decode_threshold_hint(xdr, bitmap, &res->wr_io_sz, 459062306a36Sopenharmony_ci THRESHOLD_WR_IO); 459162306a36Sopenharmony_ci if (status < 0) 459262306a36Sopenharmony_ci goto xdr_error; 459362306a36Sopenharmony_ci 459462306a36Sopenharmony_ci status = verify_attr_len(xdr, savep, attrlen); 459562306a36Sopenharmony_ci res->bm = bitmap[0]; 459662306a36Sopenharmony_ci 459762306a36Sopenharmony_ci dprintk("%s bm=0x%x rd_sz=%llu wr_sz=%llu rd_io=%llu wr_io=%llu\n", 459862306a36Sopenharmony_ci __func__, res->bm, res->rd_sz, res->wr_sz, res->rd_io_sz, 459962306a36Sopenharmony_ci res->wr_io_sz); 460062306a36Sopenharmony_cixdr_error: 460162306a36Sopenharmony_ci dprintk("%s ret=%d!\n", __func__, status); 460262306a36Sopenharmony_ci return status; 460362306a36Sopenharmony_ci} 460462306a36Sopenharmony_ci 460562306a36Sopenharmony_ci/* 460662306a36Sopenharmony_ci * Thresholds on pNFS direct I/O vrs MDS I/O 460762306a36Sopenharmony_ci */ 460862306a36Sopenharmony_cistatic int decode_attr_mdsthreshold(struct xdr_stream *xdr, 460962306a36Sopenharmony_ci uint32_t *bitmap, 461062306a36Sopenharmony_ci struct nfs4_threshold *res) 461162306a36Sopenharmony_ci{ 461262306a36Sopenharmony_ci __be32 *p; 461362306a36Sopenharmony_ci int status = 0; 461462306a36Sopenharmony_ci uint32_t num; 461562306a36Sopenharmony_ci 461662306a36Sopenharmony_ci if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U))) 461762306a36Sopenharmony_ci return -EIO; 461862306a36Sopenharmony_ci if (bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD) { 461962306a36Sopenharmony_ci /* Did the server return an unrequested attribute? */ 462062306a36Sopenharmony_ci if (unlikely(res == NULL)) 462162306a36Sopenharmony_ci return -EREMOTEIO; 462262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 462362306a36Sopenharmony_ci if (unlikely(!p)) 462462306a36Sopenharmony_ci return -EIO; 462562306a36Sopenharmony_ci num = be32_to_cpup(p); 462662306a36Sopenharmony_ci if (num == 0) 462762306a36Sopenharmony_ci return 0; 462862306a36Sopenharmony_ci if (num > 1) 462962306a36Sopenharmony_ci printk(KERN_INFO "%s: Warning: Multiple pNFS layout " 463062306a36Sopenharmony_ci "drivers per filesystem not supported\n", 463162306a36Sopenharmony_ci __func__); 463262306a36Sopenharmony_ci 463362306a36Sopenharmony_ci status = decode_first_threshold_item4(xdr, res); 463462306a36Sopenharmony_ci bitmap[2] &= ~FATTR4_WORD2_MDSTHRESHOLD; 463562306a36Sopenharmony_ci } 463662306a36Sopenharmony_ci return status; 463762306a36Sopenharmony_ci} 463862306a36Sopenharmony_ci 463962306a36Sopenharmony_cistatic int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, 464062306a36Sopenharmony_ci struct nfs_fattr *fattr, struct nfs_fh *fh, 464162306a36Sopenharmony_ci struct nfs4_fs_locations *fs_loc, const struct nfs_server *server) 464262306a36Sopenharmony_ci{ 464362306a36Sopenharmony_ci int status; 464462306a36Sopenharmony_ci umode_t fmode = 0; 464562306a36Sopenharmony_ci uint32_t type; 464662306a36Sopenharmony_ci int32_t err; 464762306a36Sopenharmony_ci 464862306a36Sopenharmony_ci status = decode_attr_type(xdr, bitmap, &type); 464962306a36Sopenharmony_ci if (status < 0) 465062306a36Sopenharmony_ci goto xdr_error; 465162306a36Sopenharmony_ci fattr->mode = 0; 465262306a36Sopenharmony_ci if (status != 0) { 465362306a36Sopenharmony_ci fattr->mode |= nfs_type2fmt[type]; 465462306a36Sopenharmony_ci fattr->valid |= status; 465562306a36Sopenharmony_ci } 465662306a36Sopenharmony_ci 465762306a36Sopenharmony_ci status = decode_attr_change(xdr, bitmap, &fattr->change_attr); 465862306a36Sopenharmony_ci if (status < 0) 465962306a36Sopenharmony_ci goto xdr_error; 466062306a36Sopenharmony_ci fattr->valid |= status; 466162306a36Sopenharmony_ci 466262306a36Sopenharmony_ci status = decode_attr_size(xdr, bitmap, &fattr->size); 466362306a36Sopenharmony_ci if (status < 0) 466462306a36Sopenharmony_ci goto xdr_error; 466562306a36Sopenharmony_ci fattr->valid |= status; 466662306a36Sopenharmony_ci 466762306a36Sopenharmony_ci status = decode_attr_fsid(xdr, bitmap, &fattr->fsid); 466862306a36Sopenharmony_ci if (status < 0) 466962306a36Sopenharmony_ci goto xdr_error; 467062306a36Sopenharmony_ci fattr->valid |= status; 467162306a36Sopenharmony_ci 467262306a36Sopenharmony_ci err = 0; 467362306a36Sopenharmony_ci status = decode_attr_error(xdr, bitmap, &err); 467462306a36Sopenharmony_ci if (status < 0) 467562306a36Sopenharmony_ci goto xdr_error; 467662306a36Sopenharmony_ci 467762306a36Sopenharmony_ci status = decode_attr_filehandle(xdr, bitmap, fh); 467862306a36Sopenharmony_ci if (status < 0) 467962306a36Sopenharmony_ci goto xdr_error; 468062306a36Sopenharmony_ci 468162306a36Sopenharmony_ci status = decode_attr_fileid(xdr, bitmap, &fattr->fileid); 468262306a36Sopenharmony_ci if (status < 0) 468362306a36Sopenharmony_ci goto xdr_error; 468462306a36Sopenharmony_ci fattr->valid |= status; 468562306a36Sopenharmony_ci 468662306a36Sopenharmony_ci status = decode_attr_fs_locations(xdr, bitmap, fs_loc); 468762306a36Sopenharmony_ci if (status < 0) 468862306a36Sopenharmony_ci goto xdr_error; 468962306a36Sopenharmony_ci fattr->valid |= status; 469062306a36Sopenharmony_ci 469162306a36Sopenharmony_ci status = -EIO; 469262306a36Sopenharmony_ci if (unlikely(bitmap[0])) 469362306a36Sopenharmony_ci goto xdr_error; 469462306a36Sopenharmony_ci 469562306a36Sopenharmony_ci status = decode_attr_mode(xdr, bitmap, &fmode); 469662306a36Sopenharmony_ci if (status < 0) 469762306a36Sopenharmony_ci goto xdr_error; 469862306a36Sopenharmony_ci if (status != 0) { 469962306a36Sopenharmony_ci fattr->mode |= fmode; 470062306a36Sopenharmony_ci fattr->valid |= status; 470162306a36Sopenharmony_ci } 470262306a36Sopenharmony_ci 470362306a36Sopenharmony_ci status = decode_attr_nlink(xdr, bitmap, &fattr->nlink); 470462306a36Sopenharmony_ci if (status < 0) 470562306a36Sopenharmony_ci goto xdr_error; 470662306a36Sopenharmony_ci fattr->valid |= status; 470762306a36Sopenharmony_ci 470862306a36Sopenharmony_ci status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, fattr->owner_name); 470962306a36Sopenharmony_ci if (status < 0) 471062306a36Sopenharmony_ci goto xdr_error; 471162306a36Sopenharmony_ci fattr->valid |= status; 471262306a36Sopenharmony_ci 471362306a36Sopenharmony_ci status = decode_attr_group(xdr, bitmap, server, &fattr->gid, fattr->group_name); 471462306a36Sopenharmony_ci if (status < 0) 471562306a36Sopenharmony_ci goto xdr_error; 471662306a36Sopenharmony_ci fattr->valid |= status; 471762306a36Sopenharmony_ci 471862306a36Sopenharmony_ci status = decode_attr_rdev(xdr, bitmap, &fattr->rdev); 471962306a36Sopenharmony_ci if (status < 0) 472062306a36Sopenharmony_ci goto xdr_error; 472162306a36Sopenharmony_ci fattr->valid |= status; 472262306a36Sopenharmony_ci 472362306a36Sopenharmony_ci status = decode_attr_space_used(xdr, bitmap, &fattr->du.nfs3.used); 472462306a36Sopenharmony_ci if (status < 0) 472562306a36Sopenharmony_ci goto xdr_error; 472662306a36Sopenharmony_ci fattr->valid |= status; 472762306a36Sopenharmony_ci 472862306a36Sopenharmony_ci status = decode_attr_time_access(xdr, bitmap, &fattr->atime); 472962306a36Sopenharmony_ci if (status < 0) 473062306a36Sopenharmony_ci goto xdr_error; 473162306a36Sopenharmony_ci fattr->valid |= status; 473262306a36Sopenharmony_ci 473362306a36Sopenharmony_ci status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime); 473462306a36Sopenharmony_ci if (status < 0) 473562306a36Sopenharmony_ci goto xdr_error; 473662306a36Sopenharmony_ci fattr->valid |= status; 473762306a36Sopenharmony_ci 473862306a36Sopenharmony_ci status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime); 473962306a36Sopenharmony_ci if (status < 0) 474062306a36Sopenharmony_ci goto xdr_error; 474162306a36Sopenharmony_ci fattr->valid |= status; 474262306a36Sopenharmony_ci 474362306a36Sopenharmony_ci status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid); 474462306a36Sopenharmony_ci if (status < 0) 474562306a36Sopenharmony_ci goto xdr_error; 474662306a36Sopenharmony_ci fattr->valid |= status; 474762306a36Sopenharmony_ci 474862306a36Sopenharmony_ci status = -EIO; 474962306a36Sopenharmony_ci if (unlikely(bitmap[1])) 475062306a36Sopenharmony_ci goto xdr_error; 475162306a36Sopenharmony_ci 475262306a36Sopenharmony_ci status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); 475362306a36Sopenharmony_ci if (status < 0) 475462306a36Sopenharmony_ci goto xdr_error; 475562306a36Sopenharmony_ci 475662306a36Sopenharmony_ci status = decode_attr_security_label(xdr, bitmap, fattr->label); 475762306a36Sopenharmony_ci if (status < 0) 475862306a36Sopenharmony_ci goto xdr_error; 475962306a36Sopenharmony_ci fattr->valid |= status; 476062306a36Sopenharmony_ci 476162306a36Sopenharmony_cixdr_error: 476262306a36Sopenharmony_ci dprintk("%s: xdr returned %d\n", __func__, -status); 476362306a36Sopenharmony_ci return status; 476462306a36Sopenharmony_ci} 476562306a36Sopenharmony_ci 476662306a36Sopenharmony_cistatic int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr, 476762306a36Sopenharmony_ci struct nfs_fh *fh, struct nfs4_fs_locations *fs_loc, 476862306a36Sopenharmony_ci const struct nfs_server *server) 476962306a36Sopenharmony_ci{ 477062306a36Sopenharmony_ci unsigned int savep; 477162306a36Sopenharmony_ci uint32_t attrlen, 477262306a36Sopenharmony_ci bitmap[3] = {0}; 477362306a36Sopenharmony_ci int status; 477462306a36Sopenharmony_ci 477562306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_GETATTR); 477662306a36Sopenharmony_ci if (status < 0) 477762306a36Sopenharmony_ci goto xdr_error; 477862306a36Sopenharmony_ci 477962306a36Sopenharmony_ci status = decode_attr_bitmap(xdr, bitmap); 478062306a36Sopenharmony_ci if (status < 0) 478162306a36Sopenharmony_ci goto xdr_error; 478262306a36Sopenharmony_ci 478362306a36Sopenharmony_ci status = decode_attr_length(xdr, &attrlen, &savep); 478462306a36Sopenharmony_ci if (status < 0) 478562306a36Sopenharmony_ci goto xdr_error; 478662306a36Sopenharmony_ci 478762306a36Sopenharmony_ci status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, fs_loc, server); 478862306a36Sopenharmony_ci if (status < 0) 478962306a36Sopenharmony_ci goto xdr_error; 479062306a36Sopenharmony_ci 479162306a36Sopenharmony_ci status = verify_attr_len(xdr, savep, attrlen); 479262306a36Sopenharmony_cixdr_error: 479362306a36Sopenharmony_ci dprintk("%s: xdr returned %d\n", __func__, -status); 479462306a36Sopenharmony_ci return status; 479562306a36Sopenharmony_ci} 479662306a36Sopenharmony_ci 479762306a36Sopenharmony_cistatic int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, 479862306a36Sopenharmony_ci const struct nfs_server *server) 479962306a36Sopenharmony_ci{ 480062306a36Sopenharmony_ci return decode_getfattr_generic(xdr, fattr, NULL, NULL, server); 480162306a36Sopenharmony_ci} 480262306a36Sopenharmony_ci 480362306a36Sopenharmony_ci/* 480462306a36Sopenharmony_ci * Decode potentially multiple layout types. 480562306a36Sopenharmony_ci */ 480662306a36Sopenharmony_cistatic int decode_pnfs_layout_types(struct xdr_stream *xdr, 480762306a36Sopenharmony_ci struct nfs_fsinfo *fsinfo) 480862306a36Sopenharmony_ci{ 480962306a36Sopenharmony_ci __be32 *p; 481062306a36Sopenharmony_ci uint32_t i; 481162306a36Sopenharmony_ci 481262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 481362306a36Sopenharmony_ci if (unlikely(!p)) 481462306a36Sopenharmony_ci return -EIO; 481562306a36Sopenharmony_ci fsinfo->nlayouttypes = be32_to_cpup(p); 481662306a36Sopenharmony_ci 481762306a36Sopenharmony_ci /* pNFS is not supported by the underlying file system */ 481862306a36Sopenharmony_ci if (fsinfo->nlayouttypes == 0) 481962306a36Sopenharmony_ci return 0; 482062306a36Sopenharmony_ci 482162306a36Sopenharmony_ci /* Decode and set first layout type, move xdr->p past unused types */ 482262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, fsinfo->nlayouttypes * 4); 482362306a36Sopenharmony_ci if (unlikely(!p)) 482462306a36Sopenharmony_ci return -EIO; 482562306a36Sopenharmony_ci 482662306a36Sopenharmony_ci /* If we get too many, then just cap it at the max */ 482762306a36Sopenharmony_ci if (fsinfo->nlayouttypes > NFS_MAX_LAYOUT_TYPES) { 482862306a36Sopenharmony_ci printk(KERN_INFO "NFS: %s: Warning: Too many (%u) pNFS layout types\n", 482962306a36Sopenharmony_ci __func__, fsinfo->nlayouttypes); 483062306a36Sopenharmony_ci fsinfo->nlayouttypes = NFS_MAX_LAYOUT_TYPES; 483162306a36Sopenharmony_ci } 483262306a36Sopenharmony_ci 483362306a36Sopenharmony_ci for(i = 0; i < fsinfo->nlayouttypes; ++i) 483462306a36Sopenharmony_ci fsinfo->layouttype[i] = be32_to_cpup(p++); 483562306a36Sopenharmony_ci return 0; 483662306a36Sopenharmony_ci} 483762306a36Sopenharmony_ci 483862306a36Sopenharmony_ci/* 483962306a36Sopenharmony_ci * The type of file system exported. 484062306a36Sopenharmony_ci * Note we must ensure that layouttype is set in any non-error case. 484162306a36Sopenharmony_ci */ 484262306a36Sopenharmony_cistatic int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap, 484362306a36Sopenharmony_ci struct nfs_fsinfo *fsinfo) 484462306a36Sopenharmony_ci{ 484562306a36Sopenharmony_ci int status = 0; 484662306a36Sopenharmony_ci 484762306a36Sopenharmony_ci dprintk("%s: bitmap is %x\n", __func__, bitmap[1]); 484862306a36Sopenharmony_ci if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U))) 484962306a36Sopenharmony_ci return -EIO; 485062306a36Sopenharmony_ci if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) { 485162306a36Sopenharmony_ci status = decode_pnfs_layout_types(xdr, fsinfo); 485262306a36Sopenharmony_ci bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES; 485362306a36Sopenharmony_ci } 485462306a36Sopenharmony_ci return status; 485562306a36Sopenharmony_ci} 485662306a36Sopenharmony_ci 485762306a36Sopenharmony_ci/* 485862306a36Sopenharmony_ci * The prefered block size for layout directed io 485962306a36Sopenharmony_ci */ 486062306a36Sopenharmony_cistatic int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap, 486162306a36Sopenharmony_ci uint32_t *res) 486262306a36Sopenharmony_ci{ 486362306a36Sopenharmony_ci __be32 *p; 486462306a36Sopenharmony_ci 486562306a36Sopenharmony_ci dprintk("%s: bitmap is %x\n", __func__, bitmap[2]); 486662306a36Sopenharmony_ci *res = 0; 486762306a36Sopenharmony_ci if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) { 486862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 486962306a36Sopenharmony_ci if (unlikely(!p)) 487062306a36Sopenharmony_ci return -EIO; 487162306a36Sopenharmony_ci *res = be32_to_cpup(p); 487262306a36Sopenharmony_ci bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE; 487362306a36Sopenharmony_ci } 487462306a36Sopenharmony_ci return 0; 487562306a36Sopenharmony_ci} 487662306a36Sopenharmony_ci 487762306a36Sopenharmony_ci/* 487862306a36Sopenharmony_ci * The granularity of a CLONE operation. 487962306a36Sopenharmony_ci */ 488062306a36Sopenharmony_cistatic int decode_attr_clone_blksize(struct xdr_stream *xdr, uint32_t *bitmap, 488162306a36Sopenharmony_ci uint32_t *res) 488262306a36Sopenharmony_ci{ 488362306a36Sopenharmony_ci __be32 *p; 488462306a36Sopenharmony_ci 488562306a36Sopenharmony_ci dprintk("%s: bitmap is %x\n", __func__, bitmap[2]); 488662306a36Sopenharmony_ci *res = 0; 488762306a36Sopenharmony_ci if (bitmap[2] & FATTR4_WORD2_CLONE_BLKSIZE) { 488862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 488962306a36Sopenharmony_ci if (unlikely(!p)) 489062306a36Sopenharmony_ci return -EIO; 489162306a36Sopenharmony_ci *res = be32_to_cpup(p); 489262306a36Sopenharmony_ci bitmap[2] &= ~FATTR4_WORD2_CLONE_BLKSIZE; 489362306a36Sopenharmony_ci } 489462306a36Sopenharmony_ci return 0; 489562306a36Sopenharmony_ci} 489662306a36Sopenharmony_ci 489762306a36Sopenharmony_cistatic int decode_attr_change_attr_type(struct xdr_stream *xdr, 489862306a36Sopenharmony_ci uint32_t *bitmap, 489962306a36Sopenharmony_ci enum nfs4_change_attr_type *res) 490062306a36Sopenharmony_ci{ 490162306a36Sopenharmony_ci u32 tmp = NFS4_CHANGE_TYPE_IS_UNDEFINED; 490262306a36Sopenharmony_ci 490362306a36Sopenharmony_ci dprintk("%s: bitmap is %x\n", __func__, bitmap[2]); 490462306a36Sopenharmony_ci if (bitmap[2] & FATTR4_WORD2_CHANGE_ATTR_TYPE) { 490562306a36Sopenharmony_ci if (xdr_stream_decode_u32(xdr, &tmp)) 490662306a36Sopenharmony_ci return -EIO; 490762306a36Sopenharmony_ci bitmap[2] &= ~FATTR4_WORD2_CHANGE_ATTR_TYPE; 490862306a36Sopenharmony_ci } 490962306a36Sopenharmony_ci 491062306a36Sopenharmony_ci switch(tmp) { 491162306a36Sopenharmony_ci case NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR: 491262306a36Sopenharmony_ci case NFS4_CHANGE_TYPE_IS_VERSION_COUNTER: 491362306a36Sopenharmony_ci case NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS: 491462306a36Sopenharmony_ci case NFS4_CHANGE_TYPE_IS_TIME_METADATA: 491562306a36Sopenharmony_ci *res = tmp; 491662306a36Sopenharmony_ci break; 491762306a36Sopenharmony_ci default: 491862306a36Sopenharmony_ci *res = NFS4_CHANGE_TYPE_IS_UNDEFINED; 491962306a36Sopenharmony_ci } 492062306a36Sopenharmony_ci return 0; 492162306a36Sopenharmony_ci} 492262306a36Sopenharmony_ci 492362306a36Sopenharmony_cistatic int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) 492462306a36Sopenharmony_ci{ 492562306a36Sopenharmony_ci unsigned int savep; 492662306a36Sopenharmony_ci uint32_t attrlen, bitmap[3]; 492762306a36Sopenharmony_ci int status; 492862306a36Sopenharmony_ci 492962306a36Sopenharmony_ci if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 493062306a36Sopenharmony_ci goto xdr_error; 493162306a36Sopenharmony_ci if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 493262306a36Sopenharmony_ci goto xdr_error; 493362306a36Sopenharmony_ci if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 493462306a36Sopenharmony_ci goto xdr_error; 493562306a36Sopenharmony_ci 493662306a36Sopenharmony_ci fsinfo->rtmult = fsinfo->wtmult = 512; /* ??? */ 493762306a36Sopenharmony_ci 493862306a36Sopenharmony_ci if ((status = decode_attr_lease_time(xdr, bitmap, &fsinfo->lease_time)) != 0) 493962306a36Sopenharmony_ci goto xdr_error; 494062306a36Sopenharmony_ci if ((status = decode_attr_maxfilesize(xdr, bitmap, &fsinfo->maxfilesize)) != 0) 494162306a36Sopenharmony_ci goto xdr_error; 494262306a36Sopenharmony_ci if ((status = decode_attr_maxread(xdr, bitmap, &fsinfo->rtmax)) != 0) 494362306a36Sopenharmony_ci goto xdr_error; 494462306a36Sopenharmony_ci fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax; 494562306a36Sopenharmony_ci if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) 494662306a36Sopenharmony_ci goto xdr_error; 494762306a36Sopenharmony_ci fsinfo->wtpref = fsinfo->wtmax; 494862306a36Sopenharmony_ci 494962306a36Sopenharmony_ci status = -EIO; 495062306a36Sopenharmony_ci if (unlikely(bitmap[0])) 495162306a36Sopenharmony_ci goto xdr_error; 495262306a36Sopenharmony_ci 495362306a36Sopenharmony_ci status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); 495462306a36Sopenharmony_ci if (status != 0) 495562306a36Sopenharmony_ci goto xdr_error; 495662306a36Sopenharmony_ci status = decode_attr_pnfstype(xdr, bitmap, fsinfo); 495762306a36Sopenharmony_ci if (status != 0) 495862306a36Sopenharmony_ci goto xdr_error; 495962306a36Sopenharmony_ci 496062306a36Sopenharmony_ci status = -EIO; 496162306a36Sopenharmony_ci if (unlikely(bitmap[1])) 496262306a36Sopenharmony_ci goto xdr_error; 496362306a36Sopenharmony_ci 496462306a36Sopenharmony_ci status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); 496562306a36Sopenharmony_ci if (status) 496662306a36Sopenharmony_ci goto xdr_error; 496762306a36Sopenharmony_ci status = decode_attr_clone_blksize(xdr, bitmap, &fsinfo->clone_blksize); 496862306a36Sopenharmony_ci if (status) 496962306a36Sopenharmony_ci goto xdr_error; 497062306a36Sopenharmony_ci 497162306a36Sopenharmony_ci status = decode_attr_change_attr_type(xdr, bitmap, 497262306a36Sopenharmony_ci &fsinfo->change_attr_type); 497362306a36Sopenharmony_ci if (status) 497462306a36Sopenharmony_ci goto xdr_error; 497562306a36Sopenharmony_ci 497662306a36Sopenharmony_ci status = decode_attr_xattrsupport(xdr, bitmap, 497762306a36Sopenharmony_ci &fsinfo->xattr_support); 497862306a36Sopenharmony_ci if (status) 497962306a36Sopenharmony_ci goto xdr_error; 498062306a36Sopenharmony_ci 498162306a36Sopenharmony_ci status = verify_attr_len(xdr, savep, attrlen); 498262306a36Sopenharmony_cixdr_error: 498362306a36Sopenharmony_ci dprintk("%s: xdr returned %d!\n", __func__, -status); 498462306a36Sopenharmony_ci return status; 498562306a36Sopenharmony_ci} 498662306a36Sopenharmony_ci 498762306a36Sopenharmony_cistatic int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) 498862306a36Sopenharmony_ci{ 498962306a36Sopenharmony_ci __be32 *p; 499062306a36Sopenharmony_ci uint32_t len; 499162306a36Sopenharmony_ci int status; 499262306a36Sopenharmony_ci 499362306a36Sopenharmony_ci /* Zero handle first to allow comparisons */ 499462306a36Sopenharmony_ci memset(fh, 0, sizeof(*fh)); 499562306a36Sopenharmony_ci 499662306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_GETFH); 499762306a36Sopenharmony_ci if (status) 499862306a36Sopenharmony_ci return status; 499962306a36Sopenharmony_ci 500062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 500162306a36Sopenharmony_ci if (unlikely(!p)) 500262306a36Sopenharmony_ci return -EIO; 500362306a36Sopenharmony_ci len = be32_to_cpup(p); 500462306a36Sopenharmony_ci if (len > NFS4_FHSIZE || len == 0) { 500562306a36Sopenharmony_ci trace_nfs4_xdr_bad_filehandle(xdr, OP_GETFH, NFS4ERR_BADHANDLE); 500662306a36Sopenharmony_ci return -EREMOTEIO; 500762306a36Sopenharmony_ci } 500862306a36Sopenharmony_ci fh->size = len; 500962306a36Sopenharmony_ci p = xdr_inline_decode(xdr, len); 501062306a36Sopenharmony_ci if (unlikely(!p)) 501162306a36Sopenharmony_ci return -EIO; 501262306a36Sopenharmony_ci memcpy(fh->data, p, len); 501362306a36Sopenharmony_ci return 0; 501462306a36Sopenharmony_ci} 501562306a36Sopenharmony_ci 501662306a36Sopenharmony_cistatic int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) 501762306a36Sopenharmony_ci{ 501862306a36Sopenharmony_ci int status; 501962306a36Sopenharmony_ci 502062306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_LINK); 502162306a36Sopenharmony_ci if (status) 502262306a36Sopenharmony_ci return status; 502362306a36Sopenharmony_ci return decode_change_info(xdr, cinfo); 502462306a36Sopenharmony_ci} 502562306a36Sopenharmony_ci 502662306a36Sopenharmony_ci/* 502762306a36Sopenharmony_ci * We create the owner, so we know a proper owner.id length is 4. 502862306a36Sopenharmony_ci */ 502962306a36Sopenharmony_cistatic int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) 503062306a36Sopenharmony_ci{ 503162306a36Sopenharmony_ci uint64_t offset, length, clientid; 503262306a36Sopenharmony_ci __be32 *p; 503362306a36Sopenharmony_ci uint32_t namelen, type; 503462306a36Sopenharmony_ci 503562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 32); /* read 32 bytes */ 503662306a36Sopenharmony_ci if (unlikely(!p)) 503762306a36Sopenharmony_ci return -EIO; 503862306a36Sopenharmony_ci p = xdr_decode_hyper(p, &offset); /* read 2 8-byte long words */ 503962306a36Sopenharmony_ci p = xdr_decode_hyper(p, &length); 504062306a36Sopenharmony_ci type = be32_to_cpup(p++); /* 4 byte read */ 504162306a36Sopenharmony_ci if (fl != NULL) { /* manipulate file lock */ 504262306a36Sopenharmony_ci fl->fl_start = (loff_t)offset; 504362306a36Sopenharmony_ci fl->fl_end = fl->fl_start + (loff_t)length - 1; 504462306a36Sopenharmony_ci if (length == ~(uint64_t)0) 504562306a36Sopenharmony_ci fl->fl_end = OFFSET_MAX; 504662306a36Sopenharmony_ci fl->fl_type = F_WRLCK; 504762306a36Sopenharmony_ci if (type & 1) 504862306a36Sopenharmony_ci fl->fl_type = F_RDLCK; 504962306a36Sopenharmony_ci fl->fl_pid = 0; 505062306a36Sopenharmony_ci } 505162306a36Sopenharmony_ci p = xdr_decode_hyper(p, &clientid); /* read 8 bytes */ 505262306a36Sopenharmony_ci namelen = be32_to_cpup(p); /* read 4 bytes */ /* have read all 32 bytes now */ 505362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, namelen); /* variable size field */ 505462306a36Sopenharmony_ci if (likely(!p)) 505562306a36Sopenharmony_ci return -EIO; 505662306a36Sopenharmony_ci return -NFS4ERR_DENIED; 505762306a36Sopenharmony_ci} 505862306a36Sopenharmony_ci 505962306a36Sopenharmony_cistatic int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) 506062306a36Sopenharmony_ci{ 506162306a36Sopenharmony_ci int status; 506262306a36Sopenharmony_ci 506362306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_LOCK); 506462306a36Sopenharmony_ci if (status == -EIO) 506562306a36Sopenharmony_ci goto out; 506662306a36Sopenharmony_ci if (status == 0) { 506762306a36Sopenharmony_ci status = decode_lock_stateid(xdr, &res->stateid); 506862306a36Sopenharmony_ci if (unlikely(status)) 506962306a36Sopenharmony_ci goto out; 507062306a36Sopenharmony_ci } else if (status == -NFS4ERR_DENIED) 507162306a36Sopenharmony_ci status = decode_lock_denied(xdr, NULL); 507262306a36Sopenharmony_ci if (res->open_seqid != NULL) 507362306a36Sopenharmony_ci nfs_increment_open_seqid(status, res->open_seqid); 507462306a36Sopenharmony_ci nfs_increment_lock_seqid(status, res->lock_seqid); 507562306a36Sopenharmony_ciout: 507662306a36Sopenharmony_ci return status; 507762306a36Sopenharmony_ci} 507862306a36Sopenharmony_ci 507962306a36Sopenharmony_cistatic int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res) 508062306a36Sopenharmony_ci{ 508162306a36Sopenharmony_ci int status; 508262306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_LOCKT); 508362306a36Sopenharmony_ci if (status == -NFS4ERR_DENIED) 508462306a36Sopenharmony_ci return decode_lock_denied(xdr, res->denied); 508562306a36Sopenharmony_ci return status; 508662306a36Sopenharmony_ci} 508762306a36Sopenharmony_ci 508862306a36Sopenharmony_cistatic int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) 508962306a36Sopenharmony_ci{ 509062306a36Sopenharmony_ci int status; 509162306a36Sopenharmony_ci 509262306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_LOCKU); 509362306a36Sopenharmony_ci if (status != -EIO) 509462306a36Sopenharmony_ci nfs_increment_lock_seqid(status, res->seqid); 509562306a36Sopenharmony_ci if (status == 0) 509662306a36Sopenharmony_ci status = decode_lock_stateid(xdr, &res->stateid); 509762306a36Sopenharmony_ci return status; 509862306a36Sopenharmony_ci} 509962306a36Sopenharmony_ci 510062306a36Sopenharmony_cistatic int decode_release_lockowner(struct xdr_stream *xdr) 510162306a36Sopenharmony_ci{ 510262306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_RELEASE_LOCKOWNER); 510362306a36Sopenharmony_ci} 510462306a36Sopenharmony_ci 510562306a36Sopenharmony_cistatic int decode_lookup(struct xdr_stream *xdr) 510662306a36Sopenharmony_ci{ 510762306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_LOOKUP); 510862306a36Sopenharmony_ci} 510962306a36Sopenharmony_ci 511062306a36Sopenharmony_cistatic int decode_lookupp(struct xdr_stream *xdr) 511162306a36Sopenharmony_ci{ 511262306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_LOOKUPP); 511362306a36Sopenharmony_ci} 511462306a36Sopenharmony_ci 511562306a36Sopenharmony_ci/* This is too sick! */ 511662306a36Sopenharmony_cistatic int decode_space_limit(struct xdr_stream *xdr, 511762306a36Sopenharmony_ci unsigned long *pagemod_limit) 511862306a36Sopenharmony_ci{ 511962306a36Sopenharmony_ci __be32 *p; 512062306a36Sopenharmony_ci uint32_t limit_type, nblocks, blocksize; 512162306a36Sopenharmony_ci u64 maxsize = 0; 512262306a36Sopenharmony_ci 512362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 12); 512462306a36Sopenharmony_ci if (unlikely(!p)) 512562306a36Sopenharmony_ci return -EIO; 512662306a36Sopenharmony_ci limit_type = be32_to_cpup(p++); 512762306a36Sopenharmony_ci switch (limit_type) { 512862306a36Sopenharmony_ci case NFS4_LIMIT_SIZE: 512962306a36Sopenharmony_ci xdr_decode_hyper(p, &maxsize); 513062306a36Sopenharmony_ci break; 513162306a36Sopenharmony_ci case NFS4_LIMIT_BLOCKS: 513262306a36Sopenharmony_ci nblocks = be32_to_cpup(p++); 513362306a36Sopenharmony_ci blocksize = be32_to_cpup(p); 513462306a36Sopenharmony_ci maxsize = (uint64_t)nblocks * (uint64_t)blocksize; 513562306a36Sopenharmony_ci } 513662306a36Sopenharmony_ci maxsize >>= PAGE_SHIFT; 513762306a36Sopenharmony_ci *pagemod_limit = min_t(u64, maxsize, ULONG_MAX); 513862306a36Sopenharmony_ci return 0; 513962306a36Sopenharmony_ci} 514062306a36Sopenharmony_ci 514162306a36Sopenharmony_cistatic int decode_rw_delegation(struct xdr_stream *xdr, 514262306a36Sopenharmony_ci uint32_t delegation_type, 514362306a36Sopenharmony_ci struct nfs_openres *res) 514462306a36Sopenharmony_ci{ 514562306a36Sopenharmony_ci __be32 *p; 514662306a36Sopenharmony_ci int status; 514762306a36Sopenharmony_ci 514862306a36Sopenharmony_ci status = decode_delegation_stateid(xdr, &res->delegation); 514962306a36Sopenharmony_ci if (unlikely(status)) 515062306a36Sopenharmony_ci return status; 515162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 515262306a36Sopenharmony_ci if (unlikely(!p)) 515362306a36Sopenharmony_ci return -EIO; 515462306a36Sopenharmony_ci res->do_recall = be32_to_cpup(p); 515562306a36Sopenharmony_ci 515662306a36Sopenharmony_ci switch (delegation_type) { 515762306a36Sopenharmony_ci case NFS4_OPEN_DELEGATE_READ: 515862306a36Sopenharmony_ci res->delegation_type = FMODE_READ; 515962306a36Sopenharmony_ci break; 516062306a36Sopenharmony_ci case NFS4_OPEN_DELEGATE_WRITE: 516162306a36Sopenharmony_ci res->delegation_type = FMODE_WRITE|FMODE_READ; 516262306a36Sopenharmony_ci if (decode_space_limit(xdr, &res->pagemod_limit) < 0) 516362306a36Sopenharmony_ci return -EIO; 516462306a36Sopenharmony_ci } 516562306a36Sopenharmony_ci return decode_ace(xdr, NULL); 516662306a36Sopenharmony_ci} 516762306a36Sopenharmony_ci 516862306a36Sopenharmony_cistatic int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) 516962306a36Sopenharmony_ci{ 517062306a36Sopenharmony_ci __be32 *p; 517162306a36Sopenharmony_ci uint32_t why_no_delegation; 517262306a36Sopenharmony_ci 517362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 517462306a36Sopenharmony_ci if (unlikely(!p)) 517562306a36Sopenharmony_ci return -EIO; 517662306a36Sopenharmony_ci why_no_delegation = be32_to_cpup(p); 517762306a36Sopenharmony_ci switch (why_no_delegation) { 517862306a36Sopenharmony_ci case WND4_CONTENTION: 517962306a36Sopenharmony_ci case WND4_RESOURCE: 518062306a36Sopenharmony_ci xdr_inline_decode(xdr, 4); 518162306a36Sopenharmony_ci /* Ignore for now */ 518262306a36Sopenharmony_ci } 518362306a36Sopenharmony_ci return 0; 518462306a36Sopenharmony_ci} 518562306a36Sopenharmony_ci 518662306a36Sopenharmony_cistatic int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) 518762306a36Sopenharmony_ci{ 518862306a36Sopenharmony_ci __be32 *p; 518962306a36Sopenharmony_ci uint32_t delegation_type; 519062306a36Sopenharmony_ci 519162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 519262306a36Sopenharmony_ci if (unlikely(!p)) 519362306a36Sopenharmony_ci return -EIO; 519462306a36Sopenharmony_ci delegation_type = be32_to_cpup(p); 519562306a36Sopenharmony_ci res->delegation_type = 0; 519662306a36Sopenharmony_ci switch (delegation_type) { 519762306a36Sopenharmony_ci case NFS4_OPEN_DELEGATE_NONE: 519862306a36Sopenharmony_ci return 0; 519962306a36Sopenharmony_ci case NFS4_OPEN_DELEGATE_READ: 520062306a36Sopenharmony_ci case NFS4_OPEN_DELEGATE_WRITE: 520162306a36Sopenharmony_ci return decode_rw_delegation(xdr, delegation_type, res); 520262306a36Sopenharmony_ci case NFS4_OPEN_DELEGATE_NONE_EXT: 520362306a36Sopenharmony_ci return decode_no_delegation(xdr, res); 520462306a36Sopenharmony_ci } 520562306a36Sopenharmony_ci return -EIO; 520662306a36Sopenharmony_ci} 520762306a36Sopenharmony_ci 520862306a36Sopenharmony_cistatic int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) 520962306a36Sopenharmony_ci{ 521062306a36Sopenharmony_ci __be32 *p; 521162306a36Sopenharmony_ci uint32_t savewords, bmlen, i; 521262306a36Sopenharmony_ci int status; 521362306a36Sopenharmony_ci 521462306a36Sopenharmony_ci if (!__decode_op_hdr(xdr, OP_OPEN, &status)) 521562306a36Sopenharmony_ci return status; 521662306a36Sopenharmony_ci nfs_increment_open_seqid(status, res->seqid); 521762306a36Sopenharmony_ci if (status) 521862306a36Sopenharmony_ci return status; 521962306a36Sopenharmony_ci status = decode_open_stateid(xdr, &res->stateid); 522062306a36Sopenharmony_ci if (unlikely(status)) 522162306a36Sopenharmony_ci return status; 522262306a36Sopenharmony_ci 522362306a36Sopenharmony_ci decode_change_info(xdr, &res->cinfo); 522462306a36Sopenharmony_ci 522562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 522662306a36Sopenharmony_ci if (unlikely(!p)) 522762306a36Sopenharmony_ci return -EIO; 522862306a36Sopenharmony_ci res->rflags = be32_to_cpup(p++); 522962306a36Sopenharmony_ci bmlen = be32_to_cpup(p); 523062306a36Sopenharmony_ci if (bmlen > 10) 523162306a36Sopenharmony_ci goto xdr_error; 523262306a36Sopenharmony_ci 523362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, bmlen << 2); 523462306a36Sopenharmony_ci if (unlikely(!p)) 523562306a36Sopenharmony_ci return -EIO; 523662306a36Sopenharmony_ci savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); 523762306a36Sopenharmony_ci for (i = 0; i < savewords; ++i) 523862306a36Sopenharmony_ci res->attrset[i] = be32_to_cpup(p++); 523962306a36Sopenharmony_ci for (; i < NFS4_BITMAP_SIZE; i++) 524062306a36Sopenharmony_ci res->attrset[i] = 0; 524162306a36Sopenharmony_ci 524262306a36Sopenharmony_ci return decode_delegation(xdr, res); 524362306a36Sopenharmony_cixdr_error: 524462306a36Sopenharmony_ci dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); 524562306a36Sopenharmony_ci return -EIO; 524662306a36Sopenharmony_ci} 524762306a36Sopenharmony_ci 524862306a36Sopenharmony_cistatic int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) 524962306a36Sopenharmony_ci{ 525062306a36Sopenharmony_ci int status; 525162306a36Sopenharmony_ci 525262306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_OPEN_CONFIRM); 525362306a36Sopenharmony_ci if (status != -EIO) 525462306a36Sopenharmony_ci nfs_increment_open_seqid(status, res->seqid); 525562306a36Sopenharmony_ci if (!status) 525662306a36Sopenharmony_ci status = decode_open_stateid(xdr, &res->stateid); 525762306a36Sopenharmony_ci return status; 525862306a36Sopenharmony_ci} 525962306a36Sopenharmony_ci 526062306a36Sopenharmony_cistatic int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res) 526162306a36Sopenharmony_ci{ 526262306a36Sopenharmony_ci int status; 526362306a36Sopenharmony_ci 526462306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE); 526562306a36Sopenharmony_ci if (status != -EIO) 526662306a36Sopenharmony_ci nfs_increment_open_seqid(status, res->seqid); 526762306a36Sopenharmony_ci if (!status) 526862306a36Sopenharmony_ci status = decode_open_stateid(xdr, &res->stateid); 526962306a36Sopenharmony_ci return status; 527062306a36Sopenharmony_ci} 527162306a36Sopenharmony_ci 527262306a36Sopenharmony_cistatic int decode_putfh(struct xdr_stream *xdr) 527362306a36Sopenharmony_ci{ 527462306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_PUTFH); 527562306a36Sopenharmony_ci} 527662306a36Sopenharmony_ci 527762306a36Sopenharmony_cistatic int decode_putrootfh(struct xdr_stream *xdr) 527862306a36Sopenharmony_ci{ 527962306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_PUTROOTFH); 528062306a36Sopenharmony_ci} 528162306a36Sopenharmony_ci 528262306a36Sopenharmony_cistatic int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, 528362306a36Sopenharmony_ci struct nfs_pgio_res *res) 528462306a36Sopenharmony_ci{ 528562306a36Sopenharmony_ci __be32 *p; 528662306a36Sopenharmony_ci uint32_t count, eof, recvd; 528762306a36Sopenharmony_ci int status; 528862306a36Sopenharmony_ci 528962306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_READ); 529062306a36Sopenharmony_ci if (status) 529162306a36Sopenharmony_ci return status; 529262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 529362306a36Sopenharmony_ci if (unlikely(!p)) 529462306a36Sopenharmony_ci return -EIO; 529562306a36Sopenharmony_ci eof = be32_to_cpup(p++); 529662306a36Sopenharmony_ci count = be32_to_cpup(p); 529762306a36Sopenharmony_ci recvd = xdr_read_pages(xdr, count); 529862306a36Sopenharmony_ci if (count > recvd) { 529962306a36Sopenharmony_ci dprintk("NFS: server cheating in read reply: " 530062306a36Sopenharmony_ci "count %u > recvd %u\n", count, recvd); 530162306a36Sopenharmony_ci count = recvd; 530262306a36Sopenharmony_ci eof = 0; 530362306a36Sopenharmony_ci } 530462306a36Sopenharmony_ci res->eof = eof; 530562306a36Sopenharmony_ci res->count = count; 530662306a36Sopenharmony_ci return 0; 530762306a36Sopenharmony_ci} 530862306a36Sopenharmony_ci 530962306a36Sopenharmony_cistatic int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) 531062306a36Sopenharmony_ci{ 531162306a36Sopenharmony_ci int status; 531262306a36Sopenharmony_ci __be32 verf[2]; 531362306a36Sopenharmony_ci 531462306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_READDIR); 531562306a36Sopenharmony_ci if (!status) 531662306a36Sopenharmony_ci status = decode_verifier(xdr, readdir->verifier.data); 531762306a36Sopenharmony_ci if (unlikely(status)) 531862306a36Sopenharmony_ci return status; 531962306a36Sopenharmony_ci memcpy(verf, readdir->verifier.data, sizeof(verf)); 532062306a36Sopenharmony_ci dprintk("%s: verifier = %08x:%08x\n", 532162306a36Sopenharmony_ci __func__, verf[0], verf[1]); 532262306a36Sopenharmony_ci return xdr_read_pages(xdr, xdr->buf->page_len); 532362306a36Sopenharmony_ci} 532462306a36Sopenharmony_ci 532562306a36Sopenharmony_cistatic int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) 532662306a36Sopenharmony_ci{ 532762306a36Sopenharmony_ci struct xdr_buf *rcvbuf = &req->rq_rcv_buf; 532862306a36Sopenharmony_ci u32 len, recvd; 532962306a36Sopenharmony_ci __be32 *p; 533062306a36Sopenharmony_ci int status; 533162306a36Sopenharmony_ci 533262306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_READLINK); 533362306a36Sopenharmony_ci if (status) 533462306a36Sopenharmony_ci return status; 533562306a36Sopenharmony_ci 533662306a36Sopenharmony_ci /* Convert length of symlink */ 533762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 533862306a36Sopenharmony_ci if (unlikely(!p)) 533962306a36Sopenharmony_ci return -EIO; 534062306a36Sopenharmony_ci len = be32_to_cpup(p); 534162306a36Sopenharmony_ci if (len >= rcvbuf->page_len || len <= 0) { 534262306a36Sopenharmony_ci dprintk("nfs: server returned giant symlink!\n"); 534362306a36Sopenharmony_ci return -ENAMETOOLONG; 534462306a36Sopenharmony_ci } 534562306a36Sopenharmony_ci recvd = xdr_read_pages(xdr, len); 534662306a36Sopenharmony_ci if (recvd < len) { 534762306a36Sopenharmony_ci dprintk("NFS: server cheating in readlink reply: " 534862306a36Sopenharmony_ci "count %u > recvd %u\n", len, recvd); 534962306a36Sopenharmony_ci return -EIO; 535062306a36Sopenharmony_ci } 535162306a36Sopenharmony_ci /* 535262306a36Sopenharmony_ci * The XDR encode routine has set things up so that 535362306a36Sopenharmony_ci * the link text will be copied directly into the 535462306a36Sopenharmony_ci * buffer. We just have to do overflow-checking, 535562306a36Sopenharmony_ci * and null-terminate the text (the VFS expects 535662306a36Sopenharmony_ci * null-termination). 535762306a36Sopenharmony_ci */ 535862306a36Sopenharmony_ci xdr_terminate_string(rcvbuf, len); 535962306a36Sopenharmony_ci return 0; 536062306a36Sopenharmony_ci} 536162306a36Sopenharmony_ci 536262306a36Sopenharmony_cistatic int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) 536362306a36Sopenharmony_ci{ 536462306a36Sopenharmony_ci int status; 536562306a36Sopenharmony_ci 536662306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_REMOVE); 536762306a36Sopenharmony_ci if (status) 536862306a36Sopenharmony_ci goto out; 536962306a36Sopenharmony_ci status = decode_change_info(xdr, cinfo); 537062306a36Sopenharmony_ciout: 537162306a36Sopenharmony_ci return status; 537262306a36Sopenharmony_ci} 537362306a36Sopenharmony_ci 537462306a36Sopenharmony_cistatic int decode_rename(struct xdr_stream *xdr, struct nfs4_change_info *old_cinfo, 537562306a36Sopenharmony_ci struct nfs4_change_info *new_cinfo) 537662306a36Sopenharmony_ci{ 537762306a36Sopenharmony_ci int status; 537862306a36Sopenharmony_ci 537962306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_RENAME); 538062306a36Sopenharmony_ci if (status) 538162306a36Sopenharmony_ci goto out; 538262306a36Sopenharmony_ci if ((status = decode_change_info(xdr, old_cinfo))) 538362306a36Sopenharmony_ci goto out; 538462306a36Sopenharmony_ci status = decode_change_info(xdr, new_cinfo); 538562306a36Sopenharmony_ciout: 538662306a36Sopenharmony_ci return status; 538762306a36Sopenharmony_ci} 538862306a36Sopenharmony_ci 538962306a36Sopenharmony_cistatic int decode_renew(struct xdr_stream *xdr) 539062306a36Sopenharmony_ci{ 539162306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_RENEW); 539262306a36Sopenharmony_ci} 539362306a36Sopenharmony_ci 539462306a36Sopenharmony_cistatic int 539562306a36Sopenharmony_cidecode_restorefh(struct xdr_stream *xdr) 539662306a36Sopenharmony_ci{ 539762306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_RESTOREFH); 539862306a36Sopenharmony_ci} 539962306a36Sopenharmony_ci 540062306a36Sopenharmony_cistatic int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, 540162306a36Sopenharmony_ci struct nfs_getaclres *res, enum nfs4_acl_type type) 540262306a36Sopenharmony_ci{ 540362306a36Sopenharmony_ci unsigned int savep; 540462306a36Sopenharmony_ci uint32_t attrlen, 540562306a36Sopenharmony_ci bitmap[3] = {0}; 540662306a36Sopenharmony_ci int status; 540762306a36Sopenharmony_ci 540862306a36Sopenharmony_ci res->acl_len = 0; 540962306a36Sopenharmony_ci if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 541062306a36Sopenharmony_ci goto out; 541162306a36Sopenharmony_ci 541262306a36Sopenharmony_ci xdr_enter_page(xdr, xdr->buf->page_len); 541362306a36Sopenharmony_ci 541462306a36Sopenharmony_ci if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 541562306a36Sopenharmony_ci goto out; 541662306a36Sopenharmony_ci if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 541762306a36Sopenharmony_ci goto out; 541862306a36Sopenharmony_ci 541962306a36Sopenharmony_ci switch (type) { 542062306a36Sopenharmony_ci default: 542162306a36Sopenharmony_ci if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) 542262306a36Sopenharmony_ci return -EIO; 542362306a36Sopenharmony_ci if (!(bitmap[0] & FATTR4_WORD0_ACL)) 542462306a36Sopenharmony_ci return -EOPNOTSUPP; 542562306a36Sopenharmony_ci break; 542662306a36Sopenharmony_ci case NFS4ACL_DACL: 542762306a36Sopenharmony_ci if (unlikely(bitmap[0] || bitmap[1] & (FATTR4_WORD1_DACL - 1U))) 542862306a36Sopenharmony_ci return -EIO; 542962306a36Sopenharmony_ci if (!(bitmap[1] & FATTR4_WORD1_DACL)) 543062306a36Sopenharmony_ci return -EOPNOTSUPP; 543162306a36Sopenharmony_ci break; 543262306a36Sopenharmony_ci case NFS4ACL_SACL: 543362306a36Sopenharmony_ci if (unlikely(bitmap[0] || bitmap[1] & (FATTR4_WORD1_SACL - 1U))) 543462306a36Sopenharmony_ci return -EIO; 543562306a36Sopenharmony_ci if (!(bitmap[1] & FATTR4_WORD1_SACL)) 543662306a36Sopenharmony_ci return -EOPNOTSUPP; 543762306a36Sopenharmony_ci } 543862306a36Sopenharmony_ci 543962306a36Sopenharmony_ci /* The bitmap (xdr len + bitmaps) and the attr xdr len words 544062306a36Sopenharmony_ci * are stored with the acl data to handle the problem of 544162306a36Sopenharmony_ci * variable length bitmaps.*/ 544262306a36Sopenharmony_ci res->acl_data_offset = xdr_page_pos(xdr); 544362306a36Sopenharmony_ci res->acl_len = attrlen; 544462306a36Sopenharmony_ci 544562306a36Sopenharmony_ci /* Check for receive buffer overflow */ 544662306a36Sopenharmony_ci if (res->acl_len > xdr_stream_remaining(xdr) || 544762306a36Sopenharmony_ci res->acl_len + res->acl_data_offset > xdr->buf->page_len) { 544862306a36Sopenharmony_ci res->acl_flags |= NFS4_ACL_TRUNC; 544962306a36Sopenharmony_ci dprintk("NFS: acl reply: attrlen %u > page_len %zu\n", 545062306a36Sopenharmony_ci attrlen, xdr_stream_remaining(xdr)); 545162306a36Sopenharmony_ci } 545262306a36Sopenharmony_ciout: 545362306a36Sopenharmony_ci return status; 545462306a36Sopenharmony_ci} 545562306a36Sopenharmony_ci 545662306a36Sopenharmony_cistatic int 545762306a36Sopenharmony_cidecode_savefh(struct xdr_stream *xdr) 545862306a36Sopenharmony_ci{ 545962306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_SAVEFH); 546062306a36Sopenharmony_ci} 546162306a36Sopenharmony_ci 546262306a36Sopenharmony_cistatic int decode_setattr(struct xdr_stream *xdr) 546362306a36Sopenharmony_ci{ 546462306a36Sopenharmony_ci int status; 546562306a36Sopenharmony_ci 546662306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_SETATTR); 546762306a36Sopenharmony_ci if (status) 546862306a36Sopenharmony_ci return status; 546962306a36Sopenharmony_ci if (decode_bitmap4(xdr, NULL, 0) >= 0) 547062306a36Sopenharmony_ci return 0; 547162306a36Sopenharmony_ci return -EIO; 547262306a36Sopenharmony_ci} 547362306a36Sopenharmony_ci 547462306a36Sopenharmony_cistatic int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_res *res) 547562306a36Sopenharmony_ci{ 547662306a36Sopenharmony_ci __be32 *p; 547762306a36Sopenharmony_ci uint32_t opnum; 547862306a36Sopenharmony_ci int32_t nfserr; 547962306a36Sopenharmony_ci 548062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 548162306a36Sopenharmony_ci if (unlikely(!p)) 548262306a36Sopenharmony_ci return -EIO; 548362306a36Sopenharmony_ci opnum = be32_to_cpup(p++); 548462306a36Sopenharmony_ci if (opnum != OP_SETCLIENTID) { 548562306a36Sopenharmony_ci dprintk("nfs: decode_setclientid: Server returned operation" 548662306a36Sopenharmony_ci " %d\n", opnum); 548762306a36Sopenharmony_ci return -EIO; 548862306a36Sopenharmony_ci } 548962306a36Sopenharmony_ci nfserr = be32_to_cpup(p); 549062306a36Sopenharmony_ci if (nfserr == NFS_OK) { 549162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE); 549262306a36Sopenharmony_ci if (unlikely(!p)) 549362306a36Sopenharmony_ci return -EIO; 549462306a36Sopenharmony_ci p = xdr_decode_hyper(p, &res->clientid); 549562306a36Sopenharmony_ci memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE); 549662306a36Sopenharmony_ci } else if (nfserr == NFSERR_CLID_INUSE) { 549762306a36Sopenharmony_ci uint32_t len; 549862306a36Sopenharmony_ci 549962306a36Sopenharmony_ci /* skip netid string */ 550062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 550162306a36Sopenharmony_ci if (unlikely(!p)) 550262306a36Sopenharmony_ci return -EIO; 550362306a36Sopenharmony_ci len = be32_to_cpup(p); 550462306a36Sopenharmony_ci p = xdr_inline_decode(xdr, len); 550562306a36Sopenharmony_ci if (unlikely(!p)) 550662306a36Sopenharmony_ci return -EIO; 550762306a36Sopenharmony_ci 550862306a36Sopenharmony_ci /* skip uaddr string */ 550962306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 551062306a36Sopenharmony_ci if (unlikely(!p)) 551162306a36Sopenharmony_ci return -EIO; 551262306a36Sopenharmony_ci len = be32_to_cpup(p); 551362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, len); 551462306a36Sopenharmony_ci if (unlikely(!p)) 551562306a36Sopenharmony_ci return -EIO; 551662306a36Sopenharmony_ci return -NFSERR_CLID_INUSE; 551762306a36Sopenharmony_ci } else 551862306a36Sopenharmony_ci return nfs4_stat_to_errno(nfserr); 551962306a36Sopenharmony_ci 552062306a36Sopenharmony_ci return 0; 552162306a36Sopenharmony_ci} 552262306a36Sopenharmony_ci 552362306a36Sopenharmony_cistatic int decode_setclientid_confirm(struct xdr_stream *xdr) 552462306a36Sopenharmony_ci{ 552562306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_SETCLIENTID_CONFIRM); 552662306a36Sopenharmony_ci} 552762306a36Sopenharmony_ci 552862306a36Sopenharmony_cistatic int decode_write(struct xdr_stream *xdr, struct nfs_pgio_res *res) 552962306a36Sopenharmony_ci{ 553062306a36Sopenharmony_ci __be32 *p; 553162306a36Sopenharmony_ci int status; 553262306a36Sopenharmony_ci 553362306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_WRITE); 553462306a36Sopenharmony_ci if (status) 553562306a36Sopenharmony_ci return status; 553662306a36Sopenharmony_ci 553762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 553862306a36Sopenharmony_ci if (unlikely(!p)) 553962306a36Sopenharmony_ci return -EIO; 554062306a36Sopenharmony_ci res->count = be32_to_cpup(p++); 554162306a36Sopenharmony_ci res->verf->committed = be32_to_cpup(p++); 554262306a36Sopenharmony_ci return decode_write_verifier(xdr, &res->verf->verifier); 554362306a36Sopenharmony_ci} 554462306a36Sopenharmony_ci 554562306a36Sopenharmony_cistatic int decode_delegreturn(struct xdr_stream *xdr) 554662306a36Sopenharmony_ci{ 554762306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_DELEGRETURN); 554862306a36Sopenharmony_ci} 554962306a36Sopenharmony_ci 555062306a36Sopenharmony_cistatic int decode_secinfo_gss(struct xdr_stream *xdr, 555162306a36Sopenharmony_ci struct nfs4_secinfo4 *flavor) 555262306a36Sopenharmony_ci{ 555362306a36Sopenharmony_ci u32 oid_len; 555462306a36Sopenharmony_ci __be32 *p; 555562306a36Sopenharmony_ci 555662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 555762306a36Sopenharmony_ci if (unlikely(!p)) 555862306a36Sopenharmony_ci return -EIO; 555962306a36Sopenharmony_ci oid_len = be32_to_cpup(p); 556062306a36Sopenharmony_ci if (oid_len > GSS_OID_MAX_LEN) 556162306a36Sopenharmony_ci return -EINVAL; 556262306a36Sopenharmony_ci 556362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, oid_len); 556462306a36Sopenharmony_ci if (unlikely(!p)) 556562306a36Sopenharmony_ci return -EIO; 556662306a36Sopenharmony_ci memcpy(flavor->flavor_info.oid.data, p, oid_len); 556762306a36Sopenharmony_ci flavor->flavor_info.oid.len = oid_len; 556862306a36Sopenharmony_ci 556962306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 557062306a36Sopenharmony_ci if (unlikely(!p)) 557162306a36Sopenharmony_ci return -EIO; 557262306a36Sopenharmony_ci flavor->flavor_info.qop = be32_to_cpup(p++); 557362306a36Sopenharmony_ci flavor->flavor_info.service = be32_to_cpup(p); 557462306a36Sopenharmony_ci 557562306a36Sopenharmony_ci return 0; 557662306a36Sopenharmony_ci} 557762306a36Sopenharmony_ci 557862306a36Sopenharmony_cistatic int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) 557962306a36Sopenharmony_ci{ 558062306a36Sopenharmony_ci struct nfs4_secinfo4 *sec_flavor; 558162306a36Sopenharmony_ci unsigned int i, num_flavors; 558262306a36Sopenharmony_ci int status; 558362306a36Sopenharmony_ci __be32 *p; 558462306a36Sopenharmony_ci 558562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 558662306a36Sopenharmony_ci if (unlikely(!p)) 558762306a36Sopenharmony_ci return -EIO; 558862306a36Sopenharmony_ci 558962306a36Sopenharmony_ci res->flavors->num_flavors = 0; 559062306a36Sopenharmony_ci num_flavors = be32_to_cpup(p); 559162306a36Sopenharmony_ci 559262306a36Sopenharmony_ci for (i = 0; i < num_flavors; i++) { 559362306a36Sopenharmony_ci sec_flavor = &res->flavors->flavors[i]; 559462306a36Sopenharmony_ci if ((char *)&sec_flavor[1] - (char *)res->flavors > PAGE_SIZE) 559562306a36Sopenharmony_ci break; 559662306a36Sopenharmony_ci 559762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 559862306a36Sopenharmony_ci if (unlikely(!p)) 559962306a36Sopenharmony_ci return -EIO; 560062306a36Sopenharmony_ci sec_flavor->flavor = be32_to_cpup(p); 560162306a36Sopenharmony_ci 560262306a36Sopenharmony_ci if (sec_flavor->flavor == RPC_AUTH_GSS) { 560362306a36Sopenharmony_ci status = decode_secinfo_gss(xdr, sec_flavor); 560462306a36Sopenharmony_ci if (status) 560562306a36Sopenharmony_ci goto out; 560662306a36Sopenharmony_ci } 560762306a36Sopenharmony_ci res->flavors->num_flavors++; 560862306a36Sopenharmony_ci } 560962306a36Sopenharmony_ci 561062306a36Sopenharmony_ci status = 0; 561162306a36Sopenharmony_ciout: 561262306a36Sopenharmony_ci return status; 561362306a36Sopenharmony_ci} 561462306a36Sopenharmony_ci 561562306a36Sopenharmony_cistatic int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) 561662306a36Sopenharmony_ci{ 561762306a36Sopenharmony_ci int status = decode_op_hdr(xdr, OP_SECINFO); 561862306a36Sopenharmony_ci if (status) 561962306a36Sopenharmony_ci return status; 562062306a36Sopenharmony_ci return decode_secinfo_common(xdr, res); 562162306a36Sopenharmony_ci} 562262306a36Sopenharmony_ci 562362306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 562462306a36Sopenharmony_cistatic int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) 562562306a36Sopenharmony_ci{ 562662306a36Sopenharmony_ci int status = decode_op_hdr(xdr, OP_SECINFO_NO_NAME); 562762306a36Sopenharmony_ci if (status) 562862306a36Sopenharmony_ci return status; 562962306a36Sopenharmony_ci return decode_secinfo_common(xdr, res); 563062306a36Sopenharmony_ci} 563162306a36Sopenharmony_ci 563262306a36Sopenharmony_cistatic int decode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map) 563362306a36Sopenharmony_ci{ 563462306a36Sopenharmony_ci if (xdr_stream_decode_uint32_array(xdr, op_map->u.words, 563562306a36Sopenharmony_ci ARRAY_SIZE(op_map->u.words)) < 0) 563662306a36Sopenharmony_ci return -EIO; 563762306a36Sopenharmony_ci return 0; 563862306a36Sopenharmony_ci} 563962306a36Sopenharmony_ci 564062306a36Sopenharmony_cistatic int decode_exchange_id(struct xdr_stream *xdr, 564162306a36Sopenharmony_ci struct nfs41_exchange_id_res *res) 564262306a36Sopenharmony_ci{ 564362306a36Sopenharmony_ci __be32 *p; 564462306a36Sopenharmony_ci uint32_t dummy; 564562306a36Sopenharmony_ci char *dummy_str; 564662306a36Sopenharmony_ci int status; 564762306a36Sopenharmony_ci uint32_t impl_id_count; 564862306a36Sopenharmony_ci 564962306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_EXCHANGE_ID); 565062306a36Sopenharmony_ci if (status) 565162306a36Sopenharmony_ci return status; 565262306a36Sopenharmony_ci 565362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 565462306a36Sopenharmony_ci if (unlikely(!p)) 565562306a36Sopenharmony_ci return -EIO; 565662306a36Sopenharmony_ci xdr_decode_hyper(p, &res->clientid); 565762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 12); 565862306a36Sopenharmony_ci if (unlikely(!p)) 565962306a36Sopenharmony_ci return -EIO; 566062306a36Sopenharmony_ci res->seqid = be32_to_cpup(p++); 566162306a36Sopenharmony_ci res->flags = be32_to_cpup(p++); 566262306a36Sopenharmony_ci 566362306a36Sopenharmony_ci res->state_protect.how = be32_to_cpup(p); 566462306a36Sopenharmony_ci switch (res->state_protect.how) { 566562306a36Sopenharmony_ci case SP4_NONE: 566662306a36Sopenharmony_ci break; 566762306a36Sopenharmony_ci case SP4_MACH_CRED: 566862306a36Sopenharmony_ci status = decode_op_map(xdr, &res->state_protect.enforce); 566962306a36Sopenharmony_ci if (status) 567062306a36Sopenharmony_ci return status; 567162306a36Sopenharmony_ci status = decode_op_map(xdr, &res->state_protect.allow); 567262306a36Sopenharmony_ci if (status) 567362306a36Sopenharmony_ci return status; 567462306a36Sopenharmony_ci break; 567562306a36Sopenharmony_ci default: 567662306a36Sopenharmony_ci WARN_ON_ONCE(1); 567762306a36Sopenharmony_ci return -EIO; 567862306a36Sopenharmony_ci } 567962306a36Sopenharmony_ci 568062306a36Sopenharmony_ci /* server_owner4.so_minor_id */ 568162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 568262306a36Sopenharmony_ci if (unlikely(!p)) 568362306a36Sopenharmony_ci return -EIO; 568462306a36Sopenharmony_ci p = xdr_decode_hyper(p, &res->server_owner->minor_id); 568562306a36Sopenharmony_ci 568662306a36Sopenharmony_ci /* server_owner4.so_major_id */ 568762306a36Sopenharmony_ci status = decode_opaque_inline(xdr, &dummy, &dummy_str); 568862306a36Sopenharmony_ci if (unlikely(status)) 568962306a36Sopenharmony_ci return status; 569062306a36Sopenharmony_ci memcpy(res->server_owner->major_id, dummy_str, dummy); 569162306a36Sopenharmony_ci res->server_owner->major_id_sz = dummy; 569262306a36Sopenharmony_ci 569362306a36Sopenharmony_ci /* server_scope4 */ 569462306a36Sopenharmony_ci status = decode_opaque_inline(xdr, &dummy, &dummy_str); 569562306a36Sopenharmony_ci if (unlikely(status)) 569662306a36Sopenharmony_ci return status; 569762306a36Sopenharmony_ci memcpy(res->server_scope->server_scope, dummy_str, dummy); 569862306a36Sopenharmony_ci res->server_scope->server_scope_sz = dummy; 569962306a36Sopenharmony_ci 570062306a36Sopenharmony_ci /* Implementation Id */ 570162306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 570262306a36Sopenharmony_ci if (unlikely(!p)) 570362306a36Sopenharmony_ci return -EIO; 570462306a36Sopenharmony_ci impl_id_count = be32_to_cpup(p++); 570562306a36Sopenharmony_ci 570662306a36Sopenharmony_ci if (impl_id_count) { 570762306a36Sopenharmony_ci /* nii_domain */ 570862306a36Sopenharmony_ci status = decode_opaque_inline(xdr, &dummy, &dummy_str); 570962306a36Sopenharmony_ci if (unlikely(status)) 571062306a36Sopenharmony_ci return status; 571162306a36Sopenharmony_ci memcpy(res->impl_id->domain, dummy_str, dummy); 571262306a36Sopenharmony_ci 571362306a36Sopenharmony_ci /* nii_name */ 571462306a36Sopenharmony_ci status = decode_opaque_inline(xdr, &dummy, &dummy_str); 571562306a36Sopenharmony_ci if (unlikely(status)) 571662306a36Sopenharmony_ci return status; 571762306a36Sopenharmony_ci memcpy(res->impl_id->name, dummy_str, dummy); 571862306a36Sopenharmony_ci 571962306a36Sopenharmony_ci /* nii_date */ 572062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 12); 572162306a36Sopenharmony_ci if (unlikely(!p)) 572262306a36Sopenharmony_ci return -EIO; 572362306a36Sopenharmony_ci p = xdr_decode_hyper(p, &res->impl_id->date.seconds); 572462306a36Sopenharmony_ci res->impl_id->date.nseconds = be32_to_cpup(p); 572562306a36Sopenharmony_ci 572662306a36Sopenharmony_ci /* if there's more than one entry, ignore the rest */ 572762306a36Sopenharmony_ci } 572862306a36Sopenharmony_ci return 0; 572962306a36Sopenharmony_ci} 573062306a36Sopenharmony_ci 573162306a36Sopenharmony_cistatic int decode_chan_attrs(struct xdr_stream *xdr, 573262306a36Sopenharmony_ci struct nfs4_channel_attrs *attrs) 573362306a36Sopenharmony_ci{ 573462306a36Sopenharmony_ci __be32 *p; 573562306a36Sopenharmony_ci u32 nr_attrs, val; 573662306a36Sopenharmony_ci 573762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 28); 573862306a36Sopenharmony_ci if (unlikely(!p)) 573962306a36Sopenharmony_ci return -EIO; 574062306a36Sopenharmony_ci val = be32_to_cpup(p++); /* headerpadsz */ 574162306a36Sopenharmony_ci if (val) 574262306a36Sopenharmony_ci return -EINVAL; /* no support for header padding yet */ 574362306a36Sopenharmony_ci attrs->max_rqst_sz = be32_to_cpup(p++); 574462306a36Sopenharmony_ci attrs->max_resp_sz = be32_to_cpup(p++); 574562306a36Sopenharmony_ci attrs->max_resp_sz_cached = be32_to_cpup(p++); 574662306a36Sopenharmony_ci attrs->max_ops = be32_to_cpup(p++); 574762306a36Sopenharmony_ci attrs->max_reqs = be32_to_cpup(p++); 574862306a36Sopenharmony_ci nr_attrs = be32_to_cpup(p); 574962306a36Sopenharmony_ci if (unlikely(nr_attrs > 1)) { 575062306a36Sopenharmony_ci printk(KERN_WARNING "NFS: %s: Invalid rdma channel attrs " 575162306a36Sopenharmony_ci "count %u\n", __func__, nr_attrs); 575262306a36Sopenharmony_ci return -EINVAL; 575362306a36Sopenharmony_ci } 575462306a36Sopenharmony_ci if (nr_attrs == 1) { 575562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */ 575662306a36Sopenharmony_ci if (unlikely(!p)) 575762306a36Sopenharmony_ci return -EIO; 575862306a36Sopenharmony_ci } 575962306a36Sopenharmony_ci return 0; 576062306a36Sopenharmony_ci} 576162306a36Sopenharmony_ci 576262306a36Sopenharmony_cistatic int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid) 576362306a36Sopenharmony_ci{ 576462306a36Sopenharmony_ci return decode_opaque_fixed(xdr, sid->data, NFS4_MAX_SESSIONID_LEN); 576562306a36Sopenharmony_ci} 576662306a36Sopenharmony_ci 576762306a36Sopenharmony_cistatic int decode_bind_conn_to_session(struct xdr_stream *xdr, 576862306a36Sopenharmony_ci struct nfs41_bind_conn_to_session_res *res) 576962306a36Sopenharmony_ci{ 577062306a36Sopenharmony_ci __be32 *p; 577162306a36Sopenharmony_ci int status; 577262306a36Sopenharmony_ci 577362306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION); 577462306a36Sopenharmony_ci if (!status) 577562306a36Sopenharmony_ci status = decode_sessionid(xdr, &res->sessionid); 577662306a36Sopenharmony_ci if (unlikely(status)) 577762306a36Sopenharmony_ci return status; 577862306a36Sopenharmony_ci 577962306a36Sopenharmony_ci /* dir flags, rdma mode bool */ 578062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 578162306a36Sopenharmony_ci if (unlikely(!p)) 578262306a36Sopenharmony_ci return -EIO; 578362306a36Sopenharmony_ci 578462306a36Sopenharmony_ci res->dir = be32_to_cpup(p++); 578562306a36Sopenharmony_ci if (res->dir == 0 || res->dir > NFS4_CDFS4_BOTH) 578662306a36Sopenharmony_ci return -EIO; 578762306a36Sopenharmony_ci if (be32_to_cpup(p) == 0) 578862306a36Sopenharmony_ci res->use_conn_in_rdma_mode = false; 578962306a36Sopenharmony_ci else 579062306a36Sopenharmony_ci res->use_conn_in_rdma_mode = true; 579162306a36Sopenharmony_ci 579262306a36Sopenharmony_ci return 0; 579362306a36Sopenharmony_ci} 579462306a36Sopenharmony_ci 579562306a36Sopenharmony_cistatic int decode_create_session(struct xdr_stream *xdr, 579662306a36Sopenharmony_ci struct nfs41_create_session_res *res) 579762306a36Sopenharmony_ci{ 579862306a36Sopenharmony_ci __be32 *p; 579962306a36Sopenharmony_ci int status; 580062306a36Sopenharmony_ci 580162306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_CREATE_SESSION); 580262306a36Sopenharmony_ci if (!status) 580362306a36Sopenharmony_ci status = decode_sessionid(xdr, &res->sessionid); 580462306a36Sopenharmony_ci if (unlikely(status)) 580562306a36Sopenharmony_ci return status; 580662306a36Sopenharmony_ci 580762306a36Sopenharmony_ci /* seqid, flags */ 580862306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 580962306a36Sopenharmony_ci if (unlikely(!p)) 581062306a36Sopenharmony_ci return -EIO; 581162306a36Sopenharmony_ci res->seqid = be32_to_cpup(p++); 581262306a36Sopenharmony_ci res->flags = be32_to_cpup(p); 581362306a36Sopenharmony_ci 581462306a36Sopenharmony_ci /* Channel attributes */ 581562306a36Sopenharmony_ci status = decode_chan_attrs(xdr, &res->fc_attrs); 581662306a36Sopenharmony_ci if (!status) 581762306a36Sopenharmony_ci status = decode_chan_attrs(xdr, &res->bc_attrs); 581862306a36Sopenharmony_ci return status; 581962306a36Sopenharmony_ci} 582062306a36Sopenharmony_ci 582162306a36Sopenharmony_cistatic int decode_destroy_session(struct xdr_stream *xdr, void *dummy) 582262306a36Sopenharmony_ci{ 582362306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_DESTROY_SESSION); 582462306a36Sopenharmony_ci} 582562306a36Sopenharmony_ci 582662306a36Sopenharmony_cistatic int decode_destroy_clientid(struct xdr_stream *xdr, void *dummy) 582762306a36Sopenharmony_ci{ 582862306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_DESTROY_CLIENTID); 582962306a36Sopenharmony_ci} 583062306a36Sopenharmony_ci 583162306a36Sopenharmony_cistatic int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy) 583262306a36Sopenharmony_ci{ 583362306a36Sopenharmony_ci return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE); 583462306a36Sopenharmony_ci} 583562306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 583662306a36Sopenharmony_ci 583762306a36Sopenharmony_cistatic int decode_sequence(struct xdr_stream *xdr, 583862306a36Sopenharmony_ci struct nfs4_sequence_res *res, 583962306a36Sopenharmony_ci struct rpc_rqst *rqstp) 584062306a36Sopenharmony_ci{ 584162306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 584262306a36Sopenharmony_ci struct nfs4_session *session; 584362306a36Sopenharmony_ci struct nfs4_sessionid id; 584462306a36Sopenharmony_ci u32 dummy; 584562306a36Sopenharmony_ci int status; 584662306a36Sopenharmony_ci __be32 *p; 584762306a36Sopenharmony_ci 584862306a36Sopenharmony_ci if (res->sr_slot == NULL) 584962306a36Sopenharmony_ci return 0; 585062306a36Sopenharmony_ci if (!res->sr_slot->table->session) 585162306a36Sopenharmony_ci return 0; 585262306a36Sopenharmony_ci 585362306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_SEQUENCE); 585462306a36Sopenharmony_ci if (!status) 585562306a36Sopenharmony_ci status = decode_sessionid(xdr, &id); 585662306a36Sopenharmony_ci if (unlikely(status)) 585762306a36Sopenharmony_ci goto out_err; 585862306a36Sopenharmony_ci 585962306a36Sopenharmony_ci /* 586062306a36Sopenharmony_ci * If the server returns different values for sessionID, slotID or 586162306a36Sopenharmony_ci * sequence number, the server is looney tunes. 586262306a36Sopenharmony_ci */ 586362306a36Sopenharmony_ci status = -EREMOTEIO; 586462306a36Sopenharmony_ci session = res->sr_slot->table->session; 586562306a36Sopenharmony_ci 586662306a36Sopenharmony_ci if (memcmp(id.data, session->sess_id.data, 586762306a36Sopenharmony_ci NFS4_MAX_SESSIONID_LEN)) { 586862306a36Sopenharmony_ci dprintk("%s Invalid session id\n", __func__); 586962306a36Sopenharmony_ci goto out_err; 587062306a36Sopenharmony_ci } 587162306a36Sopenharmony_ci 587262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 20); 587362306a36Sopenharmony_ci if (unlikely(!p)) 587462306a36Sopenharmony_ci goto out_overflow; 587562306a36Sopenharmony_ci 587662306a36Sopenharmony_ci /* seqid */ 587762306a36Sopenharmony_ci dummy = be32_to_cpup(p++); 587862306a36Sopenharmony_ci if (dummy != res->sr_slot->seq_nr) { 587962306a36Sopenharmony_ci dprintk("%s Invalid sequence number\n", __func__); 588062306a36Sopenharmony_ci goto out_err; 588162306a36Sopenharmony_ci } 588262306a36Sopenharmony_ci /* slot id */ 588362306a36Sopenharmony_ci dummy = be32_to_cpup(p++); 588462306a36Sopenharmony_ci if (dummy != res->sr_slot->slot_nr) { 588562306a36Sopenharmony_ci dprintk("%s Invalid slot id\n", __func__); 588662306a36Sopenharmony_ci goto out_err; 588762306a36Sopenharmony_ci } 588862306a36Sopenharmony_ci /* highest slot id */ 588962306a36Sopenharmony_ci res->sr_highest_slotid = be32_to_cpup(p++); 589062306a36Sopenharmony_ci /* target highest slot id */ 589162306a36Sopenharmony_ci res->sr_target_highest_slotid = be32_to_cpup(p++); 589262306a36Sopenharmony_ci /* result flags */ 589362306a36Sopenharmony_ci res->sr_status_flags = be32_to_cpup(p); 589462306a36Sopenharmony_ci status = 0; 589562306a36Sopenharmony_ciout_err: 589662306a36Sopenharmony_ci res->sr_status = status; 589762306a36Sopenharmony_ci return status; 589862306a36Sopenharmony_ciout_overflow: 589962306a36Sopenharmony_ci status = -EIO; 590062306a36Sopenharmony_ci goto out_err; 590162306a36Sopenharmony_ci#else /* CONFIG_NFS_V4_1 */ 590262306a36Sopenharmony_ci return 0; 590362306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 590462306a36Sopenharmony_ci} 590562306a36Sopenharmony_ci 590662306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 590762306a36Sopenharmony_cistatic int decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) 590862306a36Sopenharmony_ci{ 590962306a36Sopenharmony_ci stateid->type = NFS4_LAYOUT_STATEID_TYPE; 591062306a36Sopenharmony_ci return decode_stateid(xdr, stateid); 591162306a36Sopenharmony_ci} 591262306a36Sopenharmony_ci 591362306a36Sopenharmony_cistatic int decode_getdeviceinfo(struct xdr_stream *xdr, 591462306a36Sopenharmony_ci struct nfs4_getdeviceinfo_res *res) 591562306a36Sopenharmony_ci{ 591662306a36Sopenharmony_ci struct pnfs_device *pdev = res->pdev; 591762306a36Sopenharmony_ci __be32 *p; 591862306a36Sopenharmony_ci uint32_t len, type; 591962306a36Sopenharmony_ci int status; 592062306a36Sopenharmony_ci 592162306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_GETDEVICEINFO); 592262306a36Sopenharmony_ci if (status) { 592362306a36Sopenharmony_ci if (status == -ETOOSMALL) { 592462306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 592562306a36Sopenharmony_ci if (unlikely(!p)) 592662306a36Sopenharmony_ci return -EIO; 592762306a36Sopenharmony_ci pdev->mincount = be32_to_cpup(p); 592862306a36Sopenharmony_ci dprintk("%s: Min count too small. mincnt = %u\n", 592962306a36Sopenharmony_ci __func__, pdev->mincount); 593062306a36Sopenharmony_ci } 593162306a36Sopenharmony_ci return status; 593262306a36Sopenharmony_ci } 593362306a36Sopenharmony_ci 593462306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 593562306a36Sopenharmony_ci if (unlikely(!p)) 593662306a36Sopenharmony_ci return -EIO; 593762306a36Sopenharmony_ci type = be32_to_cpup(p++); 593862306a36Sopenharmony_ci if (type != pdev->layout_type) { 593962306a36Sopenharmony_ci dprintk("%s: layout mismatch req: %u pdev: %u\n", 594062306a36Sopenharmony_ci __func__, pdev->layout_type, type); 594162306a36Sopenharmony_ci return -EINVAL; 594262306a36Sopenharmony_ci } 594362306a36Sopenharmony_ci /* 594462306a36Sopenharmony_ci * Get the length of the opaque device_addr4. xdr_read_pages places 594562306a36Sopenharmony_ci * the opaque device_addr4 in the xdr_buf->pages (pnfs_device->pages) 594662306a36Sopenharmony_ci * and places the remaining xdr data in xdr_buf->tail 594762306a36Sopenharmony_ci */ 594862306a36Sopenharmony_ci pdev->mincount = be32_to_cpup(p); 594962306a36Sopenharmony_ci if (xdr_read_pages(xdr, pdev->mincount) != pdev->mincount) 595062306a36Sopenharmony_ci return -EIO; 595162306a36Sopenharmony_ci 595262306a36Sopenharmony_ci /* Parse notification bitmap, verifying that it is zero. */ 595362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 595462306a36Sopenharmony_ci if (unlikely(!p)) 595562306a36Sopenharmony_ci return -EIO; 595662306a36Sopenharmony_ci len = be32_to_cpup(p); 595762306a36Sopenharmony_ci if (len) { 595862306a36Sopenharmony_ci uint32_t i; 595962306a36Sopenharmony_ci 596062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4 * len); 596162306a36Sopenharmony_ci if (unlikely(!p)) 596262306a36Sopenharmony_ci return -EIO; 596362306a36Sopenharmony_ci 596462306a36Sopenharmony_ci res->notification = be32_to_cpup(p++); 596562306a36Sopenharmony_ci for (i = 1; i < len; i++) { 596662306a36Sopenharmony_ci if (be32_to_cpup(p++)) { 596762306a36Sopenharmony_ci dprintk("%s: unsupported notification\n", 596862306a36Sopenharmony_ci __func__); 596962306a36Sopenharmony_ci return -EIO; 597062306a36Sopenharmony_ci } 597162306a36Sopenharmony_ci } 597262306a36Sopenharmony_ci } 597362306a36Sopenharmony_ci return 0; 597462306a36Sopenharmony_ci} 597562306a36Sopenharmony_ci 597662306a36Sopenharmony_cistatic int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, 597762306a36Sopenharmony_ci struct nfs4_layoutget_res *res) 597862306a36Sopenharmony_ci{ 597962306a36Sopenharmony_ci __be32 *p; 598062306a36Sopenharmony_ci int status; 598162306a36Sopenharmony_ci u32 layout_count; 598262306a36Sopenharmony_ci u32 recvd; 598362306a36Sopenharmony_ci 598462306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_LAYOUTGET); 598562306a36Sopenharmony_ci if (status) 598662306a36Sopenharmony_ci goto out; 598762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 598862306a36Sopenharmony_ci if (unlikely(!p)) 598962306a36Sopenharmony_ci goto out_overflow; 599062306a36Sopenharmony_ci res->return_on_close = be32_to_cpup(p); 599162306a36Sopenharmony_ci decode_layout_stateid(xdr, &res->stateid); 599262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 599362306a36Sopenharmony_ci if (unlikely(!p)) 599462306a36Sopenharmony_ci goto out_overflow; 599562306a36Sopenharmony_ci layout_count = be32_to_cpup(p); 599662306a36Sopenharmony_ci if (!layout_count) { 599762306a36Sopenharmony_ci dprintk("%s: server responded with empty layout array\n", 599862306a36Sopenharmony_ci __func__); 599962306a36Sopenharmony_ci status = -EINVAL; 600062306a36Sopenharmony_ci goto out; 600162306a36Sopenharmony_ci } 600262306a36Sopenharmony_ci 600362306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 28); 600462306a36Sopenharmony_ci if (unlikely(!p)) 600562306a36Sopenharmony_ci goto out_overflow; 600662306a36Sopenharmony_ci p = xdr_decode_hyper(p, &res->range.offset); 600762306a36Sopenharmony_ci p = xdr_decode_hyper(p, &res->range.length); 600862306a36Sopenharmony_ci res->range.iomode = be32_to_cpup(p++); 600962306a36Sopenharmony_ci res->type = be32_to_cpup(p++); 601062306a36Sopenharmony_ci res->layoutp->len = be32_to_cpup(p); 601162306a36Sopenharmony_ci 601262306a36Sopenharmony_ci dprintk("%s roff:%lu rlen:%lu riomode:%d, lo_type:0x%x, lo.len:%d\n", 601362306a36Sopenharmony_ci __func__, 601462306a36Sopenharmony_ci (unsigned long)res->range.offset, 601562306a36Sopenharmony_ci (unsigned long)res->range.length, 601662306a36Sopenharmony_ci res->range.iomode, 601762306a36Sopenharmony_ci res->type, 601862306a36Sopenharmony_ci res->layoutp->len); 601962306a36Sopenharmony_ci 602062306a36Sopenharmony_ci recvd = xdr_read_pages(xdr, res->layoutp->len); 602162306a36Sopenharmony_ci if (res->layoutp->len > recvd) { 602262306a36Sopenharmony_ci dprintk("NFS: server cheating in layoutget reply: " 602362306a36Sopenharmony_ci "layout len %u > recvd %u\n", 602462306a36Sopenharmony_ci res->layoutp->len, recvd); 602562306a36Sopenharmony_ci status = -EINVAL; 602662306a36Sopenharmony_ci goto out; 602762306a36Sopenharmony_ci } 602862306a36Sopenharmony_ci 602962306a36Sopenharmony_ci if (layout_count > 1) { 603062306a36Sopenharmony_ci /* We only handle a length one array at the moment. Any 603162306a36Sopenharmony_ci * further entries are just ignored. Note that this means 603262306a36Sopenharmony_ci * the client may see a response that is less than the 603362306a36Sopenharmony_ci * minimum it requested. 603462306a36Sopenharmony_ci */ 603562306a36Sopenharmony_ci dprintk("%s: server responded with %d layouts, dropping tail\n", 603662306a36Sopenharmony_ci __func__, layout_count); 603762306a36Sopenharmony_ci } 603862306a36Sopenharmony_ci 603962306a36Sopenharmony_ciout: 604062306a36Sopenharmony_ci res->status = status; 604162306a36Sopenharmony_ci return status; 604262306a36Sopenharmony_ciout_overflow: 604362306a36Sopenharmony_ci status = -EIO; 604462306a36Sopenharmony_ci goto out; 604562306a36Sopenharmony_ci} 604662306a36Sopenharmony_ci 604762306a36Sopenharmony_cistatic int decode_layoutreturn(struct xdr_stream *xdr, 604862306a36Sopenharmony_ci struct nfs4_layoutreturn_res *res) 604962306a36Sopenharmony_ci{ 605062306a36Sopenharmony_ci __be32 *p; 605162306a36Sopenharmony_ci int status; 605262306a36Sopenharmony_ci 605362306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_LAYOUTRETURN); 605462306a36Sopenharmony_ci if (status) 605562306a36Sopenharmony_ci return status; 605662306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 605762306a36Sopenharmony_ci if (unlikely(!p)) 605862306a36Sopenharmony_ci return -EIO; 605962306a36Sopenharmony_ci res->lrs_present = be32_to_cpup(p); 606062306a36Sopenharmony_ci if (res->lrs_present) 606162306a36Sopenharmony_ci status = decode_layout_stateid(xdr, &res->stateid); 606262306a36Sopenharmony_ci else 606362306a36Sopenharmony_ci nfs4_stateid_copy(&res->stateid, &invalid_stateid); 606462306a36Sopenharmony_ci return status; 606562306a36Sopenharmony_ci} 606662306a36Sopenharmony_ci 606762306a36Sopenharmony_cistatic int decode_layoutcommit(struct xdr_stream *xdr, 606862306a36Sopenharmony_ci struct rpc_rqst *req, 606962306a36Sopenharmony_ci struct nfs4_layoutcommit_res *res) 607062306a36Sopenharmony_ci{ 607162306a36Sopenharmony_ci __be32 *p; 607262306a36Sopenharmony_ci __u32 sizechanged; 607362306a36Sopenharmony_ci int status; 607462306a36Sopenharmony_ci 607562306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT); 607662306a36Sopenharmony_ci res->status = status; 607762306a36Sopenharmony_ci if (status) 607862306a36Sopenharmony_ci return status; 607962306a36Sopenharmony_ci 608062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 608162306a36Sopenharmony_ci if (unlikely(!p)) 608262306a36Sopenharmony_ci return -EIO; 608362306a36Sopenharmony_ci sizechanged = be32_to_cpup(p); 608462306a36Sopenharmony_ci 608562306a36Sopenharmony_ci if (sizechanged) { 608662306a36Sopenharmony_ci /* throw away new size */ 608762306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 8); 608862306a36Sopenharmony_ci if (unlikely(!p)) 608962306a36Sopenharmony_ci return -EIO; 609062306a36Sopenharmony_ci } 609162306a36Sopenharmony_ci return 0; 609262306a36Sopenharmony_ci} 609362306a36Sopenharmony_ci 609462306a36Sopenharmony_cistatic int decode_test_stateid(struct xdr_stream *xdr, 609562306a36Sopenharmony_ci struct nfs41_test_stateid_res *res) 609662306a36Sopenharmony_ci{ 609762306a36Sopenharmony_ci __be32 *p; 609862306a36Sopenharmony_ci int status; 609962306a36Sopenharmony_ci int num_res; 610062306a36Sopenharmony_ci 610162306a36Sopenharmony_ci status = decode_op_hdr(xdr, OP_TEST_STATEID); 610262306a36Sopenharmony_ci if (status) 610362306a36Sopenharmony_ci return status; 610462306a36Sopenharmony_ci 610562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 610662306a36Sopenharmony_ci if (unlikely(!p)) 610762306a36Sopenharmony_ci return -EIO; 610862306a36Sopenharmony_ci num_res = be32_to_cpup(p++); 610962306a36Sopenharmony_ci if (num_res != 1) 611062306a36Sopenharmony_ci return -EIO; 611162306a36Sopenharmony_ci 611262306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 611362306a36Sopenharmony_ci if (unlikely(!p)) 611462306a36Sopenharmony_ci return -EIO; 611562306a36Sopenharmony_ci res->status = be32_to_cpup(p++); 611662306a36Sopenharmony_ci 611762306a36Sopenharmony_ci return status; 611862306a36Sopenharmony_ci} 611962306a36Sopenharmony_ci 612062306a36Sopenharmony_cistatic int decode_free_stateid(struct xdr_stream *xdr, 612162306a36Sopenharmony_ci struct nfs41_free_stateid_res *res) 612262306a36Sopenharmony_ci{ 612362306a36Sopenharmony_ci res->status = decode_op_hdr(xdr, OP_FREE_STATEID); 612462306a36Sopenharmony_ci return res->status; 612562306a36Sopenharmony_ci} 612662306a36Sopenharmony_ci#else 612762306a36Sopenharmony_cistatic inline 612862306a36Sopenharmony_ciint decode_layoutreturn(struct xdr_stream *xdr, 612962306a36Sopenharmony_ci struct nfs4_layoutreturn_res *res) 613062306a36Sopenharmony_ci{ 613162306a36Sopenharmony_ci return 0; 613262306a36Sopenharmony_ci} 613362306a36Sopenharmony_ci 613462306a36Sopenharmony_cistatic int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, 613562306a36Sopenharmony_ci struct nfs4_layoutget_res *res) 613662306a36Sopenharmony_ci{ 613762306a36Sopenharmony_ci return 0; 613862306a36Sopenharmony_ci} 613962306a36Sopenharmony_ci 614062306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 614162306a36Sopenharmony_ci 614262306a36Sopenharmony_ci/* 614362306a36Sopenharmony_ci * END OF "GENERIC" DECODE ROUTINES. 614462306a36Sopenharmony_ci */ 614562306a36Sopenharmony_ci 614662306a36Sopenharmony_ci/* 614762306a36Sopenharmony_ci * Decode OPEN_DOWNGRADE response 614862306a36Sopenharmony_ci */ 614962306a36Sopenharmony_cistatic int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, 615062306a36Sopenharmony_ci struct xdr_stream *xdr, 615162306a36Sopenharmony_ci void *data) 615262306a36Sopenharmony_ci{ 615362306a36Sopenharmony_ci struct nfs_closeres *res = data; 615462306a36Sopenharmony_ci struct compound_hdr hdr; 615562306a36Sopenharmony_ci int status; 615662306a36Sopenharmony_ci 615762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 615862306a36Sopenharmony_ci if (status) 615962306a36Sopenharmony_ci goto out; 616062306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 616162306a36Sopenharmony_ci if (status) 616262306a36Sopenharmony_ci goto out; 616362306a36Sopenharmony_ci status = decode_putfh(xdr); 616462306a36Sopenharmony_ci if (status) 616562306a36Sopenharmony_ci goto out; 616662306a36Sopenharmony_ci if (res->lr_res) { 616762306a36Sopenharmony_ci status = decode_layoutreturn(xdr, res->lr_res); 616862306a36Sopenharmony_ci res->lr_ret = status; 616962306a36Sopenharmony_ci if (status) 617062306a36Sopenharmony_ci goto out; 617162306a36Sopenharmony_ci } 617262306a36Sopenharmony_ci status = decode_open_downgrade(xdr, res); 617362306a36Sopenharmony_ciout: 617462306a36Sopenharmony_ci return status; 617562306a36Sopenharmony_ci} 617662306a36Sopenharmony_ci 617762306a36Sopenharmony_ci/* 617862306a36Sopenharmony_ci * Decode ACCESS response 617962306a36Sopenharmony_ci */ 618062306a36Sopenharmony_cistatic int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 618162306a36Sopenharmony_ci void *data) 618262306a36Sopenharmony_ci{ 618362306a36Sopenharmony_ci struct nfs4_accessres *res = data; 618462306a36Sopenharmony_ci struct compound_hdr hdr; 618562306a36Sopenharmony_ci int status; 618662306a36Sopenharmony_ci 618762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 618862306a36Sopenharmony_ci if (status) 618962306a36Sopenharmony_ci goto out; 619062306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 619162306a36Sopenharmony_ci if (status) 619262306a36Sopenharmony_ci goto out; 619362306a36Sopenharmony_ci status = decode_putfh(xdr); 619462306a36Sopenharmony_ci if (status != 0) 619562306a36Sopenharmony_ci goto out; 619662306a36Sopenharmony_ci status = decode_access(xdr, &res->supported, &res->access); 619762306a36Sopenharmony_ci if (status != 0) 619862306a36Sopenharmony_ci goto out; 619962306a36Sopenharmony_ci if (res->fattr) 620062306a36Sopenharmony_ci decode_getfattr(xdr, res->fattr, res->server); 620162306a36Sopenharmony_ciout: 620262306a36Sopenharmony_ci return status; 620362306a36Sopenharmony_ci} 620462306a36Sopenharmony_ci 620562306a36Sopenharmony_ci/* 620662306a36Sopenharmony_ci * Decode LOOKUP response 620762306a36Sopenharmony_ci */ 620862306a36Sopenharmony_cistatic int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 620962306a36Sopenharmony_ci void *data) 621062306a36Sopenharmony_ci{ 621162306a36Sopenharmony_ci struct nfs4_lookup_res *res = data; 621262306a36Sopenharmony_ci struct compound_hdr hdr; 621362306a36Sopenharmony_ci int status; 621462306a36Sopenharmony_ci 621562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 621662306a36Sopenharmony_ci if (status) 621762306a36Sopenharmony_ci goto out; 621862306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 621962306a36Sopenharmony_ci if (status) 622062306a36Sopenharmony_ci goto out; 622162306a36Sopenharmony_ci status = decode_putfh(xdr); 622262306a36Sopenharmony_ci if (status) 622362306a36Sopenharmony_ci goto out; 622462306a36Sopenharmony_ci status = decode_lookup(xdr); 622562306a36Sopenharmony_ci if (status) 622662306a36Sopenharmony_ci goto out; 622762306a36Sopenharmony_ci status = decode_getfh(xdr, res->fh); 622862306a36Sopenharmony_ci if (status) 622962306a36Sopenharmony_ci goto out; 623062306a36Sopenharmony_ci status = decode_getfattr(xdr, res->fattr, res->server); 623162306a36Sopenharmony_ciout: 623262306a36Sopenharmony_ci return status; 623362306a36Sopenharmony_ci} 623462306a36Sopenharmony_ci 623562306a36Sopenharmony_ci/* 623662306a36Sopenharmony_ci * Decode LOOKUPP response 623762306a36Sopenharmony_ci */ 623862306a36Sopenharmony_cistatic int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 623962306a36Sopenharmony_ci void *data) 624062306a36Sopenharmony_ci{ 624162306a36Sopenharmony_ci struct nfs4_lookupp_res *res = data; 624262306a36Sopenharmony_ci struct compound_hdr hdr; 624362306a36Sopenharmony_ci int status; 624462306a36Sopenharmony_ci 624562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 624662306a36Sopenharmony_ci if (status) 624762306a36Sopenharmony_ci goto out; 624862306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 624962306a36Sopenharmony_ci if (status) 625062306a36Sopenharmony_ci goto out; 625162306a36Sopenharmony_ci status = decode_putfh(xdr); 625262306a36Sopenharmony_ci if (status) 625362306a36Sopenharmony_ci goto out; 625462306a36Sopenharmony_ci status = decode_lookupp(xdr); 625562306a36Sopenharmony_ci if (status) 625662306a36Sopenharmony_ci goto out; 625762306a36Sopenharmony_ci status = decode_getfh(xdr, res->fh); 625862306a36Sopenharmony_ci if (status) 625962306a36Sopenharmony_ci goto out; 626062306a36Sopenharmony_ci status = decode_getfattr(xdr, res->fattr, res->server); 626162306a36Sopenharmony_ciout: 626262306a36Sopenharmony_ci return status; 626362306a36Sopenharmony_ci} 626462306a36Sopenharmony_ci 626562306a36Sopenharmony_ci/* 626662306a36Sopenharmony_ci * Decode LOOKUP_ROOT response 626762306a36Sopenharmony_ci */ 626862306a36Sopenharmony_cistatic int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, 626962306a36Sopenharmony_ci struct xdr_stream *xdr, 627062306a36Sopenharmony_ci void *data) 627162306a36Sopenharmony_ci{ 627262306a36Sopenharmony_ci struct nfs4_lookup_res *res = data; 627362306a36Sopenharmony_ci struct compound_hdr hdr; 627462306a36Sopenharmony_ci int status; 627562306a36Sopenharmony_ci 627662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 627762306a36Sopenharmony_ci if (status) 627862306a36Sopenharmony_ci goto out; 627962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 628062306a36Sopenharmony_ci if (status) 628162306a36Sopenharmony_ci goto out; 628262306a36Sopenharmony_ci status = decode_putrootfh(xdr); 628362306a36Sopenharmony_ci if (status) 628462306a36Sopenharmony_ci goto out; 628562306a36Sopenharmony_ci status = decode_getfh(xdr, res->fh); 628662306a36Sopenharmony_ci if (status == 0) 628762306a36Sopenharmony_ci status = decode_getfattr(xdr, res->fattr, res->server); 628862306a36Sopenharmony_ciout: 628962306a36Sopenharmony_ci return status; 629062306a36Sopenharmony_ci} 629162306a36Sopenharmony_ci 629262306a36Sopenharmony_ci/* 629362306a36Sopenharmony_ci * Decode REMOVE response 629462306a36Sopenharmony_ci */ 629562306a36Sopenharmony_cistatic int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 629662306a36Sopenharmony_ci void *data) 629762306a36Sopenharmony_ci{ 629862306a36Sopenharmony_ci struct nfs_removeres *res = data; 629962306a36Sopenharmony_ci struct compound_hdr hdr; 630062306a36Sopenharmony_ci int status; 630162306a36Sopenharmony_ci 630262306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 630362306a36Sopenharmony_ci if (status) 630462306a36Sopenharmony_ci goto out; 630562306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 630662306a36Sopenharmony_ci if (status) 630762306a36Sopenharmony_ci goto out; 630862306a36Sopenharmony_ci status = decode_putfh(xdr); 630962306a36Sopenharmony_ci if (status) 631062306a36Sopenharmony_ci goto out; 631162306a36Sopenharmony_ci status = decode_remove(xdr, &res->cinfo); 631262306a36Sopenharmony_ciout: 631362306a36Sopenharmony_ci return status; 631462306a36Sopenharmony_ci} 631562306a36Sopenharmony_ci 631662306a36Sopenharmony_ci/* 631762306a36Sopenharmony_ci * Decode RENAME response 631862306a36Sopenharmony_ci */ 631962306a36Sopenharmony_cistatic int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 632062306a36Sopenharmony_ci void *data) 632162306a36Sopenharmony_ci{ 632262306a36Sopenharmony_ci struct nfs_renameres *res = data; 632362306a36Sopenharmony_ci struct compound_hdr hdr; 632462306a36Sopenharmony_ci int status; 632562306a36Sopenharmony_ci 632662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 632762306a36Sopenharmony_ci if (status) 632862306a36Sopenharmony_ci goto out; 632962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 633062306a36Sopenharmony_ci if (status) 633162306a36Sopenharmony_ci goto out; 633262306a36Sopenharmony_ci status = decode_putfh(xdr); 633362306a36Sopenharmony_ci if (status) 633462306a36Sopenharmony_ci goto out; 633562306a36Sopenharmony_ci status = decode_savefh(xdr); 633662306a36Sopenharmony_ci if (status) 633762306a36Sopenharmony_ci goto out; 633862306a36Sopenharmony_ci status = decode_putfh(xdr); 633962306a36Sopenharmony_ci if (status) 634062306a36Sopenharmony_ci goto out; 634162306a36Sopenharmony_ci status = decode_rename(xdr, &res->old_cinfo, &res->new_cinfo); 634262306a36Sopenharmony_ciout: 634362306a36Sopenharmony_ci return status; 634462306a36Sopenharmony_ci} 634562306a36Sopenharmony_ci 634662306a36Sopenharmony_ci/* 634762306a36Sopenharmony_ci * Decode LINK response 634862306a36Sopenharmony_ci */ 634962306a36Sopenharmony_cistatic int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 635062306a36Sopenharmony_ci void *data) 635162306a36Sopenharmony_ci{ 635262306a36Sopenharmony_ci struct nfs4_link_res *res = data; 635362306a36Sopenharmony_ci struct compound_hdr hdr; 635462306a36Sopenharmony_ci int status; 635562306a36Sopenharmony_ci 635662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 635762306a36Sopenharmony_ci if (status) 635862306a36Sopenharmony_ci goto out; 635962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 636062306a36Sopenharmony_ci if (status) 636162306a36Sopenharmony_ci goto out; 636262306a36Sopenharmony_ci status = decode_putfh(xdr); 636362306a36Sopenharmony_ci if (status) 636462306a36Sopenharmony_ci goto out; 636562306a36Sopenharmony_ci status = decode_savefh(xdr); 636662306a36Sopenharmony_ci if (status) 636762306a36Sopenharmony_ci goto out; 636862306a36Sopenharmony_ci status = decode_putfh(xdr); 636962306a36Sopenharmony_ci if (status) 637062306a36Sopenharmony_ci goto out; 637162306a36Sopenharmony_ci status = decode_link(xdr, &res->cinfo); 637262306a36Sopenharmony_ci if (status) 637362306a36Sopenharmony_ci goto out; 637462306a36Sopenharmony_ci /* 637562306a36Sopenharmony_ci * Note order: OP_LINK leaves the directory as the current 637662306a36Sopenharmony_ci * filehandle. 637762306a36Sopenharmony_ci */ 637862306a36Sopenharmony_ci status = decode_restorefh(xdr); 637962306a36Sopenharmony_ci if (status) 638062306a36Sopenharmony_ci goto out; 638162306a36Sopenharmony_ci decode_getfattr(xdr, res->fattr, res->server); 638262306a36Sopenharmony_ciout: 638362306a36Sopenharmony_ci return status; 638462306a36Sopenharmony_ci} 638562306a36Sopenharmony_ci 638662306a36Sopenharmony_ci/* 638762306a36Sopenharmony_ci * Decode CREATE response 638862306a36Sopenharmony_ci */ 638962306a36Sopenharmony_cistatic int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 639062306a36Sopenharmony_ci void *data) 639162306a36Sopenharmony_ci{ 639262306a36Sopenharmony_ci struct nfs4_create_res *res = data; 639362306a36Sopenharmony_ci struct compound_hdr hdr; 639462306a36Sopenharmony_ci int status; 639562306a36Sopenharmony_ci 639662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 639762306a36Sopenharmony_ci if (status) 639862306a36Sopenharmony_ci goto out; 639962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 640062306a36Sopenharmony_ci if (status) 640162306a36Sopenharmony_ci goto out; 640262306a36Sopenharmony_ci status = decode_putfh(xdr); 640362306a36Sopenharmony_ci if (status) 640462306a36Sopenharmony_ci goto out; 640562306a36Sopenharmony_ci status = decode_create(xdr, &res->dir_cinfo); 640662306a36Sopenharmony_ci if (status) 640762306a36Sopenharmony_ci goto out; 640862306a36Sopenharmony_ci status = decode_getfh(xdr, res->fh); 640962306a36Sopenharmony_ci if (status) 641062306a36Sopenharmony_ci goto out; 641162306a36Sopenharmony_ci decode_getfattr(xdr, res->fattr, res->server); 641262306a36Sopenharmony_ciout: 641362306a36Sopenharmony_ci return status; 641462306a36Sopenharmony_ci} 641562306a36Sopenharmony_ci 641662306a36Sopenharmony_ci/* 641762306a36Sopenharmony_ci * Decode SYMLINK response 641862306a36Sopenharmony_ci */ 641962306a36Sopenharmony_cistatic int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 642062306a36Sopenharmony_ci void *res) 642162306a36Sopenharmony_ci{ 642262306a36Sopenharmony_ci return nfs4_xdr_dec_create(rqstp, xdr, res); 642362306a36Sopenharmony_ci} 642462306a36Sopenharmony_ci 642562306a36Sopenharmony_ci/* 642662306a36Sopenharmony_ci * Decode GETATTR response 642762306a36Sopenharmony_ci */ 642862306a36Sopenharmony_cistatic int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 642962306a36Sopenharmony_ci void *data) 643062306a36Sopenharmony_ci{ 643162306a36Sopenharmony_ci struct nfs4_getattr_res *res = data; 643262306a36Sopenharmony_ci struct compound_hdr hdr; 643362306a36Sopenharmony_ci int status; 643462306a36Sopenharmony_ci 643562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 643662306a36Sopenharmony_ci if (status) 643762306a36Sopenharmony_ci goto out; 643862306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 643962306a36Sopenharmony_ci if (status) 644062306a36Sopenharmony_ci goto out; 644162306a36Sopenharmony_ci status = decode_putfh(xdr); 644262306a36Sopenharmony_ci if (status) 644362306a36Sopenharmony_ci goto out; 644462306a36Sopenharmony_ci status = decode_getfattr(xdr, res->fattr, res->server); 644562306a36Sopenharmony_ciout: 644662306a36Sopenharmony_ci return status; 644762306a36Sopenharmony_ci} 644862306a36Sopenharmony_ci 644962306a36Sopenharmony_ci/* 645062306a36Sopenharmony_ci * Encode an SETACL request 645162306a36Sopenharmony_ci */ 645262306a36Sopenharmony_cistatic void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr, 645362306a36Sopenharmony_ci const void *data) 645462306a36Sopenharmony_ci{ 645562306a36Sopenharmony_ci const struct nfs_setaclargs *args = data; 645662306a36Sopenharmony_ci struct compound_hdr hdr = { 645762306a36Sopenharmony_ci .minorversion = nfs4_xdr_minorversion(&args->seq_args), 645862306a36Sopenharmony_ci }; 645962306a36Sopenharmony_ci 646062306a36Sopenharmony_ci encode_compound_hdr(xdr, req, &hdr); 646162306a36Sopenharmony_ci encode_sequence(xdr, &args->seq_args, &hdr); 646262306a36Sopenharmony_ci encode_putfh(xdr, args->fh, &hdr); 646362306a36Sopenharmony_ci encode_setacl(xdr, args, &hdr); 646462306a36Sopenharmony_ci encode_nops(&hdr); 646562306a36Sopenharmony_ci} 646662306a36Sopenharmony_ci 646762306a36Sopenharmony_ci/* 646862306a36Sopenharmony_ci * Decode SETACL response 646962306a36Sopenharmony_ci */ 647062306a36Sopenharmony_cistatic int 647162306a36Sopenharmony_cinfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 647262306a36Sopenharmony_ci void *data) 647362306a36Sopenharmony_ci{ 647462306a36Sopenharmony_ci struct nfs_setaclres *res = data; 647562306a36Sopenharmony_ci struct compound_hdr hdr; 647662306a36Sopenharmony_ci int status; 647762306a36Sopenharmony_ci 647862306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 647962306a36Sopenharmony_ci if (status) 648062306a36Sopenharmony_ci goto out; 648162306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 648262306a36Sopenharmony_ci if (status) 648362306a36Sopenharmony_ci goto out; 648462306a36Sopenharmony_ci status = decode_putfh(xdr); 648562306a36Sopenharmony_ci if (status) 648662306a36Sopenharmony_ci goto out; 648762306a36Sopenharmony_ci status = decode_setattr(xdr); 648862306a36Sopenharmony_ciout: 648962306a36Sopenharmony_ci return status; 649062306a36Sopenharmony_ci} 649162306a36Sopenharmony_ci 649262306a36Sopenharmony_ci/* 649362306a36Sopenharmony_ci * Decode GETACL response 649462306a36Sopenharmony_ci */ 649562306a36Sopenharmony_cistatic int 649662306a36Sopenharmony_cinfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 649762306a36Sopenharmony_ci void *data) 649862306a36Sopenharmony_ci{ 649962306a36Sopenharmony_ci struct nfs_getaclres *res = data; 650062306a36Sopenharmony_ci struct compound_hdr hdr; 650162306a36Sopenharmony_ci int status; 650262306a36Sopenharmony_ci 650362306a36Sopenharmony_ci if (res->acl_scratch != NULL) 650462306a36Sopenharmony_ci xdr_set_scratch_page(xdr, res->acl_scratch); 650562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 650662306a36Sopenharmony_ci if (status) 650762306a36Sopenharmony_ci goto out; 650862306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 650962306a36Sopenharmony_ci if (status) 651062306a36Sopenharmony_ci goto out; 651162306a36Sopenharmony_ci status = decode_putfh(xdr); 651262306a36Sopenharmony_ci if (status) 651362306a36Sopenharmony_ci goto out; 651462306a36Sopenharmony_ci status = decode_getacl(xdr, rqstp, res, res->acl_type); 651562306a36Sopenharmony_ci 651662306a36Sopenharmony_ciout: 651762306a36Sopenharmony_ci return status; 651862306a36Sopenharmony_ci} 651962306a36Sopenharmony_ci 652062306a36Sopenharmony_ci/* 652162306a36Sopenharmony_ci * Decode CLOSE response 652262306a36Sopenharmony_ci */ 652362306a36Sopenharmony_cistatic int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 652462306a36Sopenharmony_ci void *data) 652562306a36Sopenharmony_ci{ 652662306a36Sopenharmony_ci struct nfs_closeres *res = data; 652762306a36Sopenharmony_ci struct compound_hdr hdr; 652862306a36Sopenharmony_ci int status; 652962306a36Sopenharmony_ci 653062306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 653162306a36Sopenharmony_ci if (status) 653262306a36Sopenharmony_ci goto out; 653362306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 653462306a36Sopenharmony_ci if (status) 653562306a36Sopenharmony_ci goto out; 653662306a36Sopenharmony_ci status = decode_putfh(xdr); 653762306a36Sopenharmony_ci if (status) 653862306a36Sopenharmony_ci goto out; 653962306a36Sopenharmony_ci if (res->lr_res) { 654062306a36Sopenharmony_ci status = decode_layoutreturn(xdr, res->lr_res); 654162306a36Sopenharmony_ci res->lr_ret = status; 654262306a36Sopenharmony_ci if (status) 654362306a36Sopenharmony_ci goto out; 654462306a36Sopenharmony_ci } 654562306a36Sopenharmony_ci if (res->fattr != NULL) { 654662306a36Sopenharmony_ci status = decode_getfattr(xdr, res->fattr, res->server); 654762306a36Sopenharmony_ci if (status != 0) 654862306a36Sopenharmony_ci goto out; 654962306a36Sopenharmony_ci } 655062306a36Sopenharmony_ci status = decode_close(xdr, res); 655162306a36Sopenharmony_ciout: 655262306a36Sopenharmony_ci return status; 655362306a36Sopenharmony_ci} 655462306a36Sopenharmony_ci 655562306a36Sopenharmony_ci/* 655662306a36Sopenharmony_ci * Decode OPEN response 655762306a36Sopenharmony_ci */ 655862306a36Sopenharmony_cistatic int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 655962306a36Sopenharmony_ci void *data) 656062306a36Sopenharmony_ci{ 656162306a36Sopenharmony_ci struct nfs_openres *res = data; 656262306a36Sopenharmony_ci struct compound_hdr hdr; 656362306a36Sopenharmony_ci int status; 656462306a36Sopenharmony_ci 656562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 656662306a36Sopenharmony_ci if (status) 656762306a36Sopenharmony_ci goto out; 656862306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 656962306a36Sopenharmony_ci if (status) 657062306a36Sopenharmony_ci goto out; 657162306a36Sopenharmony_ci status = decode_putfh(xdr); 657262306a36Sopenharmony_ci if (status) 657362306a36Sopenharmony_ci goto out; 657462306a36Sopenharmony_ci status = decode_open(xdr, res); 657562306a36Sopenharmony_ci if (status) 657662306a36Sopenharmony_ci goto out; 657762306a36Sopenharmony_ci status = decode_getfh(xdr, &res->fh); 657862306a36Sopenharmony_ci if (status) 657962306a36Sopenharmony_ci goto out; 658062306a36Sopenharmony_ci if (res->access_request) 658162306a36Sopenharmony_ci decode_access(xdr, &res->access_supported, &res->access_result); 658262306a36Sopenharmony_ci decode_getfattr(xdr, res->f_attr, res->server); 658362306a36Sopenharmony_ci if (res->lg_res) 658462306a36Sopenharmony_ci decode_layoutget(xdr, rqstp, res->lg_res); 658562306a36Sopenharmony_ciout: 658662306a36Sopenharmony_ci return status; 658762306a36Sopenharmony_ci} 658862306a36Sopenharmony_ci 658962306a36Sopenharmony_ci/* 659062306a36Sopenharmony_ci * Decode OPEN_CONFIRM response 659162306a36Sopenharmony_ci */ 659262306a36Sopenharmony_cistatic int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, 659362306a36Sopenharmony_ci struct xdr_stream *xdr, 659462306a36Sopenharmony_ci void *data) 659562306a36Sopenharmony_ci{ 659662306a36Sopenharmony_ci struct nfs_open_confirmres *res = data; 659762306a36Sopenharmony_ci struct compound_hdr hdr; 659862306a36Sopenharmony_ci int status; 659962306a36Sopenharmony_ci 660062306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 660162306a36Sopenharmony_ci if (status) 660262306a36Sopenharmony_ci goto out; 660362306a36Sopenharmony_ci status = decode_putfh(xdr); 660462306a36Sopenharmony_ci if (status) 660562306a36Sopenharmony_ci goto out; 660662306a36Sopenharmony_ci status = decode_open_confirm(xdr, res); 660762306a36Sopenharmony_ciout: 660862306a36Sopenharmony_ci return status; 660962306a36Sopenharmony_ci} 661062306a36Sopenharmony_ci 661162306a36Sopenharmony_ci/* 661262306a36Sopenharmony_ci * Decode OPEN response 661362306a36Sopenharmony_ci */ 661462306a36Sopenharmony_cistatic int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, 661562306a36Sopenharmony_ci struct xdr_stream *xdr, 661662306a36Sopenharmony_ci void *data) 661762306a36Sopenharmony_ci{ 661862306a36Sopenharmony_ci struct nfs_openres *res = data; 661962306a36Sopenharmony_ci struct compound_hdr hdr; 662062306a36Sopenharmony_ci int status; 662162306a36Sopenharmony_ci 662262306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 662362306a36Sopenharmony_ci if (status) 662462306a36Sopenharmony_ci goto out; 662562306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 662662306a36Sopenharmony_ci if (status) 662762306a36Sopenharmony_ci goto out; 662862306a36Sopenharmony_ci status = decode_putfh(xdr); 662962306a36Sopenharmony_ci if (status) 663062306a36Sopenharmony_ci goto out; 663162306a36Sopenharmony_ci status = decode_open(xdr, res); 663262306a36Sopenharmony_ci if (status) 663362306a36Sopenharmony_ci goto out; 663462306a36Sopenharmony_ci if (res->access_request) 663562306a36Sopenharmony_ci decode_access(xdr, &res->access_supported, &res->access_result); 663662306a36Sopenharmony_ci decode_getfattr(xdr, res->f_attr, res->server); 663762306a36Sopenharmony_ci if (res->lg_res) 663862306a36Sopenharmony_ci decode_layoutget(xdr, rqstp, res->lg_res); 663962306a36Sopenharmony_ciout: 664062306a36Sopenharmony_ci return status; 664162306a36Sopenharmony_ci} 664262306a36Sopenharmony_ci 664362306a36Sopenharmony_ci/* 664462306a36Sopenharmony_ci * Decode SETATTR response 664562306a36Sopenharmony_ci */ 664662306a36Sopenharmony_cistatic int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, 664762306a36Sopenharmony_ci struct xdr_stream *xdr, 664862306a36Sopenharmony_ci void *data) 664962306a36Sopenharmony_ci{ 665062306a36Sopenharmony_ci struct nfs_setattrres *res = data; 665162306a36Sopenharmony_ci struct compound_hdr hdr; 665262306a36Sopenharmony_ci int status; 665362306a36Sopenharmony_ci 665462306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 665562306a36Sopenharmony_ci if (status) 665662306a36Sopenharmony_ci goto out; 665762306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 665862306a36Sopenharmony_ci if (status) 665962306a36Sopenharmony_ci goto out; 666062306a36Sopenharmony_ci status = decode_putfh(xdr); 666162306a36Sopenharmony_ci if (status) 666262306a36Sopenharmony_ci goto out; 666362306a36Sopenharmony_ci status = decode_setattr(xdr); 666462306a36Sopenharmony_ci if (status) 666562306a36Sopenharmony_ci goto out; 666662306a36Sopenharmony_ci decode_getfattr(xdr, res->fattr, res->server); 666762306a36Sopenharmony_ciout: 666862306a36Sopenharmony_ci return status; 666962306a36Sopenharmony_ci} 667062306a36Sopenharmony_ci 667162306a36Sopenharmony_ci/* 667262306a36Sopenharmony_ci * Decode LOCK response 667362306a36Sopenharmony_ci */ 667462306a36Sopenharmony_cistatic int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 667562306a36Sopenharmony_ci void *data) 667662306a36Sopenharmony_ci{ 667762306a36Sopenharmony_ci struct nfs_lock_res *res = data; 667862306a36Sopenharmony_ci struct compound_hdr hdr; 667962306a36Sopenharmony_ci int status; 668062306a36Sopenharmony_ci 668162306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 668262306a36Sopenharmony_ci if (status) 668362306a36Sopenharmony_ci goto out; 668462306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 668562306a36Sopenharmony_ci if (status) 668662306a36Sopenharmony_ci goto out; 668762306a36Sopenharmony_ci status = decode_putfh(xdr); 668862306a36Sopenharmony_ci if (status) 668962306a36Sopenharmony_ci goto out; 669062306a36Sopenharmony_ci status = decode_lock(xdr, res); 669162306a36Sopenharmony_ciout: 669262306a36Sopenharmony_ci return status; 669362306a36Sopenharmony_ci} 669462306a36Sopenharmony_ci 669562306a36Sopenharmony_ci/* 669662306a36Sopenharmony_ci * Decode LOCKT response 669762306a36Sopenharmony_ci */ 669862306a36Sopenharmony_cistatic int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 669962306a36Sopenharmony_ci void *data) 670062306a36Sopenharmony_ci{ 670162306a36Sopenharmony_ci struct nfs_lockt_res *res = data; 670262306a36Sopenharmony_ci struct compound_hdr hdr; 670362306a36Sopenharmony_ci int status; 670462306a36Sopenharmony_ci 670562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 670662306a36Sopenharmony_ci if (status) 670762306a36Sopenharmony_ci goto out; 670862306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 670962306a36Sopenharmony_ci if (status) 671062306a36Sopenharmony_ci goto out; 671162306a36Sopenharmony_ci status = decode_putfh(xdr); 671262306a36Sopenharmony_ci if (status) 671362306a36Sopenharmony_ci goto out; 671462306a36Sopenharmony_ci status = decode_lockt(xdr, res); 671562306a36Sopenharmony_ciout: 671662306a36Sopenharmony_ci return status; 671762306a36Sopenharmony_ci} 671862306a36Sopenharmony_ci 671962306a36Sopenharmony_ci/* 672062306a36Sopenharmony_ci * Decode LOCKU response 672162306a36Sopenharmony_ci */ 672262306a36Sopenharmony_cistatic int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 672362306a36Sopenharmony_ci void *data) 672462306a36Sopenharmony_ci{ 672562306a36Sopenharmony_ci struct nfs_locku_res *res = data; 672662306a36Sopenharmony_ci struct compound_hdr hdr; 672762306a36Sopenharmony_ci int status; 672862306a36Sopenharmony_ci 672962306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 673062306a36Sopenharmony_ci if (status) 673162306a36Sopenharmony_ci goto out; 673262306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 673362306a36Sopenharmony_ci if (status) 673462306a36Sopenharmony_ci goto out; 673562306a36Sopenharmony_ci status = decode_putfh(xdr); 673662306a36Sopenharmony_ci if (status) 673762306a36Sopenharmony_ci goto out; 673862306a36Sopenharmony_ci status = decode_locku(xdr, res); 673962306a36Sopenharmony_ciout: 674062306a36Sopenharmony_ci return status; 674162306a36Sopenharmony_ci} 674262306a36Sopenharmony_ci 674362306a36Sopenharmony_cistatic int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp, 674462306a36Sopenharmony_ci struct xdr_stream *xdr, void *dummy) 674562306a36Sopenharmony_ci{ 674662306a36Sopenharmony_ci struct compound_hdr hdr; 674762306a36Sopenharmony_ci int status; 674862306a36Sopenharmony_ci 674962306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 675062306a36Sopenharmony_ci if (!status) 675162306a36Sopenharmony_ci status = decode_release_lockowner(xdr); 675262306a36Sopenharmony_ci return status; 675362306a36Sopenharmony_ci} 675462306a36Sopenharmony_ci 675562306a36Sopenharmony_ci/* 675662306a36Sopenharmony_ci * Decode READLINK response 675762306a36Sopenharmony_ci */ 675862306a36Sopenharmony_cistatic int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, 675962306a36Sopenharmony_ci struct xdr_stream *xdr, 676062306a36Sopenharmony_ci void *data) 676162306a36Sopenharmony_ci{ 676262306a36Sopenharmony_ci struct nfs4_readlink_res *res = data; 676362306a36Sopenharmony_ci struct compound_hdr hdr; 676462306a36Sopenharmony_ci int status; 676562306a36Sopenharmony_ci 676662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 676762306a36Sopenharmony_ci if (status) 676862306a36Sopenharmony_ci goto out; 676962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 677062306a36Sopenharmony_ci if (status) 677162306a36Sopenharmony_ci goto out; 677262306a36Sopenharmony_ci status = decode_putfh(xdr); 677362306a36Sopenharmony_ci if (status) 677462306a36Sopenharmony_ci goto out; 677562306a36Sopenharmony_ci status = decode_readlink(xdr, rqstp); 677662306a36Sopenharmony_ciout: 677762306a36Sopenharmony_ci return status; 677862306a36Sopenharmony_ci} 677962306a36Sopenharmony_ci 678062306a36Sopenharmony_ci/* 678162306a36Sopenharmony_ci * Decode READDIR response 678262306a36Sopenharmony_ci */ 678362306a36Sopenharmony_cistatic int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 678462306a36Sopenharmony_ci void *data) 678562306a36Sopenharmony_ci{ 678662306a36Sopenharmony_ci struct nfs4_readdir_res *res = data; 678762306a36Sopenharmony_ci struct compound_hdr hdr; 678862306a36Sopenharmony_ci int status; 678962306a36Sopenharmony_ci 679062306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 679162306a36Sopenharmony_ci if (status) 679262306a36Sopenharmony_ci goto out; 679362306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 679462306a36Sopenharmony_ci if (status) 679562306a36Sopenharmony_ci goto out; 679662306a36Sopenharmony_ci status = decode_putfh(xdr); 679762306a36Sopenharmony_ci if (status) 679862306a36Sopenharmony_ci goto out; 679962306a36Sopenharmony_ci status = decode_readdir(xdr, rqstp, res); 680062306a36Sopenharmony_ciout: 680162306a36Sopenharmony_ci return status; 680262306a36Sopenharmony_ci} 680362306a36Sopenharmony_ci 680462306a36Sopenharmony_ci/* 680562306a36Sopenharmony_ci * Decode Read response 680662306a36Sopenharmony_ci */ 680762306a36Sopenharmony_cistatic int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 680862306a36Sopenharmony_ci void *data) 680962306a36Sopenharmony_ci{ 681062306a36Sopenharmony_ci struct nfs_pgio_res *res = data; 681162306a36Sopenharmony_ci struct compound_hdr hdr; 681262306a36Sopenharmony_ci int status; 681362306a36Sopenharmony_ci 681462306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 681562306a36Sopenharmony_ci res->op_status = hdr.status; 681662306a36Sopenharmony_ci if (status) 681762306a36Sopenharmony_ci goto out; 681862306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 681962306a36Sopenharmony_ci if (status) 682062306a36Sopenharmony_ci goto out; 682162306a36Sopenharmony_ci status = decode_putfh(xdr); 682262306a36Sopenharmony_ci if (status) 682362306a36Sopenharmony_ci goto out; 682462306a36Sopenharmony_ci status = decode_read(xdr, rqstp, res); 682562306a36Sopenharmony_ci if (!status) 682662306a36Sopenharmony_ci status = res->count; 682762306a36Sopenharmony_ciout: 682862306a36Sopenharmony_ci return status; 682962306a36Sopenharmony_ci} 683062306a36Sopenharmony_ci 683162306a36Sopenharmony_ci/* 683262306a36Sopenharmony_ci * Decode WRITE response 683362306a36Sopenharmony_ci */ 683462306a36Sopenharmony_cistatic int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 683562306a36Sopenharmony_ci void *data) 683662306a36Sopenharmony_ci{ 683762306a36Sopenharmony_ci struct nfs_pgio_res *res = data; 683862306a36Sopenharmony_ci struct compound_hdr hdr; 683962306a36Sopenharmony_ci int status; 684062306a36Sopenharmony_ci 684162306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 684262306a36Sopenharmony_ci res->op_status = hdr.status; 684362306a36Sopenharmony_ci if (status) 684462306a36Sopenharmony_ci goto out; 684562306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 684662306a36Sopenharmony_ci if (status) 684762306a36Sopenharmony_ci goto out; 684862306a36Sopenharmony_ci status = decode_putfh(xdr); 684962306a36Sopenharmony_ci if (status) 685062306a36Sopenharmony_ci goto out; 685162306a36Sopenharmony_ci status = decode_write(xdr, res); 685262306a36Sopenharmony_ci if (status) 685362306a36Sopenharmony_ci goto out; 685462306a36Sopenharmony_ci if (res->fattr) 685562306a36Sopenharmony_ci decode_getfattr(xdr, res->fattr, res->server); 685662306a36Sopenharmony_ci if (!status) 685762306a36Sopenharmony_ci status = res->count; 685862306a36Sopenharmony_ciout: 685962306a36Sopenharmony_ci return status; 686062306a36Sopenharmony_ci} 686162306a36Sopenharmony_ci 686262306a36Sopenharmony_ci/* 686362306a36Sopenharmony_ci * Decode COMMIT response 686462306a36Sopenharmony_ci */ 686562306a36Sopenharmony_cistatic int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 686662306a36Sopenharmony_ci void *data) 686762306a36Sopenharmony_ci{ 686862306a36Sopenharmony_ci struct nfs_commitres *res = data; 686962306a36Sopenharmony_ci struct compound_hdr hdr; 687062306a36Sopenharmony_ci int status; 687162306a36Sopenharmony_ci 687262306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 687362306a36Sopenharmony_ci res->op_status = hdr.status; 687462306a36Sopenharmony_ci if (status) 687562306a36Sopenharmony_ci goto out; 687662306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 687762306a36Sopenharmony_ci if (status) 687862306a36Sopenharmony_ci goto out; 687962306a36Sopenharmony_ci status = decode_putfh(xdr); 688062306a36Sopenharmony_ci if (status) 688162306a36Sopenharmony_ci goto out; 688262306a36Sopenharmony_ci status = decode_commit(xdr, res); 688362306a36Sopenharmony_ciout: 688462306a36Sopenharmony_ci return status; 688562306a36Sopenharmony_ci} 688662306a36Sopenharmony_ci 688762306a36Sopenharmony_ci/* 688862306a36Sopenharmony_ci * Decode FSINFO response 688962306a36Sopenharmony_ci */ 689062306a36Sopenharmony_cistatic int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, 689162306a36Sopenharmony_ci void *data) 689262306a36Sopenharmony_ci{ 689362306a36Sopenharmony_ci struct nfs4_fsinfo_res *res = data; 689462306a36Sopenharmony_ci struct compound_hdr hdr; 689562306a36Sopenharmony_ci int status; 689662306a36Sopenharmony_ci 689762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 689862306a36Sopenharmony_ci if (!status) 689962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, req); 690062306a36Sopenharmony_ci if (!status) 690162306a36Sopenharmony_ci status = decode_putfh(xdr); 690262306a36Sopenharmony_ci if (!status) 690362306a36Sopenharmony_ci status = decode_fsinfo(xdr, res->fsinfo); 690462306a36Sopenharmony_ci return status; 690562306a36Sopenharmony_ci} 690662306a36Sopenharmony_ci 690762306a36Sopenharmony_ci/* 690862306a36Sopenharmony_ci * Decode PATHCONF response 690962306a36Sopenharmony_ci */ 691062306a36Sopenharmony_cistatic int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, 691162306a36Sopenharmony_ci void *data) 691262306a36Sopenharmony_ci{ 691362306a36Sopenharmony_ci struct nfs4_pathconf_res *res = data; 691462306a36Sopenharmony_ci struct compound_hdr hdr; 691562306a36Sopenharmony_ci int status; 691662306a36Sopenharmony_ci 691762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 691862306a36Sopenharmony_ci if (!status) 691962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, req); 692062306a36Sopenharmony_ci if (!status) 692162306a36Sopenharmony_ci status = decode_putfh(xdr); 692262306a36Sopenharmony_ci if (!status) 692362306a36Sopenharmony_ci status = decode_pathconf(xdr, res->pathconf); 692462306a36Sopenharmony_ci return status; 692562306a36Sopenharmony_ci} 692662306a36Sopenharmony_ci 692762306a36Sopenharmony_ci/* 692862306a36Sopenharmony_ci * Decode STATFS response 692962306a36Sopenharmony_ci */ 693062306a36Sopenharmony_cistatic int nfs4_xdr_dec_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, 693162306a36Sopenharmony_ci void *data) 693262306a36Sopenharmony_ci{ 693362306a36Sopenharmony_ci struct nfs4_statfs_res *res = data; 693462306a36Sopenharmony_ci struct compound_hdr hdr; 693562306a36Sopenharmony_ci int status; 693662306a36Sopenharmony_ci 693762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 693862306a36Sopenharmony_ci if (!status) 693962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, req); 694062306a36Sopenharmony_ci if (!status) 694162306a36Sopenharmony_ci status = decode_putfh(xdr); 694262306a36Sopenharmony_ci if (!status) 694362306a36Sopenharmony_ci status = decode_statfs(xdr, res->fsstat); 694462306a36Sopenharmony_ci return status; 694562306a36Sopenharmony_ci} 694662306a36Sopenharmony_ci 694762306a36Sopenharmony_ci/* 694862306a36Sopenharmony_ci * Decode GETATTR_BITMAP response 694962306a36Sopenharmony_ci */ 695062306a36Sopenharmony_cistatic int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, 695162306a36Sopenharmony_ci struct xdr_stream *xdr, 695262306a36Sopenharmony_ci void *data) 695362306a36Sopenharmony_ci{ 695462306a36Sopenharmony_ci struct nfs4_server_caps_res *res = data; 695562306a36Sopenharmony_ci struct compound_hdr hdr; 695662306a36Sopenharmony_ci int status; 695762306a36Sopenharmony_ci 695862306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 695962306a36Sopenharmony_ci if (status) 696062306a36Sopenharmony_ci goto out; 696162306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, req); 696262306a36Sopenharmony_ci if (status) 696362306a36Sopenharmony_ci goto out; 696462306a36Sopenharmony_ci status = decode_putfh(xdr); 696562306a36Sopenharmony_ci if (status) 696662306a36Sopenharmony_ci goto out; 696762306a36Sopenharmony_ci status = decode_server_caps(xdr, res); 696862306a36Sopenharmony_ciout: 696962306a36Sopenharmony_ci return status; 697062306a36Sopenharmony_ci} 697162306a36Sopenharmony_ci 697262306a36Sopenharmony_ci/* 697362306a36Sopenharmony_ci * Decode RENEW response 697462306a36Sopenharmony_ci */ 697562306a36Sopenharmony_cistatic int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 697662306a36Sopenharmony_ci void *__unused) 697762306a36Sopenharmony_ci{ 697862306a36Sopenharmony_ci struct compound_hdr hdr; 697962306a36Sopenharmony_ci int status; 698062306a36Sopenharmony_ci 698162306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 698262306a36Sopenharmony_ci if (!status) 698362306a36Sopenharmony_ci status = decode_renew(xdr); 698462306a36Sopenharmony_ci return status; 698562306a36Sopenharmony_ci} 698662306a36Sopenharmony_ci 698762306a36Sopenharmony_ci/* 698862306a36Sopenharmony_ci * Decode SETCLIENTID response 698962306a36Sopenharmony_ci */ 699062306a36Sopenharmony_cistatic int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, 699162306a36Sopenharmony_ci struct xdr_stream *xdr, 699262306a36Sopenharmony_ci void *data) 699362306a36Sopenharmony_ci{ 699462306a36Sopenharmony_ci struct nfs4_setclientid_res *res = data; 699562306a36Sopenharmony_ci struct compound_hdr hdr; 699662306a36Sopenharmony_ci int status; 699762306a36Sopenharmony_ci 699862306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 699962306a36Sopenharmony_ci if (!status) 700062306a36Sopenharmony_ci status = decode_setclientid(xdr, res); 700162306a36Sopenharmony_ci return status; 700262306a36Sopenharmony_ci} 700362306a36Sopenharmony_ci 700462306a36Sopenharmony_ci/* 700562306a36Sopenharmony_ci * Decode SETCLIENTID_CONFIRM response 700662306a36Sopenharmony_ci */ 700762306a36Sopenharmony_cistatic int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, 700862306a36Sopenharmony_ci struct xdr_stream *xdr, 700962306a36Sopenharmony_ci void *data) 701062306a36Sopenharmony_ci{ 701162306a36Sopenharmony_ci struct compound_hdr hdr; 701262306a36Sopenharmony_ci int status; 701362306a36Sopenharmony_ci 701462306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 701562306a36Sopenharmony_ci if (!status) 701662306a36Sopenharmony_ci status = decode_setclientid_confirm(xdr); 701762306a36Sopenharmony_ci return status; 701862306a36Sopenharmony_ci} 701962306a36Sopenharmony_ci 702062306a36Sopenharmony_ci/* 702162306a36Sopenharmony_ci * Decode DELEGRETURN response 702262306a36Sopenharmony_ci */ 702362306a36Sopenharmony_cistatic int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, 702462306a36Sopenharmony_ci struct xdr_stream *xdr, 702562306a36Sopenharmony_ci void *data) 702662306a36Sopenharmony_ci{ 702762306a36Sopenharmony_ci struct nfs4_delegreturnres *res = data; 702862306a36Sopenharmony_ci struct compound_hdr hdr; 702962306a36Sopenharmony_ci int status; 703062306a36Sopenharmony_ci 703162306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 703262306a36Sopenharmony_ci if (status) 703362306a36Sopenharmony_ci goto out; 703462306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 703562306a36Sopenharmony_ci if (status) 703662306a36Sopenharmony_ci goto out; 703762306a36Sopenharmony_ci status = decode_putfh(xdr); 703862306a36Sopenharmony_ci if (status != 0) 703962306a36Sopenharmony_ci goto out; 704062306a36Sopenharmony_ci if (res->lr_res) { 704162306a36Sopenharmony_ci status = decode_layoutreturn(xdr, res->lr_res); 704262306a36Sopenharmony_ci res->lr_ret = status; 704362306a36Sopenharmony_ci if (status) 704462306a36Sopenharmony_ci goto out; 704562306a36Sopenharmony_ci } 704662306a36Sopenharmony_ci if (res->fattr) { 704762306a36Sopenharmony_ci status = decode_getfattr(xdr, res->fattr, res->server); 704862306a36Sopenharmony_ci if (status != 0) 704962306a36Sopenharmony_ci goto out; 705062306a36Sopenharmony_ci } 705162306a36Sopenharmony_ci status = decode_delegreturn(xdr); 705262306a36Sopenharmony_ciout: 705362306a36Sopenharmony_ci return status; 705462306a36Sopenharmony_ci} 705562306a36Sopenharmony_ci 705662306a36Sopenharmony_ci/* 705762306a36Sopenharmony_ci * Decode FS_LOCATIONS response 705862306a36Sopenharmony_ci */ 705962306a36Sopenharmony_cistatic int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, 706062306a36Sopenharmony_ci struct xdr_stream *xdr, 706162306a36Sopenharmony_ci void *data) 706262306a36Sopenharmony_ci{ 706362306a36Sopenharmony_ci struct nfs4_fs_locations_res *res = data; 706462306a36Sopenharmony_ci struct compound_hdr hdr; 706562306a36Sopenharmony_ci int status; 706662306a36Sopenharmony_ci 706762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 706862306a36Sopenharmony_ci if (status) 706962306a36Sopenharmony_ci goto out; 707062306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, req); 707162306a36Sopenharmony_ci if (status) 707262306a36Sopenharmony_ci goto out; 707362306a36Sopenharmony_ci status = decode_putfh(xdr); 707462306a36Sopenharmony_ci if (status) 707562306a36Sopenharmony_ci goto out; 707662306a36Sopenharmony_ci if (res->migration) { 707762306a36Sopenharmony_ci xdr_enter_page(xdr, PAGE_SIZE); 707862306a36Sopenharmony_ci status = decode_getfattr_generic(xdr, 707962306a36Sopenharmony_ci res->fs_locations->fattr, 708062306a36Sopenharmony_ci NULL, res->fs_locations, 708162306a36Sopenharmony_ci res->fs_locations->server); 708262306a36Sopenharmony_ci if (status) 708362306a36Sopenharmony_ci goto out; 708462306a36Sopenharmony_ci if (res->renew) 708562306a36Sopenharmony_ci status = decode_renew(xdr); 708662306a36Sopenharmony_ci } else { 708762306a36Sopenharmony_ci status = decode_lookup(xdr); 708862306a36Sopenharmony_ci if (status) 708962306a36Sopenharmony_ci goto out; 709062306a36Sopenharmony_ci xdr_enter_page(xdr, PAGE_SIZE); 709162306a36Sopenharmony_ci status = decode_getfattr_generic(xdr, 709262306a36Sopenharmony_ci res->fs_locations->fattr, 709362306a36Sopenharmony_ci NULL, res->fs_locations, 709462306a36Sopenharmony_ci res->fs_locations->server); 709562306a36Sopenharmony_ci } 709662306a36Sopenharmony_ciout: 709762306a36Sopenharmony_ci return status; 709862306a36Sopenharmony_ci} 709962306a36Sopenharmony_ci 710062306a36Sopenharmony_ci/* 710162306a36Sopenharmony_ci * Decode SECINFO response 710262306a36Sopenharmony_ci */ 710362306a36Sopenharmony_cistatic int nfs4_xdr_dec_secinfo(struct rpc_rqst *rqstp, 710462306a36Sopenharmony_ci struct xdr_stream *xdr, 710562306a36Sopenharmony_ci void *data) 710662306a36Sopenharmony_ci{ 710762306a36Sopenharmony_ci struct nfs4_secinfo_res *res = data; 710862306a36Sopenharmony_ci struct compound_hdr hdr; 710962306a36Sopenharmony_ci int status; 711062306a36Sopenharmony_ci 711162306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 711262306a36Sopenharmony_ci if (status) 711362306a36Sopenharmony_ci goto out; 711462306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 711562306a36Sopenharmony_ci if (status) 711662306a36Sopenharmony_ci goto out; 711762306a36Sopenharmony_ci status = decode_putfh(xdr); 711862306a36Sopenharmony_ci if (status) 711962306a36Sopenharmony_ci goto out; 712062306a36Sopenharmony_ci status = decode_secinfo(xdr, res); 712162306a36Sopenharmony_ciout: 712262306a36Sopenharmony_ci return status; 712362306a36Sopenharmony_ci} 712462306a36Sopenharmony_ci 712562306a36Sopenharmony_ci/* 712662306a36Sopenharmony_ci * Decode FSID_PRESENT response 712762306a36Sopenharmony_ci */ 712862306a36Sopenharmony_cistatic int nfs4_xdr_dec_fsid_present(struct rpc_rqst *rqstp, 712962306a36Sopenharmony_ci struct xdr_stream *xdr, 713062306a36Sopenharmony_ci void *data) 713162306a36Sopenharmony_ci{ 713262306a36Sopenharmony_ci struct nfs4_fsid_present_res *res = data; 713362306a36Sopenharmony_ci struct compound_hdr hdr; 713462306a36Sopenharmony_ci int status; 713562306a36Sopenharmony_ci 713662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 713762306a36Sopenharmony_ci if (status) 713862306a36Sopenharmony_ci goto out; 713962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 714062306a36Sopenharmony_ci if (status) 714162306a36Sopenharmony_ci goto out; 714262306a36Sopenharmony_ci status = decode_putfh(xdr); 714362306a36Sopenharmony_ci if (status) 714462306a36Sopenharmony_ci goto out; 714562306a36Sopenharmony_ci status = decode_getfh(xdr, res->fh); 714662306a36Sopenharmony_ci if (status) 714762306a36Sopenharmony_ci goto out; 714862306a36Sopenharmony_ci if (res->renew) 714962306a36Sopenharmony_ci status = decode_renew(xdr); 715062306a36Sopenharmony_ciout: 715162306a36Sopenharmony_ci return status; 715262306a36Sopenharmony_ci} 715362306a36Sopenharmony_ci 715462306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 715562306a36Sopenharmony_ci/* 715662306a36Sopenharmony_ci * Decode BIND_CONN_TO_SESSION response 715762306a36Sopenharmony_ci */ 715862306a36Sopenharmony_cistatic int nfs4_xdr_dec_bind_conn_to_session(struct rpc_rqst *rqstp, 715962306a36Sopenharmony_ci struct xdr_stream *xdr, 716062306a36Sopenharmony_ci void *res) 716162306a36Sopenharmony_ci{ 716262306a36Sopenharmony_ci struct compound_hdr hdr; 716362306a36Sopenharmony_ci int status; 716462306a36Sopenharmony_ci 716562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 716662306a36Sopenharmony_ci if (!status) 716762306a36Sopenharmony_ci status = decode_bind_conn_to_session(xdr, res); 716862306a36Sopenharmony_ci return status; 716962306a36Sopenharmony_ci} 717062306a36Sopenharmony_ci 717162306a36Sopenharmony_ci/* 717262306a36Sopenharmony_ci * Decode EXCHANGE_ID response 717362306a36Sopenharmony_ci */ 717462306a36Sopenharmony_cistatic int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, 717562306a36Sopenharmony_ci struct xdr_stream *xdr, 717662306a36Sopenharmony_ci void *res) 717762306a36Sopenharmony_ci{ 717862306a36Sopenharmony_ci struct compound_hdr hdr; 717962306a36Sopenharmony_ci int status; 718062306a36Sopenharmony_ci 718162306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 718262306a36Sopenharmony_ci if (!status) 718362306a36Sopenharmony_ci status = decode_exchange_id(xdr, res); 718462306a36Sopenharmony_ci return status; 718562306a36Sopenharmony_ci} 718662306a36Sopenharmony_ci 718762306a36Sopenharmony_ci/* 718862306a36Sopenharmony_ci * Decode CREATE_SESSION response 718962306a36Sopenharmony_ci */ 719062306a36Sopenharmony_cistatic int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, 719162306a36Sopenharmony_ci struct xdr_stream *xdr, 719262306a36Sopenharmony_ci void *res) 719362306a36Sopenharmony_ci{ 719462306a36Sopenharmony_ci struct compound_hdr hdr; 719562306a36Sopenharmony_ci int status; 719662306a36Sopenharmony_ci 719762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 719862306a36Sopenharmony_ci if (!status) 719962306a36Sopenharmony_ci status = decode_create_session(xdr, res); 720062306a36Sopenharmony_ci return status; 720162306a36Sopenharmony_ci} 720262306a36Sopenharmony_ci 720362306a36Sopenharmony_ci/* 720462306a36Sopenharmony_ci * Decode DESTROY_SESSION response 720562306a36Sopenharmony_ci */ 720662306a36Sopenharmony_cistatic int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, 720762306a36Sopenharmony_ci struct xdr_stream *xdr, 720862306a36Sopenharmony_ci void *res) 720962306a36Sopenharmony_ci{ 721062306a36Sopenharmony_ci struct compound_hdr hdr; 721162306a36Sopenharmony_ci int status; 721262306a36Sopenharmony_ci 721362306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 721462306a36Sopenharmony_ci if (!status) 721562306a36Sopenharmony_ci status = decode_destroy_session(xdr, res); 721662306a36Sopenharmony_ci return status; 721762306a36Sopenharmony_ci} 721862306a36Sopenharmony_ci 721962306a36Sopenharmony_ci/* 722062306a36Sopenharmony_ci * Decode DESTROY_CLIENTID response 722162306a36Sopenharmony_ci */ 722262306a36Sopenharmony_cistatic int nfs4_xdr_dec_destroy_clientid(struct rpc_rqst *rqstp, 722362306a36Sopenharmony_ci struct xdr_stream *xdr, 722462306a36Sopenharmony_ci void *res) 722562306a36Sopenharmony_ci{ 722662306a36Sopenharmony_ci struct compound_hdr hdr; 722762306a36Sopenharmony_ci int status; 722862306a36Sopenharmony_ci 722962306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 723062306a36Sopenharmony_ci if (!status) 723162306a36Sopenharmony_ci status = decode_destroy_clientid(xdr, res); 723262306a36Sopenharmony_ci return status; 723362306a36Sopenharmony_ci} 723462306a36Sopenharmony_ci 723562306a36Sopenharmony_ci/* 723662306a36Sopenharmony_ci * Decode SEQUENCE response 723762306a36Sopenharmony_ci */ 723862306a36Sopenharmony_cistatic int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, 723962306a36Sopenharmony_ci struct xdr_stream *xdr, 724062306a36Sopenharmony_ci void *res) 724162306a36Sopenharmony_ci{ 724262306a36Sopenharmony_ci struct compound_hdr hdr; 724362306a36Sopenharmony_ci int status; 724462306a36Sopenharmony_ci 724562306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 724662306a36Sopenharmony_ci if (!status) 724762306a36Sopenharmony_ci status = decode_sequence(xdr, res, rqstp); 724862306a36Sopenharmony_ci return status; 724962306a36Sopenharmony_ci} 725062306a36Sopenharmony_ci 725162306a36Sopenharmony_ci#endif 725262306a36Sopenharmony_ci 725362306a36Sopenharmony_ci/* 725462306a36Sopenharmony_ci * Decode GET_LEASE_TIME response 725562306a36Sopenharmony_ci */ 725662306a36Sopenharmony_cistatic int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, 725762306a36Sopenharmony_ci struct xdr_stream *xdr, 725862306a36Sopenharmony_ci void *data) 725962306a36Sopenharmony_ci{ 726062306a36Sopenharmony_ci struct nfs4_get_lease_time_res *res = data; 726162306a36Sopenharmony_ci struct compound_hdr hdr; 726262306a36Sopenharmony_ci int status; 726362306a36Sopenharmony_ci 726462306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 726562306a36Sopenharmony_ci if (!status) 726662306a36Sopenharmony_ci status = decode_sequence(xdr, &res->lr_seq_res, rqstp); 726762306a36Sopenharmony_ci if (!status) 726862306a36Sopenharmony_ci status = decode_putrootfh(xdr); 726962306a36Sopenharmony_ci if (!status) 727062306a36Sopenharmony_ci status = decode_fsinfo(xdr, res->lr_fsinfo); 727162306a36Sopenharmony_ci return status; 727262306a36Sopenharmony_ci} 727362306a36Sopenharmony_ci 727462306a36Sopenharmony_ci#ifdef CONFIG_NFS_V4_1 727562306a36Sopenharmony_ci 727662306a36Sopenharmony_ci/* 727762306a36Sopenharmony_ci * Decode RECLAIM_COMPLETE response 727862306a36Sopenharmony_ci */ 727962306a36Sopenharmony_cistatic int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, 728062306a36Sopenharmony_ci struct xdr_stream *xdr, 728162306a36Sopenharmony_ci void *data) 728262306a36Sopenharmony_ci{ 728362306a36Sopenharmony_ci struct nfs41_reclaim_complete_res *res = data; 728462306a36Sopenharmony_ci struct compound_hdr hdr; 728562306a36Sopenharmony_ci int status; 728662306a36Sopenharmony_ci 728762306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 728862306a36Sopenharmony_ci if (!status) 728962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 729062306a36Sopenharmony_ci if (!status) 729162306a36Sopenharmony_ci status = decode_reclaim_complete(xdr, NULL); 729262306a36Sopenharmony_ci return status; 729362306a36Sopenharmony_ci} 729462306a36Sopenharmony_ci 729562306a36Sopenharmony_ci/* 729662306a36Sopenharmony_ci * Decode GETDEVINFO response 729762306a36Sopenharmony_ci */ 729862306a36Sopenharmony_cistatic int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, 729962306a36Sopenharmony_ci struct xdr_stream *xdr, 730062306a36Sopenharmony_ci void *data) 730162306a36Sopenharmony_ci{ 730262306a36Sopenharmony_ci struct nfs4_getdeviceinfo_res *res = data; 730362306a36Sopenharmony_ci struct compound_hdr hdr; 730462306a36Sopenharmony_ci int status; 730562306a36Sopenharmony_ci 730662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 730762306a36Sopenharmony_ci if (status != 0) 730862306a36Sopenharmony_ci goto out; 730962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 731062306a36Sopenharmony_ci if (status != 0) 731162306a36Sopenharmony_ci goto out; 731262306a36Sopenharmony_ci status = decode_getdeviceinfo(xdr, res); 731362306a36Sopenharmony_ciout: 731462306a36Sopenharmony_ci return status; 731562306a36Sopenharmony_ci} 731662306a36Sopenharmony_ci 731762306a36Sopenharmony_ci/* 731862306a36Sopenharmony_ci * Decode LAYOUTGET response 731962306a36Sopenharmony_ci */ 732062306a36Sopenharmony_cistatic int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp, 732162306a36Sopenharmony_ci struct xdr_stream *xdr, 732262306a36Sopenharmony_ci void *data) 732362306a36Sopenharmony_ci{ 732462306a36Sopenharmony_ci struct nfs4_layoutget_res *res = data; 732562306a36Sopenharmony_ci struct compound_hdr hdr; 732662306a36Sopenharmony_ci int status; 732762306a36Sopenharmony_ci 732862306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 732962306a36Sopenharmony_ci if (status) 733062306a36Sopenharmony_ci goto out; 733162306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 733262306a36Sopenharmony_ci if (status) 733362306a36Sopenharmony_ci goto out; 733462306a36Sopenharmony_ci status = decode_putfh(xdr); 733562306a36Sopenharmony_ci if (status) 733662306a36Sopenharmony_ci goto out; 733762306a36Sopenharmony_ci status = decode_layoutget(xdr, rqstp, res); 733862306a36Sopenharmony_ciout: 733962306a36Sopenharmony_ci return status; 734062306a36Sopenharmony_ci} 734162306a36Sopenharmony_ci 734262306a36Sopenharmony_ci/* 734362306a36Sopenharmony_ci * Decode LAYOUTRETURN response 734462306a36Sopenharmony_ci */ 734562306a36Sopenharmony_cistatic int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp, 734662306a36Sopenharmony_ci struct xdr_stream *xdr, 734762306a36Sopenharmony_ci void *data) 734862306a36Sopenharmony_ci{ 734962306a36Sopenharmony_ci struct nfs4_layoutreturn_res *res = data; 735062306a36Sopenharmony_ci struct compound_hdr hdr; 735162306a36Sopenharmony_ci int status; 735262306a36Sopenharmony_ci 735362306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 735462306a36Sopenharmony_ci if (status) 735562306a36Sopenharmony_ci goto out; 735662306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 735762306a36Sopenharmony_ci if (status) 735862306a36Sopenharmony_ci goto out; 735962306a36Sopenharmony_ci status = decode_putfh(xdr); 736062306a36Sopenharmony_ci if (status) 736162306a36Sopenharmony_ci goto out; 736262306a36Sopenharmony_ci status = decode_layoutreturn(xdr, res); 736362306a36Sopenharmony_ciout: 736462306a36Sopenharmony_ci return status; 736562306a36Sopenharmony_ci} 736662306a36Sopenharmony_ci 736762306a36Sopenharmony_ci/* 736862306a36Sopenharmony_ci * Decode LAYOUTCOMMIT response 736962306a36Sopenharmony_ci */ 737062306a36Sopenharmony_cistatic int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, 737162306a36Sopenharmony_ci struct xdr_stream *xdr, 737262306a36Sopenharmony_ci void *data) 737362306a36Sopenharmony_ci{ 737462306a36Sopenharmony_ci struct nfs4_layoutcommit_res *res = data; 737562306a36Sopenharmony_ci struct compound_hdr hdr; 737662306a36Sopenharmony_ci int status; 737762306a36Sopenharmony_ci 737862306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 737962306a36Sopenharmony_ci if (status) 738062306a36Sopenharmony_ci goto out; 738162306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 738262306a36Sopenharmony_ci if (status) 738362306a36Sopenharmony_ci goto out; 738462306a36Sopenharmony_ci status = decode_putfh(xdr); 738562306a36Sopenharmony_ci if (status) 738662306a36Sopenharmony_ci goto out; 738762306a36Sopenharmony_ci status = decode_layoutcommit(xdr, rqstp, res); 738862306a36Sopenharmony_ci if (status) 738962306a36Sopenharmony_ci goto out; 739062306a36Sopenharmony_ci decode_getfattr(xdr, res->fattr, res->server); 739162306a36Sopenharmony_ciout: 739262306a36Sopenharmony_ci return status; 739362306a36Sopenharmony_ci} 739462306a36Sopenharmony_ci 739562306a36Sopenharmony_ci/* 739662306a36Sopenharmony_ci * Decode SECINFO_NO_NAME response 739762306a36Sopenharmony_ci */ 739862306a36Sopenharmony_cistatic int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp, 739962306a36Sopenharmony_ci struct xdr_stream *xdr, 740062306a36Sopenharmony_ci void *data) 740162306a36Sopenharmony_ci{ 740262306a36Sopenharmony_ci struct nfs4_secinfo_res *res = data; 740362306a36Sopenharmony_ci struct compound_hdr hdr; 740462306a36Sopenharmony_ci int status; 740562306a36Sopenharmony_ci 740662306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 740762306a36Sopenharmony_ci if (status) 740862306a36Sopenharmony_ci goto out; 740962306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 741062306a36Sopenharmony_ci if (status) 741162306a36Sopenharmony_ci goto out; 741262306a36Sopenharmony_ci status = decode_putrootfh(xdr); 741362306a36Sopenharmony_ci if (status) 741462306a36Sopenharmony_ci goto out; 741562306a36Sopenharmony_ci status = decode_secinfo_no_name(xdr, res); 741662306a36Sopenharmony_ciout: 741762306a36Sopenharmony_ci return status; 741862306a36Sopenharmony_ci} 741962306a36Sopenharmony_ci 742062306a36Sopenharmony_ci/* 742162306a36Sopenharmony_ci * Decode TEST_STATEID response 742262306a36Sopenharmony_ci */ 742362306a36Sopenharmony_cistatic int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp, 742462306a36Sopenharmony_ci struct xdr_stream *xdr, 742562306a36Sopenharmony_ci void *data) 742662306a36Sopenharmony_ci{ 742762306a36Sopenharmony_ci struct nfs41_test_stateid_res *res = data; 742862306a36Sopenharmony_ci struct compound_hdr hdr; 742962306a36Sopenharmony_ci int status; 743062306a36Sopenharmony_ci 743162306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 743262306a36Sopenharmony_ci if (status) 743362306a36Sopenharmony_ci goto out; 743462306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 743562306a36Sopenharmony_ci if (status) 743662306a36Sopenharmony_ci goto out; 743762306a36Sopenharmony_ci status = decode_test_stateid(xdr, res); 743862306a36Sopenharmony_ciout: 743962306a36Sopenharmony_ci return status; 744062306a36Sopenharmony_ci} 744162306a36Sopenharmony_ci 744262306a36Sopenharmony_ci/* 744362306a36Sopenharmony_ci * Decode FREE_STATEID response 744462306a36Sopenharmony_ci */ 744562306a36Sopenharmony_cistatic int nfs4_xdr_dec_free_stateid(struct rpc_rqst *rqstp, 744662306a36Sopenharmony_ci struct xdr_stream *xdr, 744762306a36Sopenharmony_ci void *data) 744862306a36Sopenharmony_ci{ 744962306a36Sopenharmony_ci struct nfs41_free_stateid_res *res = data; 745062306a36Sopenharmony_ci struct compound_hdr hdr; 745162306a36Sopenharmony_ci int status; 745262306a36Sopenharmony_ci 745362306a36Sopenharmony_ci status = decode_compound_hdr(xdr, &hdr); 745462306a36Sopenharmony_ci if (status) 745562306a36Sopenharmony_ci goto out; 745662306a36Sopenharmony_ci status = decode_sequence(xdr, &res->seq_res, rqstp); 745762306a36Sopenharmony_ci if (status) 745862306a36Sopenharmony_ci goto out; 745962306a36Sopenharmony_ci status = decode_free_stateid(xdr, res); 746062306a36Sopenharmony_ciout: 746162306a36Sopenharmony_ci return status; 746262306a36Sopenharmony_ci} 746362306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_1 */ 746462306a36Sopenharmony_ci 746562306a36Sopenharmony_ci/** 746662306a36Sopenharmony_ci * nfs4_decode_dirent - Decode a single NFSv4 directory entry stored in 746762306a36Sopenharmony_ci * the local page cache. 746862306a36Sopenharmony_ci * @xdr: XDR stream where entry resides 746962306a36Sopenharmony_ci * @entry: buffer to fill in with entry data 747062306a36Sopenharmony_ci * @plus: boolean indicating whether this should be a readdirplus entry 747162306a36Sopenharmony_ci * 747262306a36Sopenharmony_ci * Returns zero if successful, otherwise a negative errno value is 747362306a36Sopenharmony_ci * returned. 747462306a36Sopenharmony_ci * 747562306a36Sopenharmony_ci * This function is not invoked during READDIR reply decoding, but 747662306a36Sopenharmony_ci * rather whenever an application invokes the getdents(2) system call 747762306a36Sopenharmony_ci * on a directory already in our cache. 747862306a36Sopenharmony_ci */ 747962306a36Sopenharmony_ciint nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, 748062306a36Sopenharmony_ci bool plus) 748162306a36Sopenharmony_ci{ 748262306a36Sopenharmony_ci unsigned int savep; 748362306a36Sopenharmony_ci uint32_t bitmap[3] = {0}; 748462306a36Sopenharmony_ci uint32_t len; 748562306a36Sopenharmony_ci uint64_t new_cookie; 748662306a36Sopenharmony_ci __be32 *p = xdr_inline_decode(xdr, 4); 748762306a36Sopenharmony_ci if (unlikely(!p)) 748862306a36Sopenharmony_ci return -EAGAIN; 748962306a36Sopenharmony_ci if (*p == xdr_zero) { 749062306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 4); 749162306a36Sopenharmony_ci if (unlikely(!p)) 749262306a36Sopenharmony_ci return -EAGAIN; 749362306a36Sopenharmony_ci if (*p == xdr_zero) 749462306a36Sopenharmony_ci return -EAGAIN; 749562306a36Sopenharmony_ci entry->eof = 1; 749662306a36Sopenharmony_ci return -EBADCOOKIE; 749762306a36Sopenharmony_ci } 749862306a36Sopenharmony_ci 749962306a36Sopenharmony_ci p = xdr_inline_decode(xdr, 12); 750062306a36Sopenharmony_ci if (unlikely(!p)) 750162306a36Sopenharmony_ci return -EAGAIN; 750262306a36Sopenharmony_ci p = xdr_decode_hyper(p, &new_cookie); 750362306a36Sopenharmony_ci entry->len = be32_to_cpup(p); 750462306a36Sopenharmony_ci 750562306a36Sopenharmony_ci p = xdr_inline_decode(xdr, entry->len); 750662306a36Sopenharmony_ci if (unlikely(!p)) 750762306a36Sopenharmony_ci return -EAGAIN; 750862306a36Sopenharmony_ci entry->name = (const char *) p; 750962306a36Sopenharmony_ci 751062306a36Sopenharmony_ci /* 751162306a36Sopenharmony_ci * In case the server doesn't return an inode number, 751262306a36Sopenharmony_ci * we fake one here. (We don't use inode number 0, 751362306a36Sopenharmony_ci * since glibc seems to choke on it...) 751462306a36Sopenharmony_ci */ 751562306a36Sopenharmony_ci entry->ino = 1; 751662306a36Sopenharmony_ci entry->fattr->valid = 0; 751762306a36Sopenharmony_ci 751862306a36Sopenharmony_ci if (decode_attr_bitmap(xdr, bitmap) < 0) 751962306a36Sopenharmony_ci return -EAGAIN; 752062306a36Sopenharmony_ci 752162306a36Sopenharmony_ci if (decode_attr_length(xdr, &len, &savep) < 0) 752262306a36Sopenharmony_ci return -EAGAIN; 752362306a36Sopenharmony_ci 752462306a36Sopenharmony_ci if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, 752562306a36Sopenharmony_ci NULL, entry->server) < 0) 752662306a36Sopenharmony_ci return -EAGAIN; 752762306a36Sopenharmony_ci if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) 752862306a36Sopenharmony_ci entry->ino = entry->fattr->mounted_on_fileid; 752962306a36Sopenharmony_ci else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) 753062306a36Sopenharmony_ci entry->ino = entry->fattr->fileid; 753162306a36Sopenharmony_ci 753262306a36Sopenharmony_ci entry->d_type = DT_UNKNOWN; 753362306a36Sopenharmony_ci if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE) 753462306a36Sopenharmony_ci entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); 753562306a36Sopenharmony_ci 753662306a36Sopenharmony_ci entry->cookie = new_cookie; 753762306a36Sopenharmony_ci 753862306a36Sopenharmony_ci return 0; 753962306a36Sopenharmony_ci} 754062306a36Sopenharmony_ci 754162306a36Sopenharmony_ci/* 754262306a36Sopenharmony_ci * We need to translate between nfs status return values and 754362306a36Sopenharmony_ci * the local errno values which may not be the same. 754462306a36Sopenharmony_ci */ 754562306a36Sopenharmony_cistatic struct { 754662306a36Sopenharmony_ci int stat; 754762306a36Sopenharmony_ci int errno; 754862306a36Sopenharmony_ci} nfs_errtbl[] = { 754962306a36Sopenharmony_ci { NFS4_OK, 0 }, 755062306a36Sopenharmony_ci { NFS4ERR_PERM, -EPERM }, 755162306a36Sopenharmony_ci { NFS4ERR_NOENT, -ENOENT }, 755262306a36Sopenharmony_ci { NFS4ERR_IO, -errno_NFSERR_IO}, 755362306a36Sopenharmony_ci { NFS4ERR_NXIO, -ENXIO }, 755462306a36Sopenharmony_ci { NFS4ERR_ACCESS, -EACCES }, 755562306a36Sopenharmony_ci { NFS4ERR_EXIST, -EEXIST }, 755662306a36Sopenharmony_ci { NFS4ERR_XDEV, -EXDEV }, 755762306a36Sopenharmony_ci { NFS4ERR_NOTDIR, -ENOTDIR }, 755862306a36Sopenharmony_ci { NFS4ERR_ISDIR, -EISDIR }, 755962306a36Sopenharmony_ci { NFS4ERR_INVAL, -EINVAL }, 756062306a36Sopenharmony_ci { NFS4ERR_FBIG, -EFBIG }, 756162306a36Sopenharmony_ci { NFS4ERR_NOSPC, -ENOSPC }, 756262306a36Sopenharmony_ci { NFS4ERR_ROFS, -EROFS }, 756362306a36Sopenharmony_ci { NFS4ERR_MLINK, -EMLINK }, 756462306a36Sopenharmony_ci { NFS4ERR_NAMETOOLONG, -ENAMETOOLONG }, 756562306a36Sopenharmony_ci { NFS4ERR_NOTEMPTY, -ENOTEMPTY }, 756662306a36Sopenharmony_ci { NFS4ERR_DQUOT, -EDQUOT }, 756762306a36Sopenharmony_ci { NFS4ERR_STALE, -ESTALE }, 756862306a36Sopenharmony_ci { NFS4ERR_BADHANDLE, -EBADHANDLE }, 756962306a36Sopenharmony_ci { NFS4ERR_BAD_COOKIE, -EBADCOOKIE }, 757062306a36Sopenharmony_ci { NFS4ERR_NOTSUPP, -ENOTSUPP }, 757162306a36Sopenharmony_ci { NFS4ERR_TOOSMALL, -ETOOSMALL }, 757262306a36Sopenharmony_ci { NFS4ERR_SERVERFAULT, -EREMOTEIO }, 757362306a36Sopenharmony_ci { NFS4ERR_BADTYPE, -EBADTYPE }, 757462306a36Sopenharmony_ci { NFS4ERR_LOCKED, -EAGAIN }, 757562306a36Sopenharmony_ci { NFS4ERR_SYMLINK, -ELOOP }, 757662306a36Sopenharmony_ci { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP }, 757762306a36Sopenharmony_ci { NFS4ERR_DEADLOCK, -EDEADLK }, 757862306a36Sopenharmony_ci { NFS4ERR_NOXATTR, -ENODATA }, 757962306a36Sopenharmony_ci { NFS4ERR_XATTR2BIG, -E2BIG }, 758062306a36Sopenharmony_ci { -1, -EIO } 758162306a36Sopenharmony_ci}; 758262306a36Sopenharmony_ci 758362306a36Sopenharmony_ci/* 758462306a36Sopenharmony_ci * Convert an NFS error code to a local one. 758562306a36Sopenharmony_ci * This one is used jointly by NFSv2 and NFSv3. 758662306a36Sopenharmony_ci */ 758762306a36Sopenharmony_cistatic int 758862306a36Sopenharmony_cinfs4_stat_to_errno(int stat) 758962306a36Sopenharmony_ci{ 759062306a36Sopenharmony_ci int i; 759162306a36Sopenharmony_ci for (i = 0; nfs_errtbl[i].stat != -1; i++) { 759262306a36Sopenharmony_ci if (nfs_errtbl[i].stat == stat) 759362306a36Sopenharmony_ci return nfs_errtbl[i].errno; 759462306a36Sopenharmony_ci } 759562306a36Sopenharmony_ci if (stat <= 10000 || stat > 10100) { 759662306a36Sopenharmony_ci /* The server is looney tunes. */ 759762306a36Sopenharmony_ci return -EREMOTEIO; 759862306a36Sopenharmony_ci } 759962306a36Sopenharmony_ci /* If we cannot translate the error, the recovery routines should 760062306a36Sopenharmony_ci * handle it. 760162306a36Sopenharmony_ci * Note: remaining NFSv4 error codes have values > 10000, so should 760262306a36Sopenharmony_ci * not conflict with native Linux error codes. 760362306a36Sopenharmony_ci */ 760462306a36Sopenharmony_ci return -stat; 760562306a36Sopenharmony_ci} 760662306a36Sopenharmony_ci 760762306a36Sopenharmony_ci#ifdef CONFIG_NFS_V4_2 760862306a36Sopenharmony_ci#include "nfs42xdr.c" 760962306a36Sopenharmony_ci#endif /* CONFIG_NFS_V4_2 */ 761062306a36Sopenharmony_ci 761162306a36Sopenharmony_ci#define PROC(proc, argtype, restype) \ 761262306a36Sopenharmony_ci[NFSPROC4_CLNT_##proc] = { \ 761362306a36Sopenharmony_ci .p_proc = NFSPROC4_COMPOUND, \ 761462306a36Sopenharmony_ci .p_encode = nfs4_xdr_##argtype, \ 761562306a36Sopenharmony_ci .p_decode = nfs4_xdr_##restype, \ 761662306a36Sopenharmony_ci .p_arglen = NFS4_##argtype##_sz, \ 761762306a36Sopenharmony_ci .p_replen = NFS4_##restype##_sz, \ 761862306a36Sopenharmony_ci .p_statidx = NFSPROC4_CLNT_##proc, \ 761962306a36Sopenharmony_ci .p_name = #proc, \ 762062306a36Sopenharmony_ci} 762162306a36Sopenharmony_ci 762262306a36Sopenharmony_ci#define STUB(proc) \ 762362306a36Sopenharmony_ci[NFSPROC4_CLNT_##proc] = { \ 762462306a36Sopenharmony_ci .p_name = #proc, \ 762562306a36Sopenharmony_ci} 762662306a36Sopenharmony_ci 762762306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_1) 762862306a36Sopenharmony_ci#define PROC41(proc, argtype, restype) \ 762962306a36Sopenharmony_ci PROC(proc, argtype, restype) 763062306a36Sopenharmony_ci#else 763162306a36Sopenharmony_ci#define PROC41(proc, argtype, restype) \ 763262306a36Sopenharmony_ci STUB(proc) 763362306a36Sopenharmony_ci#endif 763462306a36Sopenharmony_ci 763562306a36Sopenharmony_ci#if defined(CONFIG_NFS_V4_2) 763662306a36Sopenharmony_ci#define PROC42(proc, argtype, restype) \ 763762306a36Sopenharmony_ci PROC(proc, argtype, restype) 763862306a36Sopenharmony_ci#else 763962306a36Sopenharmony_ci#define PROC42(proc, argtype, restype) \ 764062306a36Sopenharmony_ci STUB(proc) 764162306a36Sopenharmony_ci#endif 764262306a36Sopenharmony_ci 764362306a36Sopenharmony_ciconst struct rpc_procinfo nfs4_procedures[] = { 764462306a36Sopenharmony_ci PROC(READ, enc_read, dec_read), 764562306a36Sopenharmony_ci PROC(WRITE, enc_write, dec_write), 764662306a36Sopenharmony_ci PROC(COMMIT, enc_commit, dec_commit), 764762306a36Sopenharmony_ci PROC(OPEN, enc_open, dec_open), 764862306a36Sopenharmony_ci PROC(OPEN_CONFIRM, enc_open_confirm, dec_open_confirm), 764962306a36Sopenharmony_ci PROC(OPEN_NOATTR, enc_open_noattr, dec_open_noattr), 765062306a36Sopenharmony_ci PROC(OPEN_DOWNGRADE, enc_open_downgrade, dec_open_downgrade), 765162306a36Sopenharmony_ci PROC(CLOSE, enc_close, dec_close), 765262306a36Sopenharmony_ci PROC(SETATTR, enc_setattr, dec_setattr), 765362306a36Sopenharmony_ci PROC(FSINFO, enc_fsinfo, dec_fsinfo), 765462306a36Sopenharmony_ci PROC(RENEW, enc_renew, dec_renew), 765562306a36Sopenharmony_ci PROC(SETCLIENTID, enc_setclientid, dec_setclientid), 765662306a36Sopenharmony_ci PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm), 765762306a36Sopenharmony_ci PROC(LOCK, enc_lock, dec_lock), 765862306a36Sopenharmony_ci PROC(LOCKT, enc_lockt, dec_lockt), 765962306a36Sopenharmony_ci PROC(LOCKU, enc_locku, dec_locku), 766062306a36Sopenharmony_ci PROC(ACCESS, enc_access, dec_access), 766162306a36Sopenharmony_ci PROC(GETATTR, enc_getattr, dec_getattr), 766262306a36Sopenharmony_ci PROC(LOOKUP, enc_lookup, dec_lookup), 766362306a36Sopenharmony_ci PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), 766462306a36Sopenharmony_ci PROC(REMOVE, enc_remove, dec_remove), 766562306a36Sopenharmony_ci PROC(RENAME, enc_rename, dec_rename), 766662306a36Sopenharmony_ci PROC(LINK, enc_link, dec_link), 766762306a36Sopenharmony_ci PROC(SYMLINK, enc_symlink, dec_symlink), 766862306a36Sopenharmony_ci PROC(CREATE, enc_create, dec_create), 766962306a36Sopenharmony_ci PROC(PATHCONF, enc_pathconf, dec_pathconf), 767062306a36Sopenharmony_ci PROC(STATFS, enc_statfs, dec_statfs), 767162306a36Sopenharmony_ci PROC(READLINK, enc_readlink, dec_readlink), 767262306a36Sopenharmony_ci PROC(READDIR, enc_readdir, dec_readdir), 767362306a36Sopenharmony_ci PROC(SERVER_CAPS, enc_server_caps, dec_server_caps), 767462306a36Sopenharmony_ci PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn), 767562306a36Sopenharmony_ci PROC(GETACL, enc_getacl, dec_getacl), 767662306a36Sopenharmony_ci PROC(SETACL, enc_setacl, dec_setacl), 767762306a36Sopenharmony_ci PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), 767862306a36Sopenharmony_ci PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner), 767962306a36Sopenharmony_ci PROC(SECINFO, enc_secinfo, dec_secinfo), 768062306a36Sopenharmony_ci PROC(FSID_PRESENT, enc_fsid_present, dec_fsid_present), 768162306a36Sopenharmony_ci PROC41(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), 768262306a36Sopenharmony_ci PROC41(CREATE_SESSION, enc_create_session, dec_create_session), 768362306a36Sopenharmony_ci PROC41(DESTROY_SESSION, enc_destroy_session, dec_destroy_session), 768462306a36Sopenharmony_ci PROC41(SEQUENCE, enc_sequence, dec_sequence), 768562306a36Sopenharmony_ci PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time), 768662306a36Sopenharmony_ci PROC41(RECLAIM_COMPLETE,enc_reclaim_complete, dec_reclaim_complete), 768762306a36Sopenharmony_ci PROC41(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), 768862306a36Sopenharmony_ci PROC41(LAYOUTGET, enc_layoutget, dec_layoutget), 768962306a36Sopenharmony_ci PROC41(LAYOUTCOMMIT, enc_layoutcommit, dec_layoutcommit), 769062306a36Sopenharmony_ci PROC41(LAYOUTRETURN, enc_layoutreturn, dec_layoutreturn), 769162306a36Sopenharmony_ci PROC41(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), 769262306a36Sopenharmony_ci PROC41(TEST_STATEID, enc_test_stateid, dec_test_stateid), 769362306a36Sopenharmony_ci PROC41(FREE_STATEID, enc_free_stateid, dec_free_stateid), 769462306a36Sopenharmony_ci STUB(GETDEVICELIST), 769562306a36Sopenharmony_ci PROC41(BIND_CONN_TO_SESSION, 769662306a36Sopenharmony_ci enc_bind_conn_to_session, dec_bind_conn_to_session), 769762306a36Sopenharmony_ci PROC41(DESTROY_CLIENTID,enc_destroy_clientid, dec_destroy_clientid), 769862306a36Sopenharmony_ci PROC42(SEEK, enc_seek, dec_seek), 769962306a36Sopenharmony_ci PROC42(ALLOCATE, enc_allocate, dec_allocate), 770062306a36Sopenharmony_ci PROC42(DEALLOCATE, enc_deallocate, dec_deallocate), 770162306a36Sopenharmony_ci PROC42(LAYOUTSTATS, enc_layoutstats, dec_layoutstats), 770262306a36Sopenharmony_ci PROC42(CLONE, enc_clone, dec_clone), 770362306a36Sopenharmony_ci PROC42(COPY, enc_copy, dec_copy), 770462306a36Sopenharmony_ci PROC42(OFFLOAD_CANCEL, enc_offload_cancel, dec_offload_cancel), 770562306a36Sopenharmony_ci PROC42(COPY_NOTIFY, enc_copy_notify, dec_copy_notify), 770662306a36Sopenharmony_ci PROC(LOOKUPP, enc_lookupp, dec_lookupp), 770762306a36Sopenharmony_ci PROC42(LAYOUTERROR, enc_layouterror, dec_layouterror), 770862306a36Sopenharmony_ci PROC42(GETXATTR, enc_getxattr, dec_getxattr), 770962306a36Sopenharmony_ci PROC42(SETXATTR, enc_setxattr, dec_setxattr), 771062306a36Sopenharmony_ci PROC42(LISTXATTRS, enc_listxattrs, dec_listxattrs), 771162306a36Sopenharmony_ci PROC42(REMOVEXATTR, enc_removexattr, dec_removexattr), 771262306a36Sopenharmony_ci PROC42(READ_PLUS, enc_read_plus, dec_read_plus), 771362306a36Sopenharmony_ci}; 771462306a36Sopenharmony_ci 771562306a36Sopenharmony_cistatic unsigned int nfs_version4_counts[ARRAY_SIZE(nfs4_procedures)]; 771662306a36Sopenharmony_ciconst struct rpc_version nfs_version4 = { 771762306a36Sopenharmony_ci .number = 4, 771862306a36Sopenharmony_ci .nrprocs = ARRAY_SIZE(nfs4_procedures), 771962306a36Sopenharmony_ci .procs = nfs4_procedures, 772062306a36Sopenharmony_ci .counts = nfs_version4_counts, 772162306a36Sopenharmony_ci}; 7722