Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

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