cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nfs42xdr.c (41883B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
      4 */
      5#ifndef __LINUX_FS_NFS_NFS4_2XDR_H
      6#define __LINUX_FS_NFS_NFS4_2XDR_H
      7
      8#include "nfs42.h"
      9
     10#define encode_fallocate_maxsz		(encode_stateid_maxsz + \
     11					 2 /* offset */ + \
     12					 2 /* length */)
     13#define NFS42_WRITE_RES_SIZE		(1 /* wr_callback_id size */ +\
     14					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
     15					 2 /* wr_count */ + \
     16					 1 /* wr_committed */ + \
     17					 XDR_QUADLEN(NFS4_VERIFIER_SIZE))
     18#define encode_allocate_maxsz		(op_encode_hdr_maxsz + \
     19					 encode_fallocate_maxsz)
     20#define decode_allocate_maxsz		(op_decode_hdr_maxsz)
     21#define encode_copy_maxsz		(op_encode_hdr_maxsz +          \
     22					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
     23					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
     24					 2 + 2 + 2 + 1 + 1 + 1 +\
     25					 1 + /* One cnr_source_server */\
     26					 1 + /* nl4_type */ \
     27					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
     28#define decode_copy_maxsz		(op_decode_hdr_maxsz + \
     29					 NFS42_WRITE_RES_SIZE + \
     30					 1 /* cr_consecutive */ + \
     31					 1 /* cr_synchronous */)
     32#define encode_offload_cancel_maxsz	(op_encode_hdr_maxsz + \
     33					 XDR_QUADLEN(NFS4_STATEID_SIZE))
     34#define decode_offload_cancel_maxsz	(op_decode_hdr_maxsz)
     35#define encode_copy_notify_maxsz	(op_encode_hdr_maxsz + \
     36					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
     37					 1 + /* nl4_type */ \
     38					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
     39#define decode_copy_notify_maxsz	(op_decode_hdr_maxsz + \
     40					 3 + /* cnr_lease_time */\
     41					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
     42					 1 + /* Support 1 cnr_source_server */\
     43					 1 + /* nl4_type */ \
     44					 1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
     45#define encode_deallocate_maxsz		(op_encode_hdr_maxsz + \
     46					 encode_fallocate_maxsz)
     47#define decode_deallocate_maxsz		(op_decode_hdr_maxsz)
     48#define encode_read_plus_maxsz		(op_encode_hdr_maxsz + \
     49					 encode_stateid_maxsz + 3)
     50#define NFS42_READ_PLUS_SEGMENT_SIZE	(1 /* data_content4 */ + \
     51					 2 /* data_info4.di_offset */ + \
     52					 2 /* data_info4.di_length */)
     53#define decode_read_plus_maxsz		(op_decode_hdr_maxsz + \
     54					 1 /* rpr_eof */ + \
     55					 1 /* rpr_contents count */ + \
     56					 2 * NFS42_READ_PLUS_SEGMENT_SIZE)
     57#define encode_seek_maxsz		(op_encode_hdr_maxsz + \
     58					 encode_stateid_maxsz + \
     59					 2 /* offset */ + \
     60					 1 /* whence */)
     61#define decode_seek_maxsz		(op_decode_hdr_maxsz + \
     62					 1 /* eof */ + \
     63					 1 /* whence */ + \
     64					 2 /* offset */ + \
     65					 2 /* length */)
     66#define encode_io_info_maxsz		4
     67#define encode_layoutstats_maxsz	(op_decode_hdr_maxsz + \
     68					2 /* offset */ + \
     69					2 /* length */ + \
     70					encode_stateid_maxsz + \
     71					encode_io_info_maxsz + \
     72					encode_io_info_maxsz + \
     73					1 /* opaque devaddr4 length */ + \
     74					XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
     75#define decode_layoutstats_maxsz	(op_decode_hdr_maxsz)
     76#define encode_device_error_maxsz	(XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \
     77					1 /* status */ + 1 /* opnum */)
     78#define encode_layouterror_maxsz	(op_decode_hdr_maxsz + \
     79					2 /* offset */ + \
     80					2 /* length */ + \
     81					encode_stateid_maxsz + \
     82					1 /* Array size */ + \
     83					encode_device_error_maxsz)
     84#define decode_layouterror_maxsz	(op_decode_hdr_maxsz)
     85#define encode_clone_maxsz		(encode_stateid_maxsz + \
     86					encode_stateid_maxsz + \
     87					2 /* src offset */ + \
     88					2 /* dst offset */ + \
     89					2 /* count */)
     90#define decode_clone_maxsz		(op_decode_hdr_maxsz)
     91
     92#define NFS4_enc_allocate_sz		(compound_encode_hdr_maxsz + \
     93					 encode_sequence_maxsz + \
     94					 encode_putfh_maxsz + \
     95					 encode_allocate_maxsz + \
     96					 encode_getattr_maxsz)
     97#define NFS4_dec_allocate_sz		(compound_decode_hdr_maxsz + \
     98					 decode_sequence_maxsz + \
     99					 decode_putfh_maxsz + \
    100					 decode_allocate_maxsz + \
    101					 decode_getattr_maxsz)
    102#define NFS4_enc_copy_sz		(compound_encode_hdr_maxsz + \
    103					 encode_sequence_maxsz + \
    104					 encode_putfh_maxsz + \
    105					 encode_savefh_maxsz + \
    106					 encode_putfh_maxsz + \
    107					 encode_copy_maxsz + \
    108					 encode_commit_maxsz)
    109#define NFS4_dec_copy_sz		(compound_decode_hdr_maxsz + \
    110					 decode_sequence_maxsz + \
    111					 decode_putfh_maxsz + \
    112					 decode_savefh_maxsz + \
    113					 decode_putfh_maxsz + \
    114					 decode_copy_maxsz + \
    115					 decode_commit_maxsz)
    116#define NFS4_enc_offload_cancel_sz	(compound_encode_hdr_maxsz + \
    117					 encode_sequence_maxsz + \
    118					 encode_putfh_maxsz + \
    119					 encode_offload_cancel_maxsz)
    120#define NFS4_dec_offload_cancel_sz	(compound_decode_hdr_maxsz + \
    121					 decode_sequence_maxsz + \
    122					 decode_putfh_maxsz + \
    123					 decode_offload_cancel_maxsz)
    124#define NFS4_enc_copy_notify_sz		(compound_encode_hdr_maxsz + \
    125					 encode_putfh_maxsz + \
    126					 encode_copy_notify_maxsz)
    127#define NFS4_dec_copy_notify_sz		(compound_decode_hdr_maxsz + \
    128					 decode_putfh_maxsz + \
    129					 decode_copy_notify_maxsz)
    130#define NFS4_enc_deallocate_sz		(compound_encode_hdr_maxsz + \
    131					 encode_sequence_maxsz + \
    132					 encode_putfh_maxsz + \
    133					 encode_deallocate_maxsz + \
    134					 encode_getattr_maxsz)
    135#define NFS4_dec_deallocate_sz		(compound_decode_hdr_maxsz + \
    136					 decode_sequence_maxsz + \
    137					 decode_putfh_maxsz + \
    138					 decode_deallocate_maxsz + \
    139					 decode_getattr_maxsz)
    140#define NFS4_enc_read_plus_sz		(compound_encode_hdr_maxsz + \
    141					 encode_sequence_maxsz + \
    142					 encode_putfh_maxsz + \
    143					 encode_read_plus_maxsz)
    144#define NFS4_dec_read_plus_sz		(compound_decode_hdr_maxsz + \
    145					 decode_sequence_maxsz + \
    146					 decode_putfh_maxsz + \
    147					 decode_read_plus_maxsz)
    148#define NFS4_enc_seek_sz		(compound_encode_hdr_maxsz + \
    149					 encode_sequence_maxsz + \
    150					 encode_putfh_maxsz + \
    151					 encode_seek_maxsz)
    152#define NFS4_dec_seek_sz		(compound_decode_hdr_maxsz + \
    153					 decode_sequence_maxsz + \
    154					 decode_putfh_maxsz + \
    155					 decode_seek_maxsz)
    156#define NFS4_enc_layoutstats_sz		(compound_encode_hdr_maxsz + \
    157					 encode_sequence_maxsz + \
    158					 encode_putfh_maxsz + \
    159					 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
    160#define NFS4_dec_layoutstats_sz		(compound_decode_hdr_maxsz + \
    161					 decode_sequence_maxsz + \
    162					 decode_putfh_maxsz + \
    163					 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
    164#define NFS4_enc_layouterror_sz		(compound_encode_hdr_maxsz + \
    165					 encode_sequence_maxsz + \
    166					 encode_putfh_maxsz + \
    167					 NFS42_LAYOUTERROR_MAX * \
    168					 encode_layouterror_maxsz)
    169#define NFS4_dec_layouterror_sz		(compound_decode_hdr_maxsz + \
    170					 decode_sequence_maxsz + \
    171					 decode_putfh_maxsz + \
    172					 NFS42_LAYOUTERROR_MAX * \
    173					 decode_layouterror_maxsz)
    174#define NFS4_enc_clone_sz		(compound_encode_hdr_maxsz + \
    175					 encode_sequence_maxsz + \
    176					 encode_putfh_maxsz + \
    177					 encode_savefh_maxsz + \
    178					 encode_putfh_maxsz + \
    179					 encode_clone_maxsz + \
    180					 encode_getattr_maxsz)
    181#define NFS4_dec_clone_sz		(compound_decode_hdr_maxsz + \
    182					 decode_sequence_maxsz + \
    183					 decode_putfh_maxsz + \
    184					 decode_savefh_maxsz + \
    185					 decode_putfh_maxsz + \
    186					 decode_clone_maxsz + \
    187					 decode_getattr_maxsz)
    188
    189/* Not limited by NFS itself, limited by the generic xattr code */
    190#define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
    191
    192#define encode_getxattr_maxsz   (op_encode_hdr_maxsz + 1 + \
    193				 nfs4_xattr_name_maxsz)
    194#define decode_getxattr_maxsz   (op_decode_hdr_maxsz + 1 + pagepad_maxsz)
    195#define encode_setxattr_maxsz   (op_encode_hdr_maxsz + \
    196				 1 + nfs4_xattr_name_maxsz + 1)
    197#define decode_setxattr_maxsz   (op_decode_hdr_maxsz + decode_change_info_maxsz)
    198#define encode_listxattrs_maxsz  (op_encode_hdr_maxsz + 2 + 1)
    199#define decode_listxattrs_maxsz  (op_decode_hdr_maxsz + 2 + 1 + 1 + 1)
    200#define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \
    201				  nfs4_xattr_name_maxsz)
    202#define decode_removexattr_maxsz (op_decode_hdr_maxsz + \
    203				  decode_change_info_maxsz)
    204
    205#define NFS4_enc_getxattr_sz	(compound_encode_hdr_maxsz + \
    206				encode_sequence_maxsz + \
    207				encode_putfh_maxsz + \
    208				encode_getxattr_maxsz)
    209#define NFS4_dec_getxattr_sz	(compound_decode_hdr_maxsz + \
    210				decode_sequence_maxsz + \
    211				decode_putfh_maxsz + \
    212				decode_getxattr_maxsz)
    213#define NFS4_enc_setxattr_sz	(compound_encode_hdr_maxsz + \
    214				encode_sequence_maxsz + \
    215				encode_putfh_maxsz + \
    216				encode_setxattr_maxsz)
    217#define NFS4_dec_setxattr_sz	(compound_decode_hdr_maxsz + \
    218				decode_sequence_maxsz + \
    219				decode_putfh_maxsz + \
    220				decode_setxattr_maxsz)
    221#define NFS4_enc_listxattrs_sz	(compound_encode_hdr_maxsz + \
    222				encode_sequence_maxsz + \
    223				encode_putfh_maxsz + \
    224				encode_listxattrs_maxsz)
    225#define NFS4_dec_listxattrs_sz	(compound_decode_hdr_maxsz + \
    226				decode_sequence_maxsz + \
    227				decode_putfh_maxsz + \
    228				decode_listxattrs_maxsz)
    229#define NFS4_enc_removexattr_sz	(compound_encode_hdr_maxsz + \
    230				encode_sequence_maxsz + \
    231				encode_putfh_maxsz + \
    232				encode_removexattr_maxsz)
    233#define NFS4_dec_removexattr_sz	(compound_decode_hdr_maxsz + \
    234				decode_sequence_maxsz + \
    235				decode_putfh_maxsz + \
    236				decode_removexattr_maxsz)
    237
    238/*
    239 * These values specify the maximum amount of data that is not
    240 * associated with the extended attribute name or extended
    241 * attribute list in the SETXATTR, GETXATTR and LISTXATTR
    242 * respectively.
    243 */
    244const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
    245					compound_encode_hdr_maxsz +
    246					encode_sequence_maxsz +
    247					encode_putfh_maxsz + 1 +
    248					nfs4_xattr_name_maxsz)
    249					* XDR_UNIT);
    250
    251const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
    252					compound_decode_hdr_maxsz +
    253					decode_sequence_maxsz +
    254					decode_putfh_maxsz + 1) * XDR_UNIT);
    255
    256const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
    257					compound_decode_hdr_maxsz +
    258					decode_sequence_maxsz +
    259					decode_putfh_maxsz + 3) * XDR_UNIT);
    260
    261static void encode_fallocate(struct xdr_stream *xdr,
    262			     const struct nfs42_falloc_args *args)
    263{
    264	encode_nfs4_stateid(xdr, &args->falloc_stateid);
    265	encode_uint64(xdr, args->falloc_offset);
    266	encode_uint64(xdr, args->falloc_length);
    267}
    268
    269static void encode_allocate(struct xdr_stream *xdr,
    270			    const struct nfs42_falloc_args *args,
    271			    struct compound_hdr *hdr)
    272{
    273	encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
    274	encode_fallocate(xdr, args);
    275}
    276
    277static void encode_nl4_server(struct xdr_stream *xdr,
    278			      const struct nl4_server *ns)
    279{
    280	encode_uint32(xdr, ns->nl4_type);
    281	switch (ns->nl4_type) {
    282	case NL4_NAME:
    283	case NL4_URL:
    284		encode_string(xdr, ns->u.nl4_str_sz, ns->u.nl4_str);
    285		break;
    286	case NL4_NETADDR:
    287		encode_string(xdr, ns->u.nl4_addr.netid_len,
    288			      ns->u.nl4_addr.netid);
    289		encode_string(xdr, ns->u.nl4_addr.addr_len,
    290			      ns->u.nl4_addr.addr);
    291		break;
    292	default:
    293		WARN_ON_ONCE(1);
    294	}
    295}
    296
    297static void encode_copy(struct xdr_stream *xdr,
    298			const struct nfs42_copy_args *args,
    299			struct compound_hdr *hdr)
    300{
    301	encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
    302	encode_nfs4_stateid(xdr, &args->src_stateid);
    303	encode_nfs4_stateid(xdr, &args->dst_stateid);
    304
    305	encode_uint64(xdr, args->src_pos);
    306	encode_uint64(xdr, args->dst_pos);
    307	encode_uint64(xdr, args->count);
    308
    309	encode_uint32(xdr, 1); /* consecutive = true */
    310	encode_uint32(xdr, args->sync);
    311	if (args->cp_src == NULL) { /* intra-ssc */
    312		encode_uint32(xdr, 0); /* no src server list */
    313		return;
    314	}
    315	encode_uint32(xdr, 1); /* supporting 1 server */
    316	encode_nl4_server(xdr, args->cp_src);
    317}
    318
    319static void encode_offload_cancel(struct xdr_stream *xdr,
    320				  const struct nfs42_offload_status_args *args,
    321				  struct compound_hdr *hdr)
    322{
    323	encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
    324	encode_nfs4_stateid(xdr, &args->osa_stateid);
    325}
    326
    327static void encode_copy_notify(struct xdr_stream *xdr,
    328			       const struct nfs42_copy_notify_args *args,
    329			       struct compound_hdr *hdr)
    330{
    331	encode_op_hdr(xdr, OP_COPY_NOTIFY, decode_copy_notify_maxsz, hdr);
    332	encode_nfs4_stateid(xdr, &args->cna_src_stateid);
    333	encode_nl4_server(xdr, &args->cna_dst);
    334}
    335
    336static void encode_deallocate(struct xdr_stream *xdr,
    337			      const struct nfs42_falloc_args *args,
    338			      struct compound_hdr *hdr)
    339{
    340	encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
    341	encode_fallocate(xdr, args);
    342}
    343
    344static void encode_read_plus(struct xdr_stream *xdr,
    345			     const struct nfs_pgio_args *args,
    346			     struct compound_hdr *hdr)
    347{
    348	encode_op_hdr(xdr, OP_READ_PLUS, decode_read_plus_maxsz, hdr);
    349	encode_nfs4_stateid(xdr, &args->stateid);
    350	encode_uint64(xdr, args->offset);
    351	encode_uint32(xdr, args->count);
    352}
    353
    354static void encode_seek(struct xdr_stream *xdr,
    355			const struct nfs42_seek_args *args,
    356			struct compound_hdr *hdr)
    357{
    358	encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
    359	encode_nfs4_stateid(xdr, &args->sa_stateid);
    360	encode_uint64(xdr, args->sa_offset);
    361	encode_uint32(xdr, args->sa_what);
    362}
    363
    364static void encode_layoutstats(struct xdr_stream *xdr,
    365			       const struct nfs42_layoutstat_args *args,
    366			       struct nfs42_layoutstat_devinfo *devinfo,
    367			       struct compound_hdr *hdr)
    368{
    369	__be32 *p;
    370
    371	encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
    372	p = reserve_space(xdr, 8 + 8);
    373	p = xdr_encode_hyper(p, devinfo->offset);
    374	p = xdr_encode_hyper(p, devinfo->length);
    375	encode_nfs4_stateid(xdr, &args->stateid);
    376	p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
    377	p = xdr_encode_hyper(p, devinfo->read_count);
    378	p = xdr_encode_hyper(p, devinfo->read_bytes);
    379	p = xdr_encode_hyper(p, devinfo->write_count);
    380	p = xdr_encode_hyper(p, devinfo->write_bytes);
    381	p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
    382			NFS4_DEVICEID4_SIZE);
    383	/* Encode layoutupdate4 */
    384	*p++ = cpu_to_be32(devinfo->layout_type);
    385	if (devinfo->ld_private.ops)
    386		devinfo->ld_private.ops->encode(xdr, args,
    387				&devinfo->ld_private);
    388	else
    389		encode_uint32(xdr, 0);
    390}
    391
    392static void encode_clone(struct xdr_stream *xdr,
    393			 const struct nfs42_clone_args *args,
    394			 struct compound_hdr *hdr)
    395{
    396	__be32 *p;
    397
    398	encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
    399	encode_nfs4_stateid(xdr, &args->src_stateid);
    400	encode_nfs4_stateid(xdr, &args->dst_stateid);
    401	p = reserve_space(xdr, 3*8);
    402	p = xdr_encode_hyper(p, args->src_offset);
    403	p = xdr_encode_hyper(p, args->dst_offset);
    404	xdr_encode_hyper(p, args->count);
    405}
    406
    407static void encode_device_error(struct xdr_stream *xdr,
    408				const struct nfs42_device_error *error)
    409{
    410	__be32 *p;
    411
    412	p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 2*4);
    413	p = xdr_encode_opaque_fixed(p, error->dev_id.data,
    414			NFS4_DEVICEID4_SIZE);
    415	*p++ = cpu_to_be32(error->status);
    416	*p = cpu_to_be32(error->opnum);
    417}
    418
    419static void encode_layouterror(struct xdr_stream *xdr,
    420			       const struct nfs42_layout_error *args,
    421			       struct compound_hdr *hdr)
    422{
    423	__be32 *p;
    424
    425	encode_op_hdr(xdr, OP_LAYOUTERROR, decode_layouterror_maxsz, hdr);
    426	p = reserve_space(xdr, 8 + 8);
    427	p = xdr_encode_hyper(p, args->offset);
    428	p = xdr_encode_hyper(p, args->length);
    429	encode_nfs4_stateid(xdr, &args->stateid);
    430	p = reserve_space(xdr, 4);
    431	*p = cpu_to_be32(1);
    432	encode_device_error(xdr, &args->errors[0]);
    433}
    434
    435static void encode_setxattr(struct xdr_stream *xdr,
    436			    const struct nfs42_setxattrargs *arg,
    437			    struct compound_hdr *hdr)
    438{
    439	__be32 *p;
    440
    441	BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
    442	BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
    443
    444	encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
    445	p = reserve_space(xdr, 4);
    446	*p = cpu_to_be32(arg->xattr_flags);
    447	encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
    448	p = reserve_space(xdr, 4);
    449	*p = cpu_to_be32(arg->xattr_len);
    450	if (arg->xattr_len)
    451		xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
    452}
    453
    454static int decode_setxattr(struct xdr_stream *xdr,
    455			   struct nfs4_change_info *cinfo)
    456{
    457	int status;
    458
    459	status = decode_op_hdr(xdr, OP_SETXATTR);
    460	if (status)
    461		goto out;
    462	status = decode_change_info(xdr, cinfo);
    463out:
    464	return status;
    465}
    466
    467
    468static void encode_getxattr(struct xdr_stream *xdr, const char *name,
    469			    struct compound_hdr *hdr)
    470{
    471	encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
    472	encode_string(xdr, strlen(name), name);
    473}
    474
    475static int decode_getxattr(struct xdr_stream *xdr,
    476			   struct nfs42_getxattrres *res,
    477			   struct rpc_rqst *req)
    478{
    479	int status;
    480	__be32 *p;
    481	u32 len, rdlen;
    482
    483	status = decode_op_hdr(xdr, OP_GETXATTR);
    484	if (status)
    485		return status;
    486
    487	p = xdr_inline_decode(xdr, 4);
    488	if (unlikely(!p))
    489		return -EIO;
    490
    491	len = be32_to_cpup(p);
    492
    493	/*
    494	 * Only check against the page length here. The actual
    495	 * requested length may be smaller, but that is only
    496	 * checked against after possibly caching a valid reply.
    497	 */
    498	if (len > req->rq_rcv_buf.page_len)
    499		return -ERANGE;
    500
    501	res->xattr_len = len;
    502
    503	if (len > 0) {
    504		rdlen = xdr_read_pages(xdr, len);
    505		if (rdlen < len)
    506			return -EIO;
    507	}
    508
    509	return 0;
    510}
    511
    512static void encode_removexattr(struct xdr_stream *xdr, const char *name,
    513			       struct compound_hdr *hdr)
    514{
    515	encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
    516	encode_string(xdr, strlen(name), name);
    517}
    518
    519
    520static int decode_removexattr(struct xdr_stream *xdr,
    521			   struct nfs4_change_info *cinfo)
    522{
    523	int status;
    524
    525	status = decode_op_hdr(xdr, OP_REMOVEXATTR);
    526	if (status)
    527		goto out;
    528
    529	status = decode_change_info(xdr, cinfo);
    530out:
    531	return status;
    532}
    533
    534static void encode_listxattrs(struct xdr_stream *xdr,
    535			     const struct nfs42_listxattrsargs *arg,
    536			     struct compound_hdr *hdr)
    537{
    538	__be32 *p;
    539
    540	encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz, hdr);
    541
    542	p = reserve_space(xdr, 12);
    543	if (unlikely(!p))
    544		return;
    545
    546	p = xdr_encode_hyper(p, arg->cookie);
    547	/*
    548	 * RFC 8276 says to specify the full max length of the LISTXATTRS
    549	 * XDR reply. Count is set to the XDR length of the names array
    550	 * plus the EOF marker. So, add the cookie and the names count.
    551	 */
    552	*p = cpu_to_be32(arg->count + 8 + 4);
    553}
    554
    555static int decode_listxattrs(struct xdr_stream *xdr,
    556			    struct nfs42_listxattrsres *res)
    557{
    558	int status;
    559	__be32 *p;
    560	u32 count, len, ulen;
    561	size_t left, copied;
    562	char *buf;
    563
    564	status = decode_op_hdr(xdr, OP_LISTXATTRS);
    565	if (status) {
    566		/*
    567		 * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
    568		 * should be translated to ERANGE.
    569		 */
    570		if (status == -ETOOSMALL)
    571			status = -ERANGE;
    572		goto out;
    573	}
    574
    575	p = xdr_inline_decode(xdr, 8);
    576	if (unlikely(!p))
    577		return -EIO;
    578
    579	xdr_decode_hyper(p, &res->cookie);
    580
    581	p = xdr_inline_decode(xdr, 4);
    582	if (unlikely(!p))
    583		return -EIO;
    584
    585	left = res->xattr_len;
    586	buf = res->xattr_buf;
    587
    588	count = be32_to_cpup(p);
    589	copied = 0;
    590
    591	/*
    592	 * We have asked for enough room to encode the maximum number
    593	 * of possible attribute names, so everything should fit.
    594	 *
    595	 * But, don't rely on that assumption. Just decode entries
    596	 * until they don't fit anymore, just in case the server did
    597	 * something odd.
    598	 */
    599	while (count--) {
    600		p = xdr_inline_decode(xdr, 4);
    601		if (unlikely(!p))
    602			return -EIO;
    603
    604		len = be32_to_cpup(p);
    605		if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
    606			status = -ERANGE;
    607			goto out;
    608		}
    609
    610		p = xdr_inline_decode(xdr, len);
    611		if (unlikely(!p))
    612			return -EIO;
    613
    614		ulen = len + XATTR_USER_PREFIX_LEN + 1;
    615		if (buf) {
    616			if (ulen > left) {
    617				status = -ERANGE;
    618				goto out;
    619			}
    620
    621			memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
    622			memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
    623
    624			buf[ulen - 1] = 0;
    625			buf += ulen;
    626			left -= ulen;
    627		}
    628		copied += ulen;
    629	}
    630
    631	p = xdr_inline_decode(xdr, 4);
    632	if (unlikely(!p))
    633		return -EIO;
    634
    635	res->eof = be32_to_cpup(p);
    636	res->copied = copied;
    637
    638out:
    639	if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
    640		status = -E2BIG;
    641
    642	return status;
    643}
    644
    645/*
    646 * Encode ALLOCATE request
    647 */
    648static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
    649				  struct xdr_stream *xdr,
    650				  const void *data)
    651{
    652	const struct nfs42_falloc_args *args = data;
    653	struct compound_hdr hdr = {
    654		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    655	};
    656
    657	encode_compound_hdr(xdr, req, &hdr);
    658	encode_sequence(xdr, &args->seq_args, &hdr);
    659	encode_putfh(xdr, args->falloc_fh, &hdr);
    660	encode_allocate(xdr, args, &hdr);
    661	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
    662	encode_nops(&hdr);
    663}
    664
    665static void encode_copy_commit(struct xdr_stream *xdr,
    666			  const struct nfs42_copy_args *args,
    667			  struct compound_hdr *hdr)
    668{
    669	__be32 *p;
    670
    671	encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
    672	p = reserve_space(xdr, 12);
    673	p = xdr_encode_hyper(p, args->dst_pos);
    674	*p = cpu_to_be32(args->count);
    675}
    676
    677/*
    678 * Encode COPY request
    679 */
    680static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
    681			      struct xdr_stream *xdr,
    682			      const void *data)
    683{
    684	const struct nfs42_copy_args *args = data;
    685	struct compound_hdr hdr = {
    686		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    687	};
    688
    689	encode_compound_hdr(xdr, req, &hdr);
    690	encode_sequence(xdr, &args->seq_args, &hdr);
    691	encode_putfh(xdr, args->src_fh, &hdr);
    692	encode_savefh(xdr, &hdr);
    693	encode_putfh(xdr, args->dst_fh, &hdr);
    694	encode_copy(xdr, args, &hdr);
    695	if (args->sync)
    696		encode_copy_commit(xdr, args, &hdr);
    697	encode_nops(&hdr);
    698}
    699
    700/*
    701 * Encode OFFLOAD_CANEL request
    702 */
    703static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
    704					struct xdr_stream *xdr,
    705					const void *data)
    706{
    707	const struct nfs42_offload_status_args *args = data;
    708	struct compound_hdr hdr = {
    709		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
    710	};
    711
    712	encode_compound_hdr(xdr, req, &hdr);
    713	encode_sequence(xdr, &args->osa_seq_args, &hdr);
    714	encode_putfh(xdr, args->osa_src_fh, &hdr);
    715	encode_offload_cancel(xdr, args, &hdr);
    716	encode_nops(&hdr);
    717}
    718
    719/*
    720 * Encode COPY_NOTIFY request
    721 */
    722static void nfs4_xdr_enc_copy_notify(struct rpc_rqst *req,
    723				     struct xdr_stream *xdr,
    724				     const void *data)
    725{
    726	const struct nfs42_copy_notify_args *args = data;
    727	struct compound_hdr hdr = {
    728		.minorversion = nfs4_xdr_minorversion(&args->cna_seq_args),
    729	};
    730
    731	encode_compound_hdr(xdr, req, &hdr);
    732	encode_sequence(xdr, &args->cna_seq_args, &hdr);
    733	encode_putfh(xdr, args->cna_src_fh, &hdr);
    734	encode_copy_notify(xdr, args, &hdr);
    735	encode_nops(&hdr);
    736}
    737
    738/*
    739 * Encode DEALLOCATE request
    740 */
    741static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
    742				    struct xdr_stream *xdr,
    743				    const void *data)
    744{
    745	const struct nfs42_falloc_args *args = data;
    746	struct compound_hdr hdr = {
    747		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    748	};
    749
    750	encode_compound_hdr(xdr, req, &hdr);
    751	encode_sequence(xdr, &args->seq_args, &hdr);
    752	encode_putfh(xdr, args->falloc_fh, &hdr);
    753	encode_deallocate(xdr, args, &hdr);
    754	encode_getfattr(xdr, args->falloc_bitmask, &hdr);
    755	encode_nops(&hdr);
    756}
    757
    758/*
    759 * Encode READ_PLUS request
    760 */
    761static void nfs4_xdr_enc_read_plus(struct rpc_rqst *req,
    762				   struct xdr_stream *xdr,
    763				   const void *data)
    764{
    765	const struct nfs_pgio_args *args = data;
    766	struct compound_hdr hdr = {
    767		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    768	};
    769
    770	encode_compound_hdr(xdr, req, &hdr);
    771	encode_sequence(xdr, &args->seq_args, &hdr);
    772	encode_putfh(xdr, args->fh, &hdr);
    773	encode_read_plus(xdr, args, &hdr);
    774
    775	rpc_prepare_reply_pages(req, args->pages, args->pgbase,
    776				args->count, hdr.replen);
    777	encode_nops(&hdr);
    778}
    779
    780/*
    781 * Encode SEEK request
    782 */
    783static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
    784			      struct xdr_stream *xdr,
    785			      const void *data)
    786{
    787	const struct nfs42_seek_args *args = data;
    788	struct compound_hdr hdr = {
    789		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    790	};
    791
    792	encode_compound_hdr(xdr, req, &hdr);
    793	encode_sequence(xdr, &args->seq_args, &hdr);
    794	encode_putfh(xdr, args->sa_fh, &hdr);
    795	encode_seek(xdr, args, &hdr);
    796	encode_nops(&hdr);
    797}
    798
    799/*
    800 * Encode LAYOUTSTATS request
    801 */
    802static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
    803				     struct xdr_stream *xdr,
    804				     const void *data)
    805{
    806	const struct nfs42_layoutstat_args *args = data;
    807	int i;
    808
    809	struct compound_hdr hdr = {
    810		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    811	};
    812
    813	encode_compound_hdr(xdr, req, &hdr);
    814	encode_sequence(xdr, &args->seq_args, &hdr);
    815	encode_putfh(xdr, args->fh, &hdr);
    816	WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
    817	for (i = 0; i < args->num_dev; i++)
    818		encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
    819	encode_nops(&hdr);
    820}
    821
    822/*
    823 * Encode CLONE request
    824 */
    825static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
    826			       struct xdr_stream *xdr,
    827			       const void *data)
    828{
    829	const struct nfs42_clone_args *args = data;
    830	struct compound_hdr hdr = {
    831		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    832	};
    833
    834	encode_compound_hdr(xdr, req, &hdr);
    835	encode_sequence(xdr, &args->seq_args, &hdr);
    836	encode_putfh(xdr, args->src_fh, &hdr);
    837	encode_savefh(xdr, &hdr);
    838	encode_putfh(xdr, args->dst_fh, &hdr);
    839	encode_clone(xdr, args, &hdr);
    840	encode_getfattr(xdr, args->dst_bitmask, &hdr);
    841	encode_nops(&hdr);
    842}
    843
    844/*
    845 * Encode LAYOUTERROR request
    846 */
    847static void nfs4_xdr_enc_layouterror(struct rpc_rqst *req,
    848				     struct xdr_stream *xdr,
    849				     const void *data)
    850{
    851	const struct nfs42_layouterror_args *args = data;
    852	struct compound_hdr hdr = {
    853		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
    854	};
    855	int i;
    856
    857	encode_compound_hdr(xdr, req, &hdr);
    858	encode_sequence(xdr, &args->seq_args, &hdr);
    859	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
    860	for (i = 0; i < args->num_errors; i++)
    861		encode_layouterror(xdr, &args->errors[i], &hdr);
    862	encode_nops(&hdr);
    863}
    864
    865static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
    866{
    867	return decode_op_hdr(xdr, OP_ALLOCATE);
    868}
    869
    870static int decode_write_response(struct xdr_stream *xdr,
    871				 struct nfs42_write_res *res)
    872{
    873	__be32 *p;
    874	int status, count;
    875
    876	p = xdr_inline_decode(xdr, 4);
    877	if (unlikely(!p))
    878		return -EIO;
    879	count = be32_to_cpup(p);
    880	if (count > 1)
    881		return -EREMOTEIO;
    882	else if (count == 1) {
    883		status = decode_opaque_fixed(xdr, &res->stateid,
    884				NFS4_STATEID_SIZE);
    885		if (unlikely(status))
    886			return -EIO;
    887	}
    888	p = xdr_inline_decode(xdr, 8 + 4);
    889	if (unlikely(!p))
    890		return -EIO;
    891	p = xdr_decode_hyper(p, &res->count);
    892	res->verifier.committed = be32_to_cpup(p);
    893	return decode_verifier(xdr, &res->verifier.verifier);
    894}
    895
    896static int decode_nl4_server(struct xdr_stream *xdr, struct nl4_server *ns)
    897{
    898	struct nfs42_netaddr *naddr;
    899	uint32_t dummy;
    900	char *dummy_str;
    901	__be32 *p;
    902	int status;
    903
    904	/* nl_type */
    905	p = xdr_inline_decode(xdr, 4);
    906	if (unlikely(!p))
    907		return -EIO;
    908	ns->nl4_type = be32_to_cpup(p);
    909	switch (ns->nl4_type) {
    910	case NL4_NAME:
    911	case NL4_URL:
    912		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
    913		if (unlikely(status))
    914			return status;
    915		if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
    916			return -EIO;
    917		memcpy(&ns->u.nl4_str, dummy_str, dummy);
    918		ns->u.nl4_str_sz = dummy;
    919		break;
    920	case NL4_NETADDR:
    921		naddr = &ns->u.nl4_addr;
    922
    923		/* netid string */
    924		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
    925		if (unlikely(status))
    926			return status;
    927		if (unlikely(dummy > RPCBIND_MAXNETIDLEN))
    928			return -EIO;
    929		naddr->netid_len = dummy;
    930		memcpy(naddr->netid, dummy_str, naddr->netid_len);
    931
    932		/* uaddr string */
    933		status = decode_opaque_inline(xdr, &dummy, &dummy_str);
    934		if (unlikely(status))
    935			return status;
    936		if (unlikely(dummy > RPCBIND_MAXUADDRLEN))
    937			return -EIO;
    938		naddr->addr_len = dummy;
    939		memcpy(naddr->addr, dummy_str, naddr->addr_len);
    940		break;
    941	default:
    942		WARN_ON_ONCE(1);
    943		return -EIO;
    944	}
    945	return 0;
    946}
    947
    948static int decode_copy_requirements(struct xdr_stream *xdr,
    949				    struct nfs42_copy_res *res) {
    950	__be32 *p;
    951
    952	p = xdr_inline_decode(xdr, 4 + 4);
    953	if (unlikely(!p))
    954		return -EIO;
    955
    956	res->consecutive = be32_to_cpup(p++);
    957	res->synchronous = be32_to_cpup(p++);
    958	return 0;
    959}
    960
    961static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
    962{
    963	int status;
    964
    965	status = decode_op_hdr(xdr, OP_COPY);
    966	if (status == NFS4ERR_OFFLOAD_NO_REQS) {
    967		status = decode_copy_requirements(xdr, res);
    968		if (status)
    969			return status;
    970		return NFS4ERR_OFFLOAD_NO_REQS;
    971	} else if (status)
    972		return status;
    973
    974	status = decode_write_response(xdr, &res->write_res);
    975	if (status)
    976		return status;
    977
    978	return decode_copy_requirements(xdr, res);
    979}
    980
    981static int decode_offload_cancel(struct xdr_stream *xdr,
    982				 struct nfs42_offload_status_res *res)
    983{
    984	return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
    985}
    986
    987static int decode_copy_notify(struct xdr_stream *xdr,
    988			      struct nfs42_copy_notify_res *res)
    989{
    990	__be32 *p;
    991	int status, count;
    992
    993	status = decode_op_hdr(xdr, OP_COPY_NOTIFY);
    994	if (status)
    995		return status;
    996	/* cnr_lease_time */
    997	p = xdr_inline_decode(xdr, 12);
    998	if (unlikely(!p))
    999		return -EIO;
   1000	p = xdr_decode_hyper(p, &res->cnr_lease_time.seconds);
   1001	res->cnr_lease_time.nseconds = be32_to_cpup(p);
   1002
   1003	status = decode_opaque_fixed(xdr, &res->cnr_stateid, NFS4_STATEID_SIZE);
   1004	if (unlikely(status))
   1005		return -EIO;
   1006
   1007	/* number of source addresses */
   1008	p = xdr_inline_decode(xdr, 4);
   1009	if (unlikely(!p))
   1010		return -EIO;
   1011
   1012	count = be32_to_cpup(p);
   1013	if (count > 1)
   1014		pr_warn("NFS: %s: nsvr %d > Supported. Use first servers\n",
   1015			 __func__, count);
   1016
   1017	status = decode_nl4_server(xdr, &res->cnr_src);
   1018	if (unlikely(status))
   1019		return -EIO;
   1020	return 0;
   1021}
   1022
   1023static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
   1024{
   1025	return decode_op_hdr(xdr, OP_DEALLOCATE);
   1026}
   1027
   1028static int decode_read_plus_data(struct xdr_stream *xdr,
   1029				 struct nfs_pgio_args *args,
   1030				 struct nfs_pgio_res *res)
   1031{
   1032	uint32_t count, recvd;
   1033	uint64_t offset;
   1034	__be32 *p;
   1035
   1036	p = xdr_inline_decode(xdr, 8 + 4);
   1037	if (!p)
   1038		return 1;
   1039
   1040	p = xdr_decode_hyper(p, &offset);
   1041	count = be32_to_cpup(p);
   1042	recvd = xdr_align_data(xdr, res->count, xdr_align_size(count));
   1043	if (recvd > count)
   1044		recvd = count;
   1045	if (res->count + recvd > args->count) {
   1046		if (args->count > res->count)
   1047			res->count += args->count - res->count;
   1048		return 1;
   1049	}
   1050	res->count += recvd;
   1051	if (count > recvd)
   1052		return 1;
   1053	return 0;
   1054}
   1055
   1056static int decode_read_plus_hole(struct xdr_stream *xdr,
   1057				 struct nfs_pgio_args *args,
   1058				 struct nfs_pgio_res *res, uint32_t *eof)
   1059{
   1060	uint64_t offset, length, recvd;
   1061	__be32 *p;
   1062
   1063	p = xdr_inline_decode(xdr, 8 + 8);
   1064	if (!p)
   1065		return 1;
   1066
   1067	p = xdr_decode_hyper(p, &offset);
   1068	p = xdr_decode_hyper(p, &length);
   1069	if (offset != args->offset + res->count) {
   1070		/* Server returned an out-of-sequence extent */
   1071		if (offset > args->offset + res->count ||
   1072		    offset + length < args->offset + res->count) {
   1073			dprintk("NFS: server returned out of sequence extent: "
   1074				"offset/size = %llu/%llu != expected %llu\n",
   1075				(unsigned long long)offset,
   1076				(unsigned long long)length,
   1077				(unsigned long long)(args->offset +
   1078						     res->count));
   1079			return 1;
   1080		}
   1081		length -= args->offset + res->count - offset;
   1082	}
   1083	if (length + res->count > args->count) {
   1084		*eof = 0;
   1085		if (unlikely(res->count >= args->count))
   1086			return 1;
   1087		length = args->count - res->count;
   1088	}
   1089	recvd = xdr_expand_hole(xdr, res->count, length);
   1090	res->count += recvd;
   1091
   1092	if (recvd < length)
   1093		return 1;
   1094	return 0;
   1095}
   1096
   1097static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
   1098{
   1099	struct nfs_pgio_header *hdr =
   1100		container_of(res, struct nfs_pgio_header, res);
   1101	struct nfs_pgio_args *args = &hdr->args;
   1102	uint32_t eof, segments, type;
   1103	int status, i;
   1104	__be32 *p;
   1105
   1106	status = decode_op_hdr(xdr, OP_READ_PLUS);
   1107	if (status)
   1108		return status;
   1109
   1110	p = xdr_inline_decode(xdr, 4 + 4);
   1111	if (unlikely(!p))
   1112		return -EIO;
   1113
   1114	res->count = 0;
   1115	eof = be32_to_cpup(p++);
   1116	segments = be32_to_cpup(p++);
   1117	if (segments == 0)
   1118		goto out;
   1119
   1120	for (i = 0; i < segments; i++) {
   1121		p = xdr_inline_decode(xdr, 4);
   1122		if (!p)
   1123			goto early_out;
   1124
   1125		type = be32_to_cpup(p++);
   1126		if (type == NFS4_CONTENT_DATA)
   1127			status = decode_read_plus_data(xdr, args, res);
   1128		else if (type == NFS4_CONTENT_HOLE)
   1129			status = decode_read_plus_hole(xdr, args, res, &eof);
   1130		else
   1131			return -EINVAL;
   1132
   1133		if (status < 0)
   1134			return status;
   1135		if (status > 0)
   1136			goto early_out;
   1137	}
   1138
   1139out:
   1140	res->eof = eof;
   1141	return 0;
   1142early_out:
   1143	if (unlikely(!i))
   1144		return -EIO;
   1145	res->eof = 0;
   1146	return 0;
   1147}
   1148
   1149static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
   1150{
   1151	int status;
   1152	__be32 *p;
   1153
   1154	status = decode_op_hdr(xdr, OP_SEEK);
   1155	if (status)
   1156		return status;
   1157
   1158	p = xdr_inline_decode(xdr, 4 + 8);
   1159	if (unlikely(!p))
   1160		return -EIO;
   1161
   1162	res->sr_eof = be32_to_cpup(p++);
   1163	p = xdr_decode_hyper(p, &res->sr_offset);
   1164	return 0;
   1165}
   1166
   1167static int decode_layoutstats(struct xdr_stream *xdr)
   1168{
   1169	return decode_op_hdr(xdr, OP_LAYOUTSTATS);
   1170}
   1171
   1172static int decode_clone(struct xdr_stream *xdr)
   1173{
   1174	return decode_op_hdr(xdr, OP_CLONE);
   1175}
   1176
   1177static int decode_layouterror(struct xdr_stream *xdr)
   1178{
   1179	return decode_op_hdr(xdr, OP_LAYOUTERROR);
   1180}
   1181
   1182/*
   1183 * Decode ALLOCATE request
   1184 */
   1185static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
   1186				 struct xdr_stream *xdr,
   1187				 void *data)
   1188{
   1189	struct nfs42_falloc_res *res = data;
   1190	struct compound_hdr hdr;
   1191	int status;
   1192
   1193	status = decode_compound_hdr(xdr, &hdr);
   1194	if (status)
   1195		goto out;
   1196	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1197	if (status)
   1198		goto out;
   1199	status = decode_putfh(xdr);
   1200	if (status)
   1201		goto out;
   1202	status = decode_allocate(xdr, res);
   1203	if (status)
   1204		goto out;
   1205	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
   1206out:
   1207	return status;
   1208}
   1209
   1210/*
   1211 * Decode COPY response
   1212 */
   1213static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
   1214			     struct xdr_stream *xdr,
   1215			     void *data)
   1216{
   1217	struct nfs42_copy_res *res = data;
   1218	struct compound_hdr hdr;
   1219	int status;
   1220
   1221	status = decode_compound_hdr(xdr, &hdr);
   1222	if (status)
   1223		goto out;
   1224	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1225	if (status)
   1226		goto out;
   1227	status = decode_putfh(xdr);
   1228	if (status)
   1229		goto out;
   1230	status = decode_savefh(xdr);
   1231	if (status)
   1232		goto out;
   1233	status = decode_putfh(xdr);
   1234	if (status)
   1235		goto out;
   1236	status = decode_copy(xdr, res);
   1237	if (status)
   1238		goto out;
   1239	if (res->commit_res.verf)
   1240		status = decode_commit(xdr, &res->commit_res);
   1241out:
   1242	return status;
   1243}
   1244
   1245/*
   1246 * Decode OFFLOAD_CANCEL response
   1247 */
   1248static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
   1249				       struct xdr_stream *xdr,
   1250				       void *data)
   1251{
   1252	struct nfs42_offload_status_res *res = data;
   1253	struct compound_hdr hdr;
   1254	int status;
   1255
   1256	status = decode_compound_hdr(xdr, &hdr);
   1257	if (status)
   1258		goto out;
   1259	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
   1260	if (status)
   1261		goto out;
   1262	status = decode_putfh(xdr);
   1263	if (status)
   1264		goto out;
   1265	status = decode_offload_cancel(xdr, res);
   1266
   1267out:
   1268	return status;
   1269}
   1270
   1271/*
   1272 * Decode COPY_NOTIFY response
   1273 */
   1274static int nfs4_xdr_dec_copy_notify(struct rpc_rqst *rqstp,
   1275				    struct xdr_stream *xdr,
   1276				    void *data)
   1277{
   1278	struct nfs42_copy_notify_res *res = data;
   1279	struct compound_hdr hdr;
   1280	int status;
   1281
   1282	status = decode_compound_hdr(xdr, &hdr);
   1283	if (status)
   1284		goto out;
   1285	status = decode_sequence(xdr, &res->cnr_seq_res, rqstp);
   1286	if (status)
   1287		goto out;
   1288	status = decode_putfh(xdr);
   1289	if (status)
   1290		goto out;
   1291	status = decode_copy_notify(xdr, res);
   1292
   1293out:
   1294	return status;
   1295}
   1296
   1297/*
   1298 * Decode DEALLOCATE request
   1299 */
   1300static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
   1301				   struct xdr_stream *xdr,
   1302				   void *data)
   1303{
   1304	struct nfs42_falloc_res *res = data;
   1305	struct compound_hdr hdr;
   1306	int status;
   1307
   1308	status = decode_compound_hdr(xdr, &hdr);
   1309	if (status)
   1310		goto out;
   1311	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1312	if (status)
   1313		goto out;
   1314	status = decode_putfh(xdr);
   1315	if (status)
   1316		goto out;
   1317	status = decode_deallocate(xdr, res);
   1318	if (status)
   1319		goto out;
   1320	decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
   1321out:
   1322	return status;
   1323}
   1324
   1325/*
   1326 * Decode READ_PLUS request
   1327 */
   1328static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp,
   1329				  struct xdr_stream *xdr,
   1330				  void *data)
   1331{
   1332	struct nfs_pgio_res *res = data;
   1333	struct compound_hdr hdr;
   1334	int status;
   1335
   1336	status = decode_compound_hdr(xdr, &hdr);
   1337	if (status)
   1338		goto out;
   1339	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1340	if (status)
   1341		goto out;
   1342	status = decode_putfh(xdr);
   1343	if (status)
   1344		goto out;
   1345	status = decode_read_plus(xdr, res);
   1346	if (!status)
   1347		status = res->count;
   1348out:
   1349	return status;
   1350}
   1351
   1352/*
   1353 * Decode SEEK request
   1354 */
   1355static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
   1356			     struct xdr_stream *xdr,
   1357			     void *data)
   1358{
   1359	struct nfs42_seek_res *res = data;
   1360	struct compound_hdr hdr;
   1361	int status;
   1362
   1363	status = decode_compound_hdr(xdr, &hdr);
   1364	if (status)
   1365		goto out;
   1366	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1367	if (status)
   1368		goto out;
   1369	status = decode_putfh(xdr);
   1370	if (status)
   1371		goto out;
   1372	status = decode_seek(xdr, res);
   1373out:
   1374	return status;
   1375}
   1376
   1377/*
   1378 * Decode LAYOUTSTATS request
   1379 */
   1380static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
   1381				    struct xdr_stream *xdr,
   1382				    void *data)
   1383{
   1384	struct nfs42_layoutstat_res *res = data;
   1385	struct compound_hdr hdr;
   1386	int status, i;
   1387
   1388	status = decode_compound_hdr(xdr, &hdr);
   1389	if (status)
   1390		goto out;
   1391	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1392	if (status)
   1393		goto out;
   1394	status = decode_putfh(xdr);
   1395	if (status)
   1396		goto out;
   1397	WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
   1398	for (i = 0; i < res->num_dev; i++) {
   1399		status = decode_layoutstats(xdr);
   1400		if (status)
   1401			goto out;
   1402	}
   1403out:
   1404	res->rpc_status = status;
   1405	return status;
   1406}
   1407
   1408/*
   1409 * Decode CLONE request
   1410 */
   1411static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
   1412			      struct xdr_stream *xdr,
   1413			      void *data)
   1414{
   1415	struct nfs42_clone_res *res = data;
   1416	struct compound_hdr hdr;
   1417	int status;
   1418
   1419	status = decode_compound_hdr(xdr, &hdr);
   1420	if (status)
   1421		goto out;
   1422	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1423	if (status)
   1424		goto out;
   1425	status = decode_putfh(xdr);
   1426	if (status)
   1427		goto out;
   1428	status = decode_savefh(xdr);
   1429	if (status)
   1430		goto out;
   1431	status = decode_putfh(xdr);
   1432	if (status)
   1433		goto out;
   1434	status = decode_clone(xdr);
   1435	if (status)
   1436		goto out;
   1437	decode_getfattr(xdr, res->dst_fattr, res->server);
   1438out:
   1439	res->rpc_status = status;
   1440	return status;
   1441}
   1442
   1443/*
   1444 * Decode LAYOUTERROR request
   1445 */
   1446static int nfs4_xdr_dec_layouterror(struct rpc_rqst *rqstp,
   1447				    struct xdr_stream *xdr,
   1448				    void *data)
   1449{
   1450	struct nfs42_layouterror_res *res = data;
   1451	struct compound_hdr hdr;
   1452	int status, i;
   1453
   1454	status = decode_compound_hdr(xdr, &hdr);
   1455	if (status)
   1456		goto out;
   1457	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1458	if (status)
   1459		goto out;
   1460	status = decode_putfh(xdr);
   1461
   1462	for (i = 0; i < res->num_errors && status == 0; i++)
   1463		status = decode_layouterror(xdr);
   1464out:
   1465	res->rpc_status = status;
   1466	return status;
   1467}
   1468
   1469#ifdef CONFIG_NFS_V4_2
   1470static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
   1471				  const void *data)
   1472{
   1473	const struct nfs42_setxattrargs *args = data;
   1474	struct compound_hdr hdr = {
   1475		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
   1476	};
   1477
   1478	encode_compound_hdr(xdr, req, &hdr);
   1479	encode_sequence(xdr, &args->seq_args, &hdr);
   1480	encode_putfh(xdr, args->fh, &hdr);
   1481	encode_setxattr(xdr, args, &hdr);
   1482	encode_nops(&hdr);
   1483}
   1484
   1485static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
   1486				 void *data)
   1487{
   1488	struct nfs42_setxattrres *res = data;
   1489	struct compound_hdr hdr;
   1490	int status;
   1491
   1492	status = decode_compound_hdr(xdr, &hdr);
   1493	if (status)
   1494		goto out;
   1495	status = decode_sequence(xdr, &res->seq_res, req);
   1496	if (status)
   1497		goto out;
   1498	status = decode_putfh(xdr);
   1499	if (status)
   1500		goto out;
   1501
   1502	status = decode_setxattr(xdr, &res->cinfo);
   1503out:
   1504	return status;
   1505}
   1506
   1507static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
   1508				  const void *data)
   1509{
   1510	const struct nfs42_getxattrargs *args = data;
   1511	struct compound_hdr hdr = {
   1512		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
   1513	};
   1514	uint32_t replen;
   1515
   1516	encode_compound_hdr(xdr, req, &hdr);
   1517	encode_sequence(xdr, &args->seq_args, &hdr);
   1518	encode_putfh(xdr, args->fh, &hdr);
   1519	replen = hdr.replen + op_decode_hdr_maxsz + 1;
   1520	encode_getxattr(xdr, args->xattr_name, &hdr);
   1521
   1522	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->xattr_len,
   1523				replen);
   1524
   1525	encode_nops(&hdr);
   1526}
   1527
   1528static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
   1529				 struct xdr_stream *xdr, void *data)
   1530{
   1531	struct nfs42_getxattrres *res = data;
   1532	struct compound_hdr hdr;
   1533	int status;
   1534
   1535	status = decode_compound_hdr(xdr, &hdr);
   1536	if (status)
   1537		goto out;
   1538	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1539	if (status)
   1540		goto out;
   1541	status = decode_putfh(xdr);
   1542	if (status)
   1543		goto out;
   1544	status = decode_getxattr(xdr, res, rqstp);
   1545out:
   1546	return status;
   1547}
   1548
   1549static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
   1550				    struct xdr_stream *xdr, const void *data)
   1551{
   1552	const struct nfs42_listxattrsargs *args = data;
   1553	struct compound_hdr hdr = {
   1554		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
   1555	};
   1556	uint32_t replen;
   1557
   1558	encode_compound_hdr(xdr, req, &hdr);
   1559	encode_sequence(xdr, &args->seq_args, &hdr);
   1560	encode_putfh(xdr, args->fh, &hdr);
   1561	replen = hdr.replen + op_decode_hdr_maxsz + 2 + 1;
   1562	encode_listxattrs(xdr, args, &hdr);
   1563
   1564	rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count, replen);
   1565
   1566	encode_nops(&hdr);
   1567}
   1568
   1569static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
   1570				   struct xdr_stream *xdr, void *data)
   1571{
   1572	struct nfs42_listxattrsres *res = data;
   1573	struct compound_hdr hdr;
   1574	int status;
   1575
   1576	xdr_set_scratch_page(xdr, res->scratch);
   1577
   1578	status = decode_compound_hdr(xdr, &hdr);
   1579	if (status)
   1580		goto out;
   1581	status = decode_sequence(xdr, &res->seq_res, rqstp);
   1582	if (status)
   1583		goto out;
   1584	status = decode_putfh(xdr);
   1585	if (status)
   1586		goto out;
   1587	status = decode_listxattrs(xdr, res);
   1588out:
   1589	return status;
   1590}
   1591
   1592static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
   1593				     struct xdr_stream *xdr, const void *data)
   1594{
   1595	const struct nfs42_removexattrargs *args = data;
   1596	struct compound_hdr hdr = {
   1597		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
   1598	};
   1599
   1600	encode_compound_hdr(xdr, req, &hdr);
   1601	encode_sequence(xdr, &args->seq_args, &hdr);
   1602	encode_putfh(xdr, args->fh, &hdr);
   1603	encode_removexattr(xdr, args->xattr_name, &hdr);
   1604	encode_nops(&hdr);
   1605}
   1606
   1607static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
   1608				    struct xdr_stream *xdr, void *data)
   1609{
   1610	struct nfs42_removexattrres *res = data;
   1611	struct compound_hdr hdr;
   1612	int status;
   1613
   1614	status = decode_compound_hdr(xdr, &hdr);
   1615	if (status)
   1616		goto out;
   1617	status = decode_sequence(xdr, &res->seq_res, req);
   1618	if (status)
   1619		goto out;
   1620	status = decode_putfh(xdr);
   1621	if (status)
   1622		goto out;
   1623
   1624	status = decode_removexattr(xdr, &res->cinfo);
   1625out:
   1626	return status;
   1627}
   1628#endif
   1629#endif /* __LINUX_FS_NFS_NFS4_2XDR_H */