PageRenderTime 143ms CodeModel.GetById 26ms app.highlight 105ms RepoModel.GetById 1ms app.codeStats 1ms

/fs/nfs/nfs3xdr.c

https://bitbucket.org/emiliolopez/linux
C | 2618 lines | 1530 code | 235 blank | 853 comment | 202 complexity | 858eacf5c6f85aa7e6ed249a2a46ccc6 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * linux/fs/nfs/nfs3xdr.c
   3 *
   4 * XDR functions to encode/decode NFSv3 RPC arguments and results.
   5 *
   6 * Copyright (C) 1996, 1997 Olaf Kirch
   7 */
   8
   9#include <linux/param.h>
  10#include <linux/time.h>
  11#include <linux/mm.h>
  12#include <linux/errno.h>
  13#include <linux/string.h>
  14#include <linux/in.h>
  15#include <linux/pagemap.h>
  16#include <linux/proc_fs.h>
  17#include <linux/kdev_t.h>
  18#include <linux/sunrpc/clnt.h>
  19#include <linux/nfs.h>
  20#include <linux/nfs3.h>
  21#include <linux/nfs_fs.h>
  22#include <linux/nfsacl.h>
  23#include "internal.h"
  24
  25#define NFSDBG_FACILITY		NFSDBG_XDR
  26
  27/* Mapping from NFS error code to "errno" error code. */
  28#define errno_NFSERR_IO		EIO
  29
  30/*
  31 * Declare the space requirements for NFS arguments and replies as
  32 * number of 32bit-words
  33 */
  34#define NFS3_fhandle_sz		(1+16)
  35#define NFS3_fh_sz		(NFS3_fhandle_sz)	/* shorthand */
  36#define NFS3_sattr_sz		(15)
  37#define NFS3_filename_sz	(1+(NFS3_MAXNAMLEN>>2))
  38#define NFS3_path_sz		(1+(NFS3_MAXPATHLEN>>2))
  39#define NFS3_fattr_sz		(21)
  40#define NFS3_cookieverf_sz	(NFS3_COOKIEVERFSIZE>>2)
  41#define NFS3_wcc_attr_sz	(6)
  42#define NFS3_pre_op_attr_sz	(1+NFS3_wcc_attr_sz)
  43#define NFS3_post_op_attr_sz	(1+NFS3_fattr_sz)
  44#define NFS3_wcc_data_sz	(NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
  45#define NFS3_diropargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
  46
  47#define NFS3_getattrargs_sz	(NFS3_fh_sz)
  48#define NFS3_setattrargs_sz	(NFS3_fh_sz+NFS3_sattr_sz+3)
  49#define NFS3_lookupargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
  50#define NFS3_accessargs_sz	(NFS3_fh_sz+1)
  51#define NFS3_readlinkargs_sz	(NFS3_fh_sz)
  52#define NFS3_readargs_sz	(NFS3_fh_sz+3)
  53#define NFS3_writeargs_sz	(NFS3_fh_sz+5)
  54#define NFS3_createargs_sz	(NFS3_diropargs_sz+NFS3_sattr_sz)
  55#define NFS3_mkdirargs_sz	(NFS3_diropargs_sz+NFS3_sattr_sz)
  56#define NFS3_symlinkargs_sz	(NFS3_diropargs_sz+1+NFS3_sattr_sz)
  57#define NFS3_mknodargs_sz	(NFS3_diropargs_sz+2+NFS3_sattr_sz)
  58#define NFS3_removeargs_sz	(NFS3_fh_sz+NFS3_filename_sz)
  59#define NFS3_renameargs_sz	(NFS3_diropargs_sz+NFS3_diropargs_sz)
  60#define NFS3_linkargs_sz		(NFS3_fh_sz+NFS3_diropargs_sz)
  61#define NFS3_readdirargs_sz	(NFS3_fh_sz+NFS3_cookieverf_sz+3)
  62#define NFS3_readdirplusargs_sz	(NFS3_fh_sz+NFS3_cookieverf_sz+4)
  63#define NFS3_commitargs_sz	(NFS3_fh_sz+3)
  64
  65#define NFS3_getattrres_sz	(1+NFS3_fattr_sz)
  66#define NFS3_setattrres_sz	(1+NFS3_wcc_data_sz)
  67#define NFS3_removeres_sz	(NFS3_setattrres_sz)
  68#define NFS3_lookupres_sz	(1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
  69#define NFS3_accessres_sz	(1+NFS3_post_op_attr_sz+1)
  70#define NFS3_readlinkres_sz	(1+NFS3_post_op_attr_sz+1)
  71#define NFS3_readres_sz		(1+NFS3_post_op_attr_sz+3)
  72#define NFS3_writeres_sz	(1+NFS3_wcc_data_sz+4)
  73#define NFS3_createres_sz	(1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
  74#define NFS3_renameres_sz	(1+(2 * NFS3_wcc_data_sz))
  75#define NFS3_linkres_sz		(1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
  76#define NFS3_readdirres_sz	(1+NFS3_post_op_attr_sz+2)
  77#define NFS3_fsstatres_sz	(1+NFS3_post_op_attr_sz+13)
  78#define NFS3_fsinfores_sz	(1+NFS3_post_op_attr_sz+12)
  79#define NFS3_pathconfres_sz	(1+NFS3_post_op_attr_sz+6)
  80#define NFS3_commitres_sz	(1+NFS3_wcc_data_sz+2)
  81
  82#define ACL3_getaclargs_sz	(NFS3_fh_sz+1)
  83#define ACL3_setaclargs_sz	(NFS3_fh_sz+1+ \
  84				XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
  85#define ACL3_getaclres_sz	(1+NFS3_post_op_attr_sz+1+ \
  86				XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
  87#define ACL3_setaclres_sz	(1+NFS3_post_op_attr_sz)
  88
  89static int nfs3_stat_to_errno(enum nfs_stat);
  90
  91/*
  92 * Map file type to S_IFMT bits
  93 */
  94static const umode_t nfs_type2fmt[] = {
  95	[NF3BAD] = 0,
  96	[NF3REG] = S_IFREG,
  97	[NF3DIR] = S_IFDIR,
  98	[NF3BLK] = S_IFBLK,
  99	[NF3CHR] = S_IFCHR,
 100	[NF3LNK] = S_IFLNK,
 101	[NF3SOCK] = S_IFSOCK,
 102	[NF3FIFO] = S_IFIFO,
 103};
 104
 105/*
 106 * While encoding arguments, set up the reply buffer in advance to
 107 * receive reply data directly into the page cache.
 108 */
 109static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
 110				 unsigned int base, unsigned int len,
 111				 unsigned int bufsize)
 112{
 113	struct rpc_auth	*auth = req->rq_cred->cr_auth;
 114	unsigned int replen;
 115
 116	replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
 117	xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
 118}
 119
 120/*
 121 * Handle decode buffer overflows out-of-line.
 122 */
 123static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
 124{
 125	dprintk("NFS: %s prematurely hit the end of our receive buffer. "
 126		"Remaining buffer length is %tu words.\n",
 127		func, xdr->end - xdr->p);
 128}
 129
 130
 131/*
 132 * Encode/decode NFSv3 basic data types
 133 *
 134 * Basic NFSv3 data types are defined in section 2.5 of RFC 1813:
 135 * "NFS Version 3 Protocol Specification".
 136 *
 137 * Not all basic data types have their own encoding and decoding
 138 * functions.  For run-time efficiency, some data types are encoded
 139 * or decoded inline.
 140 */
 141
 142static void encode_uint32(struct xdr_stream *xdr, u32 value)
 143{
 144	__be32 *p = xdr_reserve_space(xdr, 4);
 145	*p = cpu_to_be32(value);
 146}
 147
 148static int decode_uint32(struct xdr_stream *xdr, u32 *value)
 149{
 150	__be32 *p;
 151
 152	p = xdr_inline_decode(xdr, 4);
 153	if (unlikely(p == NULL))
 154		goto out_overflow;
 155	*value = be32_to_cpup(p);
 156	return 0;
 157out_overflow:
 158	print_overflow_msg(__func__, xdr);
 159	return -EIO;
 160}
 161
 162static int decode_uint64(struct xdr_stream *xdr, u64 *value)
 163{
 164	__be32 *p;
 165
 166	p = xdr_inline_decode(xdr, 8);
 167	if (unlikely(p == NULL))
 168		goto out_overflow;
 169	xdr_decode_hyper(p, value);
 170	return 0;
 171out_overflow:
 172	print_overflow_msg(__func__, xdr);
 173	return -EIO;
 174}
 175
 176/*
 177 * fileid3
 178 *
 179 *	typedef uint64 fileid3;
 180 */
 181static __be32 *xdr_decode_fileid3(__be32 *p, u64 *fileid)
 182{
 183	return xdr_decode_hyper(p, fileid);
 184}
 185
 186static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid)
 187{
 188	return decode_uint64(xdr, fileid);
 189}
 190
 191/*
 192 * filename3
 193 *
 194 *	typedef string filename3<>;
 195 */
 196static void encode_filename3(struct xdr_stream *xdr,
 197			     const char *name, u32 length)
 198{
 199	__be32 *p;
 200
 201	WARN_ON_ONCE(length > NFS3_MAXNAMLEN);
 202	p = xdr_reserve_space(xdr, 4 + length);
 203	xdr_encode_opaque(p, name, length);
 204}
 205
 206static int decode_inline_filename3(struct xdr_stream *xdr,
 207				   const char **name, u32 *length)
 208{
 209	__be32 *p;
 210	u32 count;
 211
 212	p = xdr_inline_decode(xdr, 4);
 213	if (unlikely(p == NULL))
 214		goto out_overflow;
 215	count = be32_to_cpup(p);
 216	if (count > NFS3_MAXNAMLEN)
 217		goto out_nametoolong;
 218	p = xdr_inline_decode(xdr, count);
 219	if (unlikely(p == NULL))
 220		goto out_overflow;
 221	*name = (const char *)p;
 222	*length = count;
 223	return 0;
 224
 225out_nametoolong:
 226	dprintk("NFS: returned filename too long: %u\n", count);
 227	return -ENAMETOOLONG;
 228out_overflow:
 229	print_overflow_msg(__func__, xdr);
 230	return -EIO;
 231}
 232
 233/*
 234 * nfspath3
 235 *
 236 *	typedef string nfspath3<>;
 237 */
 238static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages,
 239			    const u32 length)
 240{
 241	encode_uint32(xdr, length);
 242	xdr_write_pages(xdr, pages, 0, length);
 243}
 244
 245static int decode_nfspath3(struct xdr_stream *xdr)
 246{
 247	u32 recvd, count;
 248	__be32 *p;
 249
 250	p = xdr_inline_decode(xdr, 4);
 251	if (unlikely(p == NULL))
 252		goto out_overflow;
 253	count = be32_to_cpup(p);
 254	if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN))
 255		goto out_nametoolong;
 256	recvd = xdr_read_pages(xdr, count);
 257	if (unlikely(count > recvd))
 258		goto out_cheating;
 259	xdr_terminate_string(xdr->buf, count);
 260	return 0;
 261
 262out_nametoolong:
 263	dprintk("NFS: returned pathname too long: %u\n", count);
 264	return -ENAMETOOLONG;
 265out_cheating:
 266	dprintk("NFS: server cheating in pathname result: "
 267		"count %u > recvd %u\n", count, recvd);
 268	return -EIO;
 269out_overflow:
 270	print_overflow_msg(__func__, xdr);
 271	return -EIO;
 272}
 273
 274/*
 275 * cookie3
 276 *
 277 *	typedef uint64 cookie3
 278 */
 279static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie)
 280{
 281	return xdr_encode_hyper(p, cookie);
 282}
 283
 284static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie)
 285{
 286	return decode_uint64(xdr, cookie);
 287}
 288
 289/*
 290 * cookieverf3
 291 *
 292 *	typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
 293 */
 294static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier)
 295{
 296	memcpy(p, verifier, NFS3_COOKIEVERFSIZE);
 297	return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE);
 298}
 299
 300static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier)
 301{
 302	__be32 *p;
 303
 304	p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
 305	if (unlikely(p == NULL))
 306		goto out_overflow;
 307	memcpy(verifier, p, NFS3_COOKIEVERFSIZE);
 308	return 0;
 309out_overflow:
 310	print_overflow_msg(__func__, xdr);
 311	return -EIO;
 312}
 313
 314/*
 315 * createverf3
 316 *
 317 *	typedef opaque createverf3[NFS3_CREATEVERFSIZE];
 318 */
 319static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier)
 320{
 321	__be32 *p;
 322
 323	p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE);
 324	memcpy(p, verifier, NFS3_CREATEVERFSIZE);
 325}
 326
 327static int decode_writeverf3(struct xdr_stream *xdr, struct nfs_write_verifier *verifier)
 328{
 329	__be32 *p;
 330
 331	p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE);
 332	if (unlikely(p == NULL))
 333		goto out_overflow;
 334	memcpy(verifier->data, p, NFS3_WRITEVERFSIZE);
 335	return 0;
 336out_overflow:
 337	print_overflow_msg(__func__, xdr);
 338	return -EIO;
 339}
 340
 341/*
 342 * size3
 343 *
 344 *	typedef uint64 size3;
 345 */
 346static __be32 *xdr_decode_size3(__be32 *p, u64 *size)
 347{
 348	return xdr_decode_hyper(p, size);
 349}
 350
 351/*
 352 * nfsstat3
 353 *
 354 *	enum nfsstat3 {
 355 *		NFS3_OK = 0,
 356 *		...
 357 *	}
 358 */
 359#define NFS3_OK		NFS_OK
 360
 361static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status)
 362{
 363	__be32 *p;
 364
 365	p = xdr_inline_decode(xdr, 4);
 366	if (unlikely(p == NULL))
 367		goto out_overflow;
 368	*status = be32_to_cpup(p);
 369	return 0;
 370out_overflow:
 371	print_overflow_msg(__func__, xdr);
 372	return -EIO;
 373}
 374
 375/*
 376 * ftype3
 377 *
 378 *	enum ftype3 {
 379 *		NF3REG	= 1,
 380 *		NF3DIR	= 2,
 381 *		NF3BLK	= 3,
 382 *		NF3CHR	= 4,
 383 *		NF3LNK	= 5,
 384 *		NF3SOCK	= 6,
 385 *		NF3FIFO	= 7
 386 *	};
 387 */
 388static void encode_ftype3(struct xdr_stream *xdr, const u32 type)
 389{
 390	encode_uint32(xdr, type);
 391}
 392
 393static __be32 *xdr_decode_ftype3(__be32 *p, umode_t *mode)
 394{
 395	u32 type;
 396
 397	type = be32_to_cpup(p++);
 398	if (type > NF3FIFO)
 399		type = NF3NON;
 400	*mode = nfs_type2fmt[type];
 401	return p;
 402}
 403
 404/*
 405 * specdata3
 406 *
 407 *     struct specdata3 {
 408 *             uint32  specdata1;
 409 *             uint32  specdata2;
 410 *     };
 411 */
 412static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev)
 413{
 414	__be32 *p;
 415
 416	p = xdr_reserve_space(xdr, 8);
 417	*p++ = cpu_to_be32(MAJOR(rdev));
 418	*p = cpu_to_be32(MINOR(rdev));
 419}
 420
 421static __be32 *xdr_decode_specdata3(__be32 *p, dev_t *rdev)
 422{
 423	unsigned int major, minor;
 424
 425	major = be32_to_cpup(p++);
 426	minor = be32_to_cpup(p++);
 427	*rdev = MKDEV(major, minor);
 428	if (MAJOR(*rdev) != major || MINOR(*rdev) != minor)
 429		*rdev = 0;
 430	return p;
 431}
 432
 433/*
 434 * nfs_fh3
 435 *
 436 *	struct nfs_fh3 {
 437 *		opaque       data<NFS3_FHSIZE>;
 438 *	};
 439 */
 440static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh)
 441{
 442	__be32 *p;
 443
 444	WARN_ON_ONCE(fh->size > NFS3_FHSIZE);
 445	p = xdr_reserve_space(xdr, 4 + fh->size);
 446	xdr_encode_opaque(p, fh->data, fh->size);
 447}
 448
 449static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
 450{
 451	u32 length;
 452	__be32 *p;
 453
 454	p = xdr_inline_decode(xdr, 4);
 455	if (unlikely(p == NULL))
 456		goto out_overflow;
 457	length = be32_to_cpup(p++);
 458	if (unlikely(length > NFS3_FHSIZE))
 459		goto out_toobig;
 460	p = xdr_inline_decode(xdr, length);
 461	if (unlikely(p == NULL))
 462		goto out_overflow;
 463	fh->size = length;
 464	memcpy(fh->data, p, length);
 465	return 0;
 466out_toobig:
 467	dprintk("NFS: file handle size (%u) too big\n", length);
 468	return -E2BIG;
 469out_overflow:
 470	print_overflow_msg(__func__, xdr);
 471	return -EIO;
 472}
 473
 474static void zero_nfs_fh3(struct nfs_fh *fh)
 475{
 476	memset(fh, 0, sizeof(*fh));
 477}
 478
 479/*
 480 * nfstime3
 481 *
 482 *	struct nfstime3 {
 483 *		uint32	seconds;
 484 *		uint32	nseconds;
 485 *	};
 486 */
 487static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep)
 488{
 489	*p++ = cpu_to_be32(timep->tv_sec);
 490	*p++ = cpu_to_be32(timep->tv_nsec);
 491	return p;
 492}
 493
 494static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep)
 495{
 496	timep->tv_sec = be32_to_cpup(p++);
 497	timep->tv_nsec = be32_to_cpup(p++);
 498	return p;
 499}
 500
 501/*
 502 * sattr3
 503 *
 504 *	enum time_how {
 505 *		DONT_CHANGE		= 0,
 506 *		SET_TO_SERVER_TIME	= 1,
 507 *		SET_TO_CLIENT_TIME	= 2
 508 *	};
 509 *
 510 *	union set_mode3 switch (bool set_it) {
 511 *	case TRUE:
 512 *		mode3	mode;
 513 *	default:
 514 *		void;
 515 *	};
 516 *
 517 *	union set_uid3 switch (bool set_it) {
 518 *	case TRUE:
 519 *		uid3	uid;
 520 *	default:
 521 *		void;
 522 *	};
 523 *
 524 *	union set_gid3 switch (bool set_it) {
 525 *	case TRUE:
 526 *		gid3	gid;
 527 *	default:
 528 *		void;
 529 *	};
 530 *
 531 *	union set_size3 switch (bool set_it) {
 532 *	case TRUE:
 533 *		size3	size;
 534 *	default:
 535 *		void;
 536 *	};
 537 *
 538 *	union set_atime switch (time_how set_it) {
 539 *	case SET_TO_CLIENT_TIME:
 540 *		nfstime3	atime;
 541 *	default:
 542 *		void;
 543 *	};
 544 *
 545 *	union set_mtime switch (time_how set_it) {
 546 *	case SET_TO_CLIENT_TIME:
 547 *		nfstime3  mtime;
 548 *	default:
 549 *		void;
 550 *	};
 551 *
 552 *	struct sattr3 {
 553 *		set_mode3	mode;
 554 *		set_uid3	uid;
 555 *		set_gid3	gid;
 556 *		set_size3	size;
 557 *		set_atime	atime;
 558 *		set_mtime	mtime;
 559 *	};
 560 */
 561static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr)
 562{
 563	u32 nbytes;
 564	__be32 *p;
 565
 566	/*
 567	 * In order to make only a single xdr_reserve_space() call,
 568	 * pre-compute the total number of bytes to be reserved.
 569	 * Six boolean values, one for each set_foo field, are always
 570	 * present in the encoded result, so start there.
 571	 */
 572	nbytes = 6 * 4;
 573	if (attr->ia_valid & ATTR_MODE)
 574		nbytes += 4;
 575	if (attr->ia_valid & ATTR_UID)
 576		nbytes += 4;
 577	if (attr->ia_valid & ATTR_GID)
 578		nbytes += 4;
 579	if (attr->ia_valid & ATTR_SIZE)
 580		nbytes += 8;
 581	if (attr->ia_valid & ATTR_ATIME_SET)
 582		nbytes += 8;
 583	if (attr->ia_valid & ATTR_MTIME_SET)
 584		nbytes += 8;
 585	p = xdr_reserve_space(xdr, nbytes);
 586
 587	if (attr->ia_valid & ATTR_MODE) {
 588		*p++ = xdr_one;
 589		*p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO);
 590	} else
 591		*p++ = xdr_zero;
 592
 593	if (attr->ia_valid & ATTR_UID) {
 594		*p++ = xdr_one;
 595		*p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
 596	} else
 597		*p++ = xdr_zero;
 598
 599	if (attr->ia_valid & ATTR_GID) {
 600		*p++ = xdr_one;
 601		*p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
 602	} else
 603		*p++ = xdr_zero;
 604
 605	if (attr->ia_valid & ATTR_SIZE) {
 606		*p++ = xdr_one;
 607		p = xdr_encode_hyper(p, (u64)attr->ia_size);
 608	} else
 609		*p++ = xdr_zero;
 610
 611	if (attr->ia_valid & ATTR_ATIME_SET) {
 612		*p++ = xdr_two;
 613		p = xdr_encode_nfstime3(p, &attr->ia_atime);
 614	} else if (attr->ia_valid & ATTR_ATIME) {
 615		*p++ = xdr_one;
 616	} else
 617		*p++ = xdr_zero;
 618
 619	if (attr->ia_valid & ATTR_MTIME_SET) {
 620		*p++ = xdr_two;
 621		xdr_encode_nfstime3(p, &attr->ia_mtime);
 622	} else if (attr->ia_valid & ATTR_MTIME) {
 623		*p = xdr_one;
 624	} else
 625		*p = xdr_zero;
 626}
 627
 628/*
 629 * fattr3
 630 *
 631 *	struct fattr3 {
 632 *		ftype3		type;
 633 *		mode3		mode;
 634 *		uint32		nlink;
 635 *		uid3		uid;
 636 *		gid3		gid;
 637 *		size3		size;
 638 *		size3		used;
 639 *		specdata3	rdev;
 640 *		uint64		fsid;
 641 *		fileid3		fileid;
 642 *		nfstime3	atime;
 643 *		nfstime3	mtime;
 644 *		nfstime3	ctime;
 645 *	};
 646 */
 647static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 648{
 649	umode_t fmode;
 650	__be32 *p;
 651
 652	p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2);
 653	if (unlikely(p == NULL))
 654		goto out_overflow;
 655
 656	p = xdr_decode_ftype3(p, &fmode);
 657
 658	fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode;
 659	fattr->nlink = be32_to_cpup(p++);
 660	fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++));
 661	if (!uid_valid(fattr->uid))
 662		goto out_uid;
 663	fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++));
 664	if (!gid_valid(fattr->gid))
 665		goto out_gid;
 666
 667	p = xdr_decode_size3(p, &fattr->size);
 668	p = xdr_decode_size3(p, &fattr->du.nfs3.used);
 669	p = xdr_decode_specdata3(p, &fattr->rdev);
 670
 671	p = xdr_decode_hyper(p, &fattr->fsid.major);
 672	fattr->fsid.minor = 0;
 673
 674	p = xdr_decode_fileid3(p, &fattr->fileid);
 675	p = xdr_decode_nfstime3(p, &fattr->atime);
 676	p = xdr_decode_nfstime3(p, &fattr->mtime);
 677	xdr_decode_nfstime3(p, &fattr->ctime);
 678	fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
 679
 680	fattr->valid |= NFS_ATTR_FATTR_V3;
 681	return 0;
 682out_uid:
 683	dprintk("NFS: returned invalid uid\n");
 684	return -EINVAL;
 685out_gid:
 686	dprintk("NFS: returned invalid gid\n");
 687	return -EINVAL;
 688out_overflow:
 689	print_overflow_msg(__func__, xdr);
 690	return -EIO;
 691}
 692
 693/*
 694 * post_op_attr
 695 *
 696 *	union post_op_attr switch (bool attributes_follow) {
 697 *	case TRUE:
 698 *		fattr3	attributes;
 699 *	case FALSE:
 700 *		void;
 701 *	};
 702 */
 703static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 704{
 705	__be32 *p;
 706
 707	p = xdr_inline_decode(xdr, 4);
 708	if (unlikely(p == NULL))
 709		goto out_overflow;
 710	if (*p != xdr_zero)
 711		return decode_fattr3(xdr, fattr);
 712	return 0;
 713out_overflow:
 714	print_overflow_msg(__func__, xdr);
 715	return -EIO;
 716}
 717
 718/*
 719 * wcc_attr
 720 *	struct wcc_attr {
 721 *		size3		size;
 722 *		nfstime3	mtime;
 723 *		nfstime3	ctime;
 724 *	};
 725 */
 726static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 727{
 728	__be32 *p;
 729
 730	p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2);
 731	if (unlikely(p == NULL))
 732		goto out_overflow;
 733
 734	fattr->valid |= NFS_ATTR_FATTR_PRESIZE
 735		| NFS_ATTR_FATTR_PRECHANGE
 736		| NFS_ATTR_FATTR_PREMTIME
 737		| NFS_ATTR_FATTR_PRECTIME;
 738
 739	p = xdr_decode_size3(p, &fattr->pre_size);
 740	p = xdr_decode_nfstime3(p, &fattr->pre_mtime);
 741	xdr_decode_nfstime3(p, &fattr->pre_ctime);
 742	fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime);
 743
 744	return 0;
 745out_overflow:
 746	print_overflow_msg(__func__, xdr);
 747	return -EIO;
 748}
 749
 750/*
 751 * pre_op_attr
 752 *	union pre_op_attr switch (bool attributes_follow) {
 753 *	case TRUE:
 754 *		wcc_attr	attributes;
 755 *	case FALSE:
 756 *		void;
 757 *	};
 758 *
 759 * wcc_data
 760 *
 761 *	struct wcc_data {
 762 *		pre_op_attr	before;
 763 *		post_op_attr	after;
 764 *	};
 765 */
 766static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 767{
 768	__be32 *p;
 769
 770	p = xdr_inline_decode(xdr, 4);
 771	if (unlikely(p == NULL))
 772		goto out_overflow;
 773	if (*p != xdr_zero)
 774		return decode_wcc_attr(xdr, fattr);
 775	return 0;
 776out_overflow:
 777	print_overflow_msg(__func__, xdr);
 778	return -EIO;
 779}
 780
 781static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 782{
 783	int error;
 784
 785	error = decode_pre_op_attr(xdr, fattr);
 786	if (unlikely(error))
 787		goto out;
 788	error = decode_post_op_attr(xdr, fattr);
 789out:
 790	return error;
 791}
 792
 793/*
 794 * post_op_fh3
 795 *
 796 *	union post_op_fh3 switch (bool handle_follows) {
 797 *	case TRUE:
 798 *		nfs_fh3  handle;
 799 *	case FALSE:
 800 *		void;
 801 *	};
 802 */
 803static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh)
 804{
 805	__be32 *p = xdr_inline_decode(xdr, 4);
 806	if (unlikely(p == NULL))
 807		goto out_overflow;
 808	if (*p != xdr_zero)
 809		return decode_nfs_fh3(xdr, fh);
 810	zero_nfs_fh3(fh);
 811	return 0;
 812out_overflow:
 813	print_overflow_msg(__func__, xdr);
 814	return -EIO;
 815}
 816
 817/*
 818 * diropargs3
 819 *
 820 *	struct diropargs3 {
 821 *		nfs_fh3		dir;
 822 *		filename3	name;
 823 *	};
 824 */
 825static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh,
 826			      const char *name, u32 length)
 827{
 828	encode_nfs_fh3(xdr, fh);
 829	encode_filename3(xdr, name, length);
 830}
 831
 832
 833/*
 834 * NFSv3 XDR encode functions
 835 *
 836 * NFSv3 argument types are defined in section 3.3 of RFC 1813:
 837 * "NFS Version 3 Protocol Specification".
 838 */
 839
 840/*
 841 * 3.3.1  GETATTR3args
 842 *
 843 *	struct GETATTR3args {
 844 *		nfs_fh3  object;
 845 *	};
 846 */
 847static void nfs3_xdr_enc_getattr3args(struct rpc_rqst *req,
 848				      struct xdr_stream *xdr,
 849				      const void *data)
 850{
 851	const struct nfs_fh *fh = data;
 852
 853	encode_nfs_fh3(xdr, fh);
 854}
 855
 856/*
 857 * 3.3.2  SETATTR3args
 858 *
 859 *	union sattrguard3 switch (bool check) {
 860 *	case TRUE:
 861 *		nfstime3  obj_ctime;
 862 *	case FALSE:
 863 *		void;
 864 *	};
 865 *
 866 *	struct SETATTR3args {
 867 *		nfs_fh3		object;
 868 *		sattr3		new_attributes;
 869 *		sattrguard3	guard;
 870 *	};
 871 */
 872static void encode_sattrguard3(struct xdr_stream *xdr,
 873			       const struct nfs3_sattrargs *args)
 874{
 875	__be32 *p;
 876
 877	if (args->guard) {
 878		p = xdr_reserve_space(xdr, 4 + 8);
 879		*p++ = xdr_one;
 880		xdr_encode_nfstime3(p, &args->guardtime);
 881	} else {
 882		p = xdr_reserve_space(xdr, 4);
 883		*p = xdr_zero;
 884	}
 885}
 886
 887static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req,
 888				      struct xdr_stream *xdr,
 889				      const void *data)
 890{
 891	const struct nfs3_sattrargs *args = data;
 892	encode_nfs_fh3(xdr, args->fh);
 893	encode_sattr3(xdr, args->sattr);
 894	encode_sattrguard3(xdr, args);
 895}
 896
 897/*
 898 * 3.3.3  LOOKUP3args
 899 *
 900 *	struct LOOKUP3args {
 901 *		diropargs3  what;
 902 *	};
 903 */
 904static void nfs3_xdr_enc_lookup3args(struct rpc_rqst *req,
 905				     struct xdr_stream *xdr,
 906				     const void *data)
 907{
 908	const struct nfs3_diropargs *args = data;
 909
 910	encode_diropargs3(xdr, args->fh, args->name, args->len);
 911}
 912
 913/*
 914 * 3.3.4  ACCESS3args
 915 *
 916 *	struct ACCESS3args {
 917 *		nfs_fh3		object;
 918 *		uint32		access;
 919 *	};
 920 */
 921static void encode_access3args(struct xdr_stream *xdr,
 922			       const struct nfs3_accessargs *args)
 923{
 924	encode_nfs_fh3(xdr, args->fh);
 925	encode_uint32(xdr, args->access);
 926}
 927
 928static void nfs3_xdr_enc_access3args(struct rpc_rqst *req,
 929				     struct xdr_stream *xdr,
 930				     const void *data)
 931{
 932	const struct nfs3_accessargs *args = data;
 933
 934	encode_access3args(xdr, args);
 935}
 936
 937/*
 938 * 3.3.5  READLINK3args
 939 *
 940 *	struct READLINK3args {
 941 *		nfs_fh3	symlink;
 942 *	};
 943 */
 944static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req,
 945				       struct xdr_stream *xdr,
 946				       const void *data)
 947{
 948	const struct nfs3_readlinkargs *args = data;
 949
 950	encode_nfs_fh3(xdr, args->fh);
 951	prepare_reply_buffer(req, args->pages, args->pgbase,
 952					args->pglen, NFS3_readlinkres_sz);
 953}
 954
 955/*
 956 * 3.3.6  READ3args
 957 *
 958 *	struct READ3args {
 959 *		nfs_fh3		file;
 960 *		offset3		offset;
 961 *		count3		count;
 962 *	};
 963 */
 964static void encode_read3args(struct xdr_stream *xdr,
 965			     const struct nfs_pgio_args *args)
 966{
 967	__be32 *p;
 968
 969	encode_nfs_fh3(xdr, args->fh);
 970
 971	p = xdr_reserve_space(xdr, 8 + 4);
 972	p = xdr_encode_hyper(p, args->offset);
 973	*p = cpu_to_be32(args->count);
 974}
 975
 976static void nfs3_xdr_enc_read3args(struct rpc_rqst *req,
 977				   struct xdr_stream *xdr,
 978				   const void *data)
 979{
 980	const struct nfs_pgio_args *args = data;
 981
 982	encode_read3args(xdr, args);
 983	prepare_reply_buffer(req, args->pages, args->pgbase,
 984					args->count, NFS3_readres_sz);
 985	req->rq_rcv_buf.flags |= XDRBUF_READ;
 986}
 987
 988/*
 989 * 3.3.7  WRITE3args
 990 *
 991 *	enum stable_how {
 992 *		UNSTABLE  = 0,
 993 *		DATA_SYNC = 1,
 994 *		FILE_SYNC = 2
 995 *	};
 996 *
 997 *	struct WRITE3args {
 998 *		nfs_fh3		file;
 999 *		offset3		offset;
1000 *		count3		count;
1001 *		stable_how	stable;
1002 *		opaque		data<>;
1003 *	};
1004 */
1005static void encode_write3args(struct xdr_stream *xdr,
1006			      const struct nfs_pgio_args *args)
1007{
1008	__be32 *p;
1009
1010	encode_nfs_fh3(xdr, args->fh);
1011
1012	p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4);
1013	p = xdr_encode_hyper(p, args->offset);
1014	*p++ = cpu_to_be32(args->count);
1015	*p++ = cpu_to_be32(args->stable);
1016	*p = cpu_to_be32(args->count);
1017	xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1018}
1019
1020static void nfs3_xdr_enc_write3args(struct rpc_rqst *req,
1021				    struct xdr_stream *xdr,
1022				    const void *data)
1023{
1024	const struct nfs_pgio_args *args = data;
1025
1026	encode_write3args(xdr, args);
1027	xdr->buf->flags |= XDRBUF_WRITE;
1028}
1029
1030/*
1031 * 3.3.8  CREATE3args
1032 *
1033 *	enum createmode3 {
1034 *		UNCHECKED = 0,
1035 *		GUARDED   = 1,
1036 *		EXCLUSIVE = 2
1037 *	};
1038 *
1039 *	union createhow3 switch (createmode3 mode) {
1040 *	case UNCHECKED:
1041 *	case GUARDED:
1042 *		sattr3       obj_attributes;
1043 *	case EXCLUSIVE:
1044 *		createverf3  verf;
1045 *	};
1046 *
1047 *	struct CREATE3args {
1048 *		diropargs3	where;
1049 *		createhow3	how;
1050 *	};
1051 */
1052static void encode_createhow3(struct xdr_stream *xdr,
1053			      const struct nfs3_createargs *args)
1054{
1055	encode_uint32(xdr, args->createmode);
1056	switch (args->createmode) {
1057	case NFS3_CREATE_UNCHECKED:
1058	case NFS3_CREATE_GUARDED:
1059		encode_sattr3(xdr, args->sattr);
1060		break;
1061	case NFS3_CREATE_EXCLUSIVE:
1062		encode_createverf3(xdr, args->verifier);
1063		break;
1064	default:
1065		BUG();
1066	}
1067}
1068
1069static void nfs3_xdr_enc_create3args(struct rpc_rqst *req,
1070				     struct xdr_stream *xdr,
1071				     const void *data)
1072{
1073	const struct nfs3_createargs *args = data;
1074
1075	encode_diropargs3(xdr, args->fh, args->name, args->len);
1076	encode_createhow3(xdr, args);
1077}
1078
1079/*
1080 * 3.3.9  MKDIR3args
1081 *
1082 *	struct MKDIR3args {
1083 *		diropargs3	where;
1084 *		sattr3		attributes;
1085 *	};
1086 */
1087static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req,
1088				    struct xdr_stream *xdr,
1089				    const void *data)
1090{
1091	const struct nfs3_mkdirargs *args = data;
1092
1093	encode_diropargs3(xdr, args->fh, args->name, args->len);
1094	encode_sattr3(xdr, args->sattr);
1095}
1096
1097/*
1098 * 3.3.10  SYMLINK3args
1099 *
1100 *	struct symlinkdata3 {
1101 *		sattr3		symlink_attributes;
1102 *		nfspath3	symlink_data;
1103 *	};
1104 *
1105 *	struct SYMLINK3args {
1106 *		diropargs3	where;
1107 *		symlinkdata3	symlink;
1108 *	};
1109 */
1110static void encode_symlinkdata3(struct xdr_stream *xdr,
1111				const void *data)
1112{
1113	const struct nfs3_symlinkargs *args = data;
1114
1115	encode_sattr3(xdr, args->sattr);
1116	encode_nfspath3(xdr, args->pages, args->pathlen);
1117}
1118
1119static void nfs3_xdr_enc_symlink3args(struct rpc_rqst *req,
1120				      struct xdr_stream *xdr,
1121				      const void *data)
1122{
1123	const struct nfs3_symlinkargs *args = data;
1124
1125	encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen);
1126	encode_symlinkdata3(xdr, args);
1127	xdr->buf->flags |= XDRBUF_WRITE;
1128}
1129
1130/*
1131 * 3.3.11  MKNOD3args
1132 *
1133 *	struct devicedata3 {
1134 *		sattr3		dev_attributes;
1135 *		specdata3	spec;
1136 *	};
1137 *
1138 *	union mknoddata3 switch (ftype3 type) {
1139 *	case NF3CHR:
1140 *	case NF3BLK:
1141 *		devicedata3	device;
1142 *	case NF3SOCK:
1143 *	case NF3FIFO:
1144 *		sattr3		pipe_attributes;
1145 *	default:
1146 *		void;
1147 *	};
1148 *
1149 *	struct MKNOD3args {
1150 *		diropargs3	where;
1151 *		mknoddata3	what;
1152 *	};
1153 */
1154static void encode_devicedata3(struct xdr_stream *xdr,
1155			       const struct nfs3_mknodargs *args)
1156{
1157	encode_sattr3(xdr, args->sattr);
1158	encode_specdata3(xdr, args->rdev);
1159}
1160
1161static void encode_mknoddata3(struct xdr_stream *xdr,
1162			      const struct nfs3_mknodargs *args)
1163{
1164	encode_ftype3(xdr, args->type);
1165	switch (args->type) {
1166	case NF3CHR:
1167	case NF3BLK:
1168		encode_devicedata3(xdr, args);
1169		break;
1170	case NF3SOCK:
1171	case NF3FIFO:
1172		encode_sattr3(xdr, args->sattr);
1173		break;
1174	case NF3REG:
1175	case NF3DIR:
1176		break;
1177	default:
1178		BUG();
1179	}
1180}
1181
1182static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req,
1183				    struct xdr_stream *xdr,
1184				    const void *data)
1185{
1186	const struct nfs3_mknodargs *args = data;
1187
1188	encode_diropargs3(xdr, args->fh, args->name, args->len);
1189	encode_mknoddata3(xdr, args);
1190}
1191
1192/*
1193 * 3.3.12  REMOVE3args
1194 *
1195 *	struct REMOVE3args {
1196 *		diropargs3  object;
1197 *	};
1198 */
1199static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req,
1200				     struct xdr_stream *xdr,
1201				     const void *data)
1202{
1203	const struct nfs_removeargs *args = data;
1204
1205	encode_diropargs3(xdr, args->fh, args->name.name, args->name.len);
1206}
1207
1208/*
1209 * 3.3.14  RENAME3args
1210 *
1211 *	struct RENAME3args {
1212 *		diropargs3	from;
1213 *		diropargs3	to;
1214 *	};
1215 */
1216static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req,
1217				     struct xdr_stream *xdr,
1218				     const void *data)
1219{
1220	const struct nfs_renameargs *args = data;
1221	const struct qstr *old = args->old_name;
1222	const struct qstr *new = args->new_name;
1223
1224	encode_diropargs3(xdr, args->old_dir, old->name, old->len);
1225	encode_diropargs3(xdr, args->new_dir, new->name, new->len);
1226}
1227
1228/*
1229 * 3.3.15  LINK3args
1230 *
1231 *	struct LINK3args {
1232 *		nfs_fh3		file;
1233 *		diropargs3	link;
1234 *	};
1235 */
1236static void nfs3_xdr_enc_link3args(struct rpc_rqst *req,
1237				   struct xdr_stream *xdr,
1238				   const void *data)
1239{
1240	const struct nfs3_linkargs *args = data;
1241
1242	encode_nfs_fh3(xdr, args->fromfh);
1243	encode_diropargs3(xdr, args->tofh, args->toname, args->tolen);
1244}
1245
1246/*
1247 * 3.3.16  READDIR3args
1248 *
1249 *	struct READDIR3args {
1250 *		nfs_fh3		dir;
1251 *		cookie3		cookie;
1252 *		cookieverf3	cookieverf;
1253 *		count3		count;
1254 *	};
1255 */
1256static void encode_readdir3args(struct xdr_stream *xdr,
1257				const struct nfs3_readdirargs *args)
1258{
1259	__be32 *p;
1260
1261	encode_nfs_fh3(xdr, args->fh);
1262
1263	p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4);
1264	p = xdr_encode_cookie3(p, args->cookie);
1265	p = xdr_encode_cookieverf3(p, args->verf);
1266	*p = cpu_to_be32(args->count);
1267}
1268
1269static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req,
1270				      struct xdr_stream *xdr,
1271				      const void *data)
1272{
1273	const struct nfs3_readdirargs *args = data;
1274
1275	encode_readdir3args(xdr, args);
1276	prepare_reply_buffer(req, args->pages, 0,
1277				args->count, NFS3_readdirres_sz);
1278}
1279
1280/*
1281 * 3.3.17  READDIRPLUS3args
1282 *
1283 *	struct READDIRPLUS3args {
1284 *		nfs_fh3		dir;
1285 *		cookie3		cookie;
1286 *		cookieverf3	cookieverf;
1287 *		count3		dircount;
1288 *		count3		maxcount;
1289 *	};
1290 */
1291static void encode_readdirplus3args(struct xdr_stream *xdr,
1292				    const struct nfs3_readdirargs *args)
1293{
1294	__be32 *p;
1295
1296	encode_nfs_fh3(xdr, args->fh);
1297
1298	p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4);
1299	p = xdr_encode_cookie3(p, args->cookie);
1300	p = xdr_encode_cookieverf3(p, args->verf);
1301
1302	/*
1303	 * readdirplus: need dircount + buffer size.
1304	 * We just make sure we make dircount big enough
1305	 */
1306	*p++ = cpu_to_be32(args->count >> 3);
1307
1308	*p = cpu_to_be32(args->count);
1309}
1310
1311static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req,
1312					  struct xdr_stream *xdr,
1313					  const void *data)
1314{
1315	const struct nfs3_readdirargs *args = data;
1316
1317	encode_readdirplus3args(xdr, args);
1318	prepare_reply_buffer(req, args->pages, 0,
1319				args->count, NFS3_readdirres_sz);
1320}
1321
1322/*
1323 * 3.3.21  COMMIT3args
1324 *
1325 *	struct COMMIT3args {
1326 *		nfs_fh3		file;
1327 *		offset3		offset;
1328 *		count3		count;
1329 *	};
1330 */
1331static void encode_commit3args(struct xdr_stream *xdr,
1332			       const struct nfs_commitargs *args)
1333{
1334	__be32 *p;
1335
1336	encode_nfs_fh3(xdr, args->fh);
1337
1338	p = xdr_reserve_space(xdr, 8 + 4);
1339	p = xdr_encode_hyper(p, args->offset);
1340	*p = cpu_to_be32(args->count);
1341}
1342
1343static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req,
1344				     struct xdr_stream *xdr,
1345				     const void *data)
1346{
1347	const struct nfs_commitargs *args = data;
1348
1349	encode_commit3args(xdr, args);
1350}
1351
1352#ifdef CONFIG_NFS_V3_ACL
1353
1354static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req,
1355				     struct xdr_stream *xdr,
1356				     const void *data)
1357{
1358	const struct nfs3_getaclargs *args = data;
1359
1360	encode_nfs_fh3(xdr, args->fh);
1361	encode_uint32(xdr, args->mask);
1362	if (args->mask & (NFS_ACL | NFS_DFACL))
1363		prepare_reply_buffer(req, args->pages, 0,
1364					NFSACL_MAXPAGES << PAGE_SHIFT,
1365					ACL3_getaclres_sz);
1366}
1367
1368static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
1369				     struct xdr_stream *xdr,
1370				     const void *data)
1371{
1372	const struct nfs3_setaclargs *args = data;
1373	unsigned int base;
1374	int error;
1375
1376	encode_nfs_fh3(xdr, NFS_FH(args->inode));
1377	encode_uint32(xdr, args->mask);
1378
1379	base = req->rq_slen;
1380	if (args->npages != 0)
1381		xdr_write_pages(xdr, args->pages, 0, args->len);
1382	else
1383		xdr_reserve_space(xdr, args->len);
1384
1385	error = nfsacl_encode(xdr->buf, base, args->inode,
1386			    (args->mask & NFS_ACL) ?
1387			    args->acl_access : NULL, 1, 0);
1388	/* FIXME: this is just broken */
1389	BUG_ON(error < 0);
1390	error = nfsacl_encode(xdr->buf, base + error, args->inode,
1391			    (args->mask & NFS_DFACL) ?
1392			    args->acl_default : NULL, 1,
1393			    NFS_ACL_DEFAULT);
1394	BUG_ON(error < 0);
1395}
1396
1397#endif  /* CONFIG_NFS_V3_ACL */
1398
1399/*
1400 * NFSv3 XDR decode functions
1401 *
1402 * NFSv3 result types are defined in section 3.3 of RFC 1813:
1403 * "NFS Version 3 Protocol Specification".
1404 */
1405
1406/*
1407 * 3.3.1  GETATTR3res
1408 *
1409 *	struct GETATTR3resok {
1410 *		fattr3		obj_attributes;
1411 *	};
1412 *
1413 *	union GETATTR3res switch (nfsstat3 status) {
1414 *	case NFS3_OK:
1415 *		GETATTR3resok  resok;
1416 *	default:
1417 *		void;
1418 *	};
1419 */
1420static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
1421				    struct xdr_stream *xdr,
1422				    void *result)
1423{
1424	enum nfs_stat status;
1425	int error;
1426
1427	error = decode_nfsstat3(xdr, &status);
1428	if (unlikely(error))
1429		goto out;
1430	if (status != NFS3_OK)
1431		goto out_default;
1432	error = decode_fattr3(xdr, result);
1433out:
1434	return error;
1435out_default:
1436	return nfs3_stat_to_errno(status);
1437}
1438
1439/*
1440 * 3.3.2  SETATTR3res
1441 *
1442 *	struct SETATTR3resok {
1443 *		wcc_data  obj_wcc;
1444 *	};
1445 *
1446 *	struct SETATTR3resfail {
1447 *		wcc_data  obj_wcc;
1448 *	};
1449 *
1450 *	union SETATTR3res switch (nfsstat3 status) {
1451 *	case NFS3_OK:
1452 *		SETATTR3resok   resok;
1453 *	default:
1454 *		SETATTR3resfail resfail;
1455 *	};
1456 */
1457static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
1458				    struct xdr_stream *xdr,
1459				    void *result)
1460{
1461	enum nfs_stat status;
1462	int error;
1463
1464	error = decode_nfsstat3(xdr, &status);
1465	if (unlikely(error))
1466		goto out;
1467	error = decode_wcc_data(xdr, result);
1468	if (unlikely(error))
1469		goto out;
1470	if (status != NFS3_OK)
1471		goto out_status;
1472out:
1473	return error;
1474out_status:
1475	return nfs3_stat_to_errno(status);
1476}
1477
1478/*
1479 * 3.3.3  LOOKUP3res
1480 *
1481 *	struct LOOKUP3resok {
1482 *		nfs_fh3		object;
1483 *		post_op_attr	obj_attributes;
1484 *		post_op_attr	dir_attributes;
1485 *	};
1486 *
1487 *	struct LOOKUP3resfail {
1488 *		post_op_attr	dir_attributes;
1489 *	};
1490 *
1491 *	union LOOKUP3res switch (nfsstat3 status) {
1492 *	case NFS3_OK:
1493 *		LOOKUP3resok	resok;
1494 *	default:
1495 *		LOOKUP3resfail	resfail;
1496 *	};
1497 */
1498static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req,
1499				   struct xdr_stream *xdr,
1500				   void *data)
1501{
1502	struct nfs3_diropres *result = data;
1503	enum nfs_stat status;
1504	int error;
1505
1506	error = decode_nfsstat3(xdr, &status);
1507	if (unlikely(error))
1508		goto out;
1509	if (status != NFS3_OK)
1510		goto out_default;
1511	error = decode_nfs_fh3(xdr, result->fh);
1512	if (unlikely(error))
1513		goto out;
1514	error = decode_post_op_attr(xdr, result->fattr);
1515	if (unlikely(error))
1516		goto out;
1517	error = decode_post_op_attr(xdr, result->dir_attr);
1518out:
1519	return error;
1520out_default:
1521	error = decode_post_op_attr(xdr, result->dir_attr);
1522	if (unlikely(error))
1523		goto out;
1524	return nfs3_stat_to_errno(status);
1525}
1526
1527/*
1528 * 3.3.4  ACCESS3res
1529 *
1530 *	struct ACCESS3resok {
1531 *		post_op_attr	obj_attributes;
1532 *		uint32		access;
1533 *	};
1534 *
1535 *	struct ACCESS3resfail {
1536 *		post_op_attr	obj_attributes;
1537 *	};
1538 *
1539 *	union ACCESS3res switch (nfsstat3 status) {
1540 *	case NFS3_OK:
1541 *		ACCESS3resok	resok;
1542 *	default:
1543 *		ACCESS3resfail	resfail;
1544 *	};
1545 */
1546static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
1547				   struct xdr_stream *xdr,
1548				   void *data)
1549{
1550	struct nfs3_accessres *result = data;
1551	enum nfs_stat status;
1552	int error;
1553
1554	error = decode_nfsstat3(xdr, &status);
1555	if (unlikely(error))
1556		goto out;
1557	error = decode_post_op_attr(xdr, result->fattr);
1558	if (unlikely(error))
1559		goto out;
1560	if (status != NFS3_OK)
1561		goto out_default;
1562	error = decode_uint32(xdr, &result->access);
1563out:
1564	return error;
1565out_default:
1566	return nfs3_stat_to_errno(status);
1567}
1568
1569/*
1570 * 3.3.5  READLINK3res
1571 *
1572 *	struct READLINK3resok {
1573 *		post_op_attr	symlink_attributes;
1574 *		nfspath3	data;
1575 *	};
1576 *
1577 *	struct READLINK3resfail {
1578 *		post_op_attr	symlink_attributes;
1579 *	};
1580 *
1581 *	union READLINK3res switch (nfsstat3 status) {
1582 *	case NFS3_OK:
1583 *		READLINK3resok	resok;
1584 *	default:
1585 *		READLINK3resfail resfail;
1586 *	};
1587 */
1588static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
1589				     struct xdr_stream *xdr,
1590				     void *result)
1591{
1592	enum nfs_stat status;
1593	int error;
1594
1595	error = decode_nfsstat3(xdr, &status);
1596	if (unlikely(error))
1597		goto out;
1598	error = decode_post_op_attr(xdr, result);
1599	if (unlikely(error))
1600		goto out;
1601	if (status != NFS3_OK)
1602		goto out_default;
1603	error = decode_nfspath3(xdr);
1604out:
1605	return error;
1606out_default:
1607	return nfs3_stat_to_errno(status);
1608}
1609
1610/*
1611 * 3.3.6  READ3res
1612 *
1613 *	struct READ3resok {
1614 *		post_op_attr	file_attributes;
1615 *		count3		count;
1616 *		bool		eof;
1617 *		opaque		data<>;
1618 *	};
1619 *
1620 *	struct READ3resfail {
1621 *		post_op_attr	file_attributes;
1622 *	};
1623 *
1624 *	union READ3res switch (nfsstat3 status) {
1625 *	case NFS3_OK:
1626 *		READ3resok	resok;
1627 *	default:
1628 *		READ3resfail	resfail;
1629 *	};
1630 */
1631static int decode_read3resok(struct xdr_stream *xdr,
1632			     struct nfs_pgio_res *result)
1633{
1634	u32 eof, count, ocount, recvd;
1635	__be32 *p;
1636
1637	p = xdr_inline_decode(xdr, 4 + 4 + 4);
1638	if (unlikely(p == NULL))
1639		goto out_overflow;
1640	count = be32_to_cpup(p++);
1641	eof = be32_to_cpup(p++);
1642	ocount = be32_to_cpup(p++);
1643	if (unlikely(ocount != count))
1644		goto out_mismatch;
1645	recvd = xdr_read_pages(xdr, count);
1646	if (unlikely(count > recvd))
1647		goto out_cheating;
1648out:
1649	result->eof = eof;
1650	result->count = count;
1651	return count;
1652out_mismatch:
1653	dprintk("NFS: READ count doesn't match length of opaque: "
1654		"count %u != ocount %u\n", count, ocount);
1655	return -EIO;
1656out_cheating:
1657	dprintk("NFS: server cheating in read result: "
1658		"count %u > recvd %u\n", count, recvd);
1659	count = recvd;
1660	eof = 0;
1661	goto out;
1662out_overflow:
1663	print_overflow_msg(__func__, xdr);
1664	return -EIO;
1665}
1666
1667static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1668				 void *data)
1669{
1670	struct nfs_pgio_res *result = data;
1671	enum nfs_stat status;
1672	int error;
1673
1674	error = decode_nfsstat3(xdr, &status);
1675	if (unlikely(error))
1676		goto out;
1677	error = decode_post_op_attr(xdr, result->fattr);
1678	if (unlikely(error))
1679		goto out;
1680	result->op_status = status;
1681	if (status != NFS3_OK)
1682		goto out_status;
1683	error = decode_read3resok(xdr, result);
1684out:
1685	return error;
1686out_status:
1687	return nfs3_stat_to_errno(status);
1688}
1689
1690/*
1691 * 3.3.7  WRITE3res
1692 *
1693 *	enum stable_how {
1694 *		UNSTABLE  = 0,
1695 *		DATA_SYNC = 1,
1696 *		FILE_SYNC = 2
1697 *	};
1698 *
1699 *	struct WRITE3resok {
1700 *		wcc_data	file_wcc;
1701 *		count3		count;
1702 *		stable_how	committed;
1703 *		writeverf3	verf;
1704 *	};
1705 *
1706 *	struct WRITE3resfail {
1707 *		wcc_data	file_wcc;
1708 *	};
1709 *
1710 *	union WRITE3res switch (nfsstat3 status) {
1711 *	case NFS3_OK:
1712 *		WRITE3resok	resok;
1713 *	default:
1714 *		WRITE3resfail	resfail;
1715 *	};
1716 */
1717static int decode_write3resok(struct xdr_stream *xdr,
1718			      struct nfs_pgio_res *result)
1719{
1720	__be32 *p;
1721
1722	p = xdr_inline_decode(xdr, 4 + 4);
1723	if (unlikely(p == NULL))
1724		goto out_overflow;
1725	result->count = be32_to_cpup(p++);
1726	result->verf->committed = be32_to_cpup(p++);
1727	if (unlikely(result->verf->committed > NFS_FILE_SYNC))
1728		goto out_badvalue;
1729	if (decode_writeverf3(xdr, &result->verf->verifier))
1730		goto out_eio;
1731	return result->count;
1732out_badvalue:
1733	dprintk("NFS: bad stable_how value: %u\n", result->verf->committed);
1734	return -EIO;
1735out_overflow:
1736	print_overflow_msg(__func__, xdr);
1737out_eio:
1738	return -EIO;
1739}
1740
1741static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1742				  void *data)
1743{
1744	struct nfs_pgio_res *result = data;
1745	enum nfs_stat status;
1746	int error;
1747
1748	error = decode_nfsstat3(xdr, &status);
1749	if (unlikely(error))
1750		goto out;
1751	error = decode_wcc_data(xdr, result->fattr);
1752	if (unlikely(error))
1753		goto out;
1754	result->op_status = status;
1755	if (status != NFS3_OK)
1756		goto out_status;
1757	error = decode_write3resok(xdr, result);
1758out:
1759	return error;
1760out_status:
1761	return nfs3_stat_to_errno(status);
1762}
1763
1764/*
1765 * 3.3.8  CREATE3res
1766 *
1767 *	struct CREATE3resok {
1768 *		post_op_fh3	obj;
1769 *		post_op_attr	obj_attributes;
1770 *		wcc_data	dir_wcc;
1771 *	};
1772 *
1773 *	struct CREATE3resfail {
1774 *		wcc_data	dir_wcc;
1775 *	};
1776 *
1777 *	union CREATE3res switch (nfsstat3 status) {
1778 *	case NFS3_OK:
1779 *		CREATE3resok	resok;
1780 *	default:
1781 *		CREATE3resfail	resfail;
1782 *	};
1783 */
1784static int decode_create3resok(struct xdr_stream *xdr,
1785			       struct nfs3_diropres *result)
1786{
1787	int error;
1788
1789	error = decode_post_op_fh3(xdr, result->fh);
1790	if (unlikely(error))
1791		goto out;
1792	error = decode_post_op_attr(xdr, result->fattr);
1793	if (unlikely(error))
1794		goto out;
1795	/* The server isn't required to return a file handle.
1796	 * If it didn't, force the client to perform a LOOKUP
1797	 * to determine the correct file handle and attribute
1798	 * values for the new object. */
1799	if (result->fh->size == 0)
1800		result->fattr->valid = 0;
1801	error = decode_wcc_data(xdr, result->dir_attr);
1802out:
1803	return error;
1804}
1805
1806static int nfs3_xdr_dec_create3res(struct rpc_rqst *req,
1807				   struct xdr_stream *xdr,
1808				   void *data)
1809{
1810	struct nfs3_diropres *result = data;
1811	enum nfs_stat status;
1812	int error;
1813
1814	error = decode_nfsstat3(xdr, &status);
1815	if (unlikely(error))
1816		goto out;
1817	if (status != NFS3_OK)
1818		goto out_default;
1819	error = decode_create3resok(xdr, result);
1820out:
1821	return error;
1822out_default:
1823	error = decode_wcc_data(xdr, result->dir_attr);
1824	if (unlikely(error))
1825		goto out;
1826	return nfs3_stat_to_errno(status);
1827}
1828
1829/*
1830 * 3.3.12  REMOVE3res
1831 *
1832 *	struct REMOVE3resok {
1833 *		wcc_data    dir_wcc;
1834 *	};
1835 *
1836 *	struct REMOVE3resfail {
1837 *		wcc_data    dir_wcc;
1838 *	};
1839 *
1840 *	union REMOVE3res switch (nfsstat3 status) {
1841 *	case NFS3_OK:
1842 *		REMOVE3resok   resok;
1843 *	default:
1844 *		REMOVE3resfail resfail;
1845 *	};
1846 */
1847static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
1848				   struct xdr_stream *xdr,
1849				   void *data)
1850{
1851	struct nfs_removeres *result = data;
1852	enum nfs_stat status;
1853	int error;
1854
1855	error = decode_nfsstat3(xdr, &status);
1856	if (unlikely(error))
1857		goto out;
1858	error = decode_wcc_data(xdr, result->dir_attr);
1859	if (unlikely(error))
1860		goto out;
1861	if (status != NFS3_OK)
1862		goto out_status;
1863out:
1864	return error;
1865out_status:
1866	return nfs3_stat_to_errno(status);
1867}
1868
1869/*
1870 * 3.3.14  RENAME3res
1871 *
1872 *	struct RENAME3resok {
1873 *		wcc_data	fromdir_wcc;
1874 *		wcc_data	todir_wcc;
1875 *	};
1876 *
1877 *	struct RENAME3resfail {
1878 *		wcc_data	fromdir_wcc;
1879 *		wcc_data	todir_wcc;
1880 *	};
1881 *
1882 *	union RENAME3res switch (nfsstat3 status) {
1883 *	case NFS3_OK:
1884 *		RENAME3resok   resok;
1885 *	default:
1886 *		RENAME3resfail resfail;
1887 *	};
1888 */
1889static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
1890				   struct xdr_stream *xdr,
1891				   void *data)
1892{
1893	struct nfs_renameres *result = data;
1894	enum nfs_stat status;
1895	int error;
1896
1897	error = decode_nfsstat3(xdr, &status);
1898	if (unlikely(error))
1899		goto out;
1900	error = decode_wcc_data(xdr, result->old_fattr);
1901	if (unlikely(error))
1902		goto out;
1903	error = decode_wcc_data(xdr, result->new_fattr);
1904	if (unlikely(error))
1905		goto out;
1906	if (status != NFS3_OK)
1907		goto out_status;
1908out:
1909	return error;
1910out_status:
1911	return nfs3_stat_to_errno(status);
1912}
1913
1914/*
1915 * 3.3.15  LINK3res
1916 *
1917 *	struct LINK3resok {
1918 *		post_op_attr	file_attributes;
1919 *		wcc_data	linkdir_wcc;
1920 *	};
1921 *
1922 *	struct LINK3resfail {
1923 *		post_op_attr	file_attributes;
1924 *		wcc_data	linkdir_wcc;
1925 *	};
1926 *
1927 *	union LINK3res switch (nfsstat3 status) {
1928 *	case NFS3_OK:
1929 *		LINK3resok	resok;
1930 *	default:
1931 *		LINK3resfail	resfail;
1932 *	};
1933 */
1934static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
1935				 void *data)
1936{
1937	struct nfs3_linkres *result = data;
1938	enum nfs_stat status;
1939	int error;
1940
1941	error = decode_nfsstat3(xdr, &status);
1942	if (unlikely(error))
1943		goto out;
1944	error = decode_post_op_attr(xdr, result->fattr);
1945	if (unlikely(error))
1946		goto out;
1947	error = decode_wcc_data(xdr, result->dir_attr);
1948	if (unlikely(error))
1949		goto out;
1950	if (status != NFS3_OK)
1951		goto out_status;
1952out:
1953	return error;
1954out_status:
1955	return nfs3_stat_to_errno(status);
1956}
1957
1958/**
1959 * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in
1960 *			the local page cache
1961 * @xdr: XDR stream where entry resides
1962 * @entry: buffer to fill in with entry data
1963 * @plus: boolean indicating whether this should be a readdirplus entry
1964 *
1965 * Returns zero if successful, otherwise a negative errno value is
1966 * returned.
1967 *
1968 * This function is not invoked during READDIR reply decoding, but
1969 * rather whenever an application invokes the getdents(2) system call
1970 * on a directory already in our cache.
1971 *
1972 * 3.3.16  entry3
1973 *
1974 *	struct entry3 {
1975 *		fileid3		fileid;
1976 *		filename3	name;
1977 *		cookie3		cookie;
1978 *		fhandle3	filehandle;
1979 *		post_op_attr3	attributes;
1980 *		entry3		*nextentry;
1981 *	};
1982 *
1983 * 3.3.17  entryplus3
1984 *	struct entryplus3 {
1985 *		fileid3		fileid;
1986 *		filename3	name;
1987 *		cookie3		cookie;
1988 *		post_op_attr	name_attributes;
1989 *		post_op_fh3	name_handle;
1990 *		entryplus3	*nextentry;
1991 *	};
1992 */
1993int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
1994		       bool plus)
1995{
1996	struct nfs_entry old = *entry;
1997	__be32 *p;
1998	int error;
1999
2000	p = xdr_inline_decode(xdr, 4);
2001	if (unlikely(p == NULL))
2002		goto out_overflow;
2003	if (*p == xdr_zero) {
2004		p = xdr_inline_decode(xdr, 4);
2005		if (unlikely(p == NULL))
2006			goto out_overflow;
2007		if (*p == xdr_zero)
2008			return -EAGAIN;
2009		entry->eof = 1;
2010		return -EBADCOOKIE;
2011	}
2012
2013	error = decode_fileid3(xdr, &entry->ino);
2014	if (unlikely(error))
2015		return error;
2016
2017	error = decode_inline_filename3(xdr, &entry->name, &entry->len);
2018	if (unlikely(error))
2019		return error;
2020
2021	entry->prev_cookie = entry->cookie;
2022	error = decode_cookie3(xdr, &entry->cookie);
2023	if (unlikely(error))
2024		return error;
2025
2026	entry->d_type = DT_UNKNOWN;
2027
2028	if (plus) {
2029		entry->fattr->valid = 0;
2030		error = decode_post_op_attr(xdr, entry->fattr);
2031		if (unlikely(error))
2032			return error;
2033		if (entry->fattr->valid & NFS_ATTR_FATTR_V3)
2034			entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
2035
2036		if (entry->fattr->fileid != entry->ino) {
2037			entry->fattr->mounted_on_fileid = entry->ino;
2038			entry->fattr->valid |= NFS_ATTR_FATTR_MOUNTED_ON_FILEID;
2039		}
2040
2041		/* In fact, a post_op_fh3: */
2042		p = xdr_inline_decode(xdr, 4);
2043		if (unlikely(p == NULL))
2044			goto out_overflow;
2045		if (*p != xdr_zero) {
2046			error = decode_nfs_fh3(xdr, entry->fh);
2047			if (unlikely(error)) {
2048				if (error == -E2BIG)
2049					goto out_truncated;
2050				return error;
2051			}
2052		} else
2053			zero_nfs_fh3(entry->fh);
2054	}
2055
2056	return 0;
2057
2058out_overflow:
2059	print_overflow_msg(__func__, xdr);
2060	return -EAGAIN;
2061out_truncated:
2062	dprintk("NFS: directory entry contains invalid file handle\n");
2063	*entry = old;
2064	return -EAGAIN;
2065}
2066
2067/*
2068 * 3.3.16  READDIR3res
2069 *
2070 *	struct dirlist3 {
2071 *		entry3		*entries;
2072 *		bool		eof;
2073 *	};
2074 *
2075 *	struct READDIR3resok {
2076 *		post_op_attr	dir_attributes;
2077 *		cookieverf3	cookieverf;
2078 *		dirlist3	reply;
2079 *	};
2080 *
2081 *	struct READDIR3resfail {
2082 *		post_op_attr	dir_attributes;
2083 *	};
2084 *
2085 *	union READDIR3res switch (nfsstat3 status) {
2086 *	case NFS3_OK:
2087 *		READDIR3resok	resok;
2088 *	default:
2089 *		READDIR3resfail	resfail;
2090 *	};
2091 *
2092 * Read the directory contents into the page cache, but otherwise
2093 * don't touch them.  The actual decoding is done by nfs3_decode_entry()
2094 * during subsequent nfs_readdir() calls.
2095 */
2096static int decode_dirlist3(struct xdr_stream *xdr)
2097{
2098	return xdr_read_pages(xdr, xdr->buf->page_len);
2099}
2100
2101static int decode_readdir3resok(struct xdr_stream *xdr,
2102				struct nfs3_readdirres *result)
2103{
2104	int error;
2105
2106	error = decode_post_op_attr(xdr, result->dir_attr);
2107	if (unlikely(error))
2108		goto out;
2109	/* XXX: do we need to check if result->verf != NULL ? */
2110	error = decode_cookieverf3(xdr, result->verf);
2111	if (unlikely(error))
2112		goto out;
2113	error = decode_dirlist3(xdr);
2114out:
2115	return error;
2116}
2117
2118static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req,
2119				    struct xdr_stream *xdr,
2120				    void *data)
2121{
2122	struct nfs3_readdirres *result = data;
2123	enum nfs_stat status;
2124	int error;
2125
2126	error = decode_nfsstat3(xdr, &status);
2127	if (unlikely(error))
2128		goto out;
2129	if (status != NFS3_OK)
2130		goto out_default;
2131	error = decode_readdir3resok(xdr, result);
2132out:
2133	return error;
2134out_default:
2135	error = decode_post_op_attr(xdr, result->dir_attr);
2136	if (unlikely(error))
2137		goto out;
2138	return nfs3_stat_to_errno(status);
2139}
2140
2141/*
2142 * 3.3.18  FSSTAT3res
2143 *
2144 *	struct FSSTAT3resok {
2145 *		post_op_attr	obj_attributes;
2146 *		size3		tbytes;
2147 *		size3		fbytes;
2148 *		size3		abytes;
2149 *		size3		tfiles;
2150 *		size3		ffiles;
2151 *		size3		afiles;
2152 *		uint32		invarsec;
2153 *	};
2154 *
2155 *	struct FSSTAT3resfail {
2156 *		post_op_attr	obj_attributes;
2157 *	};
2158 *
2159 *	union FSSTAT3res switch (nfsstat3 status) {
2160 *	case NFS3_OK:
2161 *		FSSTAT3resok	resok;
2162 *	default:
2163 *		FSSTAT3resfail	resfail;
2164 *	};
2165 */
2166static int decode_fsstat3resok(struct xdr_stream *xdr,
2167			       struct nfs_fsstat *result)
2168{
2169	__be32 *p;
2170
2171	p = xdr_inline_decode(xdr, 8 * 6 + 4);
2172	if (unlikely(p == NULL))
2173		goto out_overflow;
2174	p = xdr_decode_size3(p, &result->tbytes);
2175	p = xdr_decode_size3(p, &result->fbytes);
2176	p = xdr_decode_size3(p, &result->abytes);
2177	p = xdr_decode_size3(p, &result->tfiles);
2178	p = xdr_decode_size3(p, &result->ffiles);
2179	xdr_decode_size3(p, &result->afiles);
2180	/* ignore invarsec */
2181	return 0;
2182out_overflow:
2183	print_overflow_msg(__func__, xdr);
2184	return -EIO;
2185}
2186
2187static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req,
2188				   struct xdr_stream *xdr,
2189				   void *data)
2190{
2191	struct nfs_fsstat *result = data;
2192	enum nfs_stat status;
2193	int error;
2194
2195	error = decode_nfsstat3(xdr, &status);
2196	if (unlikely(error))
2197		goto out;
2198	error = decode_post_op_attr(xdr, result->fattr);
2199	if (unlikely(error))
2200		goto out;
2201	if (status != NFS3_OK)
2202		goto out_status;
2203	error = decode_fsstat3resok(xdr, result);
2204out:
2205	return error;
2206out_status:
2207	return nfs3_stat_to_errno(status);
2208}
2209
2210/*
2211 * 3.3.19  FSINFO3res
2212 *
2213 *	struct FSINFO3resok {
2214 *		post_op_attr	obj_attributes;
2215 *		uint32		rtmax;
2216 *		uint32		rtpref;
2217 *		uint32		rtmult;
2218 *		uint32		wtmax;
2219 *		uint32		wtpref;
2220 *		uint32		wtmult;
2221 *		uint32		dtpref;
2222 *		size3		maxfilesize;
2223 *		nfstime3	time_delta;
2224 *		uint32		properties;
2225 *	};
2226 *
2227 *	struct FSINFO3resfail {
2228 *		post_op_attr	obj_attributes;
2229 *	};
2230 *
2231 *	union FSINFO3res switch (nfsstat3 status) {
2232 *	case NFS3_OK:
2233 *		FSINFO3resok	resok;
2234 *	default:
2235 *		FSINFO3resfail	resfail;
2236 *	};
2237 */
2238static int decode_fsinfo3resok(struct xdr_stream *xdr,
2239			       struct nfs_fsinfo *result)
2240{
2241	__be32 *p;
2242
2243	p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4);
2244	if (unlikely(p == NULL))
2245		goto out_overflow;
2246	result->rtmax  = be32_to_cpup(p++);
2247	result->rtpref = be32_to_cpup(p++);
2248	result->rtmult = be32_to_cpup(p++);
2249	result->wtmax  = be32_to_cpup(p++);
2250	result->wtpref = be32_to_cpup(p++);
2251	result->wtmult = be32_to_cpup(p++);
2252	result->dtpref = be32_to_cpup(p++);
2253	p = xdr_decode_size3(p, &result->maxfilesize);
2254	xdr_decode_nfstime3(p, &result->time_delta);
2255
2256	/* ignore properties */
2257	result->lease_time = 0;
2258	return 0;
2259out_overflow:
2260	print_overflow_msg(__func__, xdr);
2261	return -EIO;
2262}
2263
2264static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
2265				   struct xdr_stream *xdr,
2266				   void *data)
2267{
2268	struct nfs_fsinfo *result = data;
2269	enum nfs_stat status;
2270	int error;
2271
2272	error = decode_nfsstat3(xdr, &status);
2273	if (unlikely(error))
2274		goto out;
2275	error = decode_post_op_attr(xdr, result->fattr);
2276	if (unlikely(error))
2277		goto out;
2278	if (status != NFS3_OK)
2279		goto out_status;
2280	error = decode_fsinfo3resok(xdr, result);
2281out:
2282	return error;
2283out_status:
2284	return nfs3_stat_to_errno(status);
2285}
2286
2287/*
2288 * 3.3.20  PATHCONF3res
2289 *
2290 *	struct PATHCONF3resok {
2291 *		post_op_attr	obj_attributes;
2292 *		uint32		linkmax;
2293 *		uint32		name_max;
2294 *		bool		no_trunc;
2295 *		bool		chown_restricted;
2296 *		bool		case_insensitive;
2297 *		bool		case_preserving;
2298 *	};
2299 *
2300 *	struct PATHCONF3resfail {
2301 *		post_op_attr	obj_attributes;
2302 *	};
2303 *
2304 *	union PATHCONF3res switch (nfsstat3 status) {
2305 *	case NFS3_OK:
2306 *		PATHCONF3resok	resok;
2307 *	default:
2308 *		PATHCONF3resfail resfail;
2309 *	};
2310 */
2311static int decode_pathconf3resok(struct xdr_stream *xdr,
2312				 struct nfs_pathconf *result)
2313{
2314	__be32 *p;
2315
2316	p = xdr_inline_decode(xdr, 4 * 6);
2317	if (unlikely(p == NULL))
2318		goto out_overflow;
2319	result->max_link = be32_to_cpup(p++);
2320	result->max_namelen = be32_to_cpup(p);
2321	/* ignore remaining fields */
2322	return 0;
2323out_overflow:
2324	print_overflow_msg(__func__, xdr);
2325	return -EIO;
2326}
2327
2328static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
2329				     struct xdr_stream *xdr,
2330				     void *data)
2331{
2332	struct nfs_pathconf *result = data;
2333	enum nfs_stat status;
2334	int er

Large files files are truncated, but you can click here to view the full file