Linux Audio

Check our new training course

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