Linux Audio

Check our new training course

Loading...
v5.14.15
   1/*
   2 *  Server-side XDR for NFSv4
   3 *
   4 *  Copyright (c) 2002 The Regents of the University of Michigan.
   5 *  All rights reserved.
   6 *
   7 *  Kendrick Smith <kmsmith@umich.edu>
   8 *  Andy Adamson   <andros@umich.edu>
   9 *
  10 *  Redistribution and use in source and binary forms, with or without
  11 *  modification, are permitted provided that the following conditions
  12 *  are met:
  13 *
  14 *  1. Redistributions of source code must retain the above copyright
  15 *     notice, this list of conditions and the following disclaimer.
  16 *  2. Redistributions in binary form must reproduce the above copyright
  17 *     notice, this list of conditions and the following disclaimer in the
  18 *     documentation and/or other materials provided with the distribution.
  19 *  3. Neither the name of the University nor the names of its
  20 *     contributors may be used to endorse or promote products derived
  21 *     from this software without specific prior written permission.
  22 *
  23 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  24 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  25 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  30 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 
 
 
 
 
  34 */
  35
  36#include <linux/file.h>
  37#include <linux/slab.h>
  38#include <linux/namei.h>
  39#include <linux/statfs.h>
  40#include <linux/utsname.h>
  41#include <linux/pagemap.h>
  42#include <linux/sunrpc/svcauth_gss.h>
  43#include <linux/sunrpc/addr.h>
  44#include <linux/xattr.h>
  45#include <uapi/linux/xattr.h>
  46
  47#include "idmap.h"
  48#include "acl.h"
  49#include "xdr4.h"
  50#include "vfs.h"
  51#include "state.h"
  52#include "cache.h"
  53#include "netns.h"
  54#include "pnfs.h"
  55#include "filecache.h"
  56
  57#include "trace.h"
  58
  59#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
  60#include <linux/security.h>
  61#endif
  62
  63
  64#define NFSDDBG_FACILITY		NFSDDBG_XDR
  65
  66const u32 nfsd_suppattrs[3][3] = {
  67	{NFSD4_SUPPORTED_ATTRS_WORD0,
  68	 NFSD4_SUPPORTED_ATTRS_WORD1,
  69	 NFSD4_SUPPORTED_ATTRS_WORD2},
  70
  71	{NFSD4_1_SUPPORTED_ATTRS_WORD0,
  72	 NFSD4_1_SUPPORTED_ATTRS_WORD1,
  73	 NFSD4_1_SUPPORTED_ATTRS_WORD2},
  74
  75	{NFSD4_1_SUPPORTED_ATTRS_WORD0,
  76	 NFSD4_1_SUPPORTED_ATTRS_WORD1,
  77	 NFSD4_2_SUPPORTED_ATTRS_WORD2},
  78};
  79
  80/*
  81 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
  82 * directory in order to indicate to the client that a filesystem boundary is present
  83 * We use a fixed fsid for a referral
  84 */
  85#define NFS4_REFERRAL_FSID_MAJOR	0x8000000ULL
  86#define NFS4_REFERRAL_FSID_MINOR	0x8000000ULL
  87
  88static __be32
  89check_filename(char *str, int len)
  90{
  91	int i;
  92
  93	if (len == 0)
  94		return nfserr_inval;
  95	if (len > NFS4_MAXNAMLEN)
  96		return nfserr_nametoolong;
  97	if (isdotent(str, len))
  98		return nfserr_badname;
  99	for (i = 0; i < len; i++)
 100		if (str[i] == '/')
 101			return nfserr_badname;
 102	return 0;
 103}
 104
 105static int zero_clientid(clientid_t *clid)
 106{
 107	return (clid->cl_boot == 0) && (clid->cl_id == 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 108}
 109
 110/**
 111 * svcxdr_tmpalloc - allocate memory to be freed after compound processing
 112 * @argp: NFSv4 compound argument structure
 113 * @len: length of buffer to allocate
 114 *
 115 * Allocates a buffer of size @len to be freed when processing the compound
 116 * operation described in @argp finishes.
 117 */
 118static void *
 119svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
 120{
 121	struct svcxdr_tmpbuf *tb;
 122
 123	tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
 124	if (!tb)
 
 
 125		return NULL;
 126	tb->next = argp->to_free;
 127	argp->to_free = tb;
 128	return tb->buf;
 129}
 130
 131/*
 132 * For xdr strings that need to be passed to other kernel api's
 133 * as null-terminated strings.
 134 *
 135 * Note null-terminating in place usually isn't safe since the
 136 * buffer might end on a page boundary.
 137 */
 138static char *
 139svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
 140{
 141	char *p = svcxdr_tmpalloc(argp, len + 1);
 142
 143	if (!p)
 144		return NULL;
 145	memcpy(p, buf, len);
 146	p[len] = '\0';
 147	return p;
 148}
 149
 150static void *
 151svcxdr_savemem(struct nfsd4_compoundargs *argp, __be32 *p, u32 len)
 152{
 153	__be32 *tmp;
 154
 155	/*
 156	 * The location of the decoded data item is stable,
 157	 * so @p is OK to use. This is the common case.
 
 158	 */
 159	if (p != argp->xdr->scratch.iov_base)
 160		return p;
 161
 162	tmp = svcxdr_tmpalloc(argp, len);
 163	if (!tmp)
 164		return NULL;
 165	memcpy(tmp, p, len);
 166	return tmp;
 167}
 168
 169/*
 170 * NFSv4 basic data type decoders
 171 */
 172
 173/*
 174 * This helper handles variable-length opaques which belong to protocol
 175 * elements that this implementation does not support.
 176 */
 177static __be32
 178nfsd4_decode_ignored_string(struct nfsd4_compoundargs *argp, u32 maxlen)
 179{
 180	u32 len;
 181
 182	if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
 183		return nfserr_bad_xdr;
 184	if (maxlen && len > maxlen)
 185		return nfserr_bad_xdr;
 186	if (!xdr_inline_decode(argp->xdr, len))
 187		return nfserr_bad_xdr;
 188
 189	return nfs_ok;
 190}
 191
 192static __be32
 193nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
 194{
 195	__be32 *p;
 196	u32 len;
 197
 198	if (xdr_stream_decode_u32(argp->xdr, &len) < 0)
 199		return nfserr_bad_xdr;
 200	if (len == 0 || len > NFS4_OPAQUE_LIMIT)
 201		return nfserr_bad_xdr;
 202	p = xdr_inline_decode(argp->xdr, len);
 203	if (!p)
 204		return nfserr_bad_xdr;
 205	o->data = svcxdr_savemem(argp, p, len);
 206	if (!o->data)
 207		return nfserr_jukebox;
 208	o->len = len;
 209
 210	return nfs_ok;
 211}
 212
 213static __be32
 214nfsd4_decode_component4(struct nfsd4_compoundargs *argp, char **namp, u32 *lenp)
 
 215{
 216	__be32 *p, status;
 217
 218	if (xdr_stream_decode_u32(argp->xdr, lenp) < 0)
 219		return nfserr_bad_xdr;
 220	p = xdr_inline_decode(argp->xdr, *lenp);
 221	if (!p)
 222		return nfserr_bad_xdr;
 223	status = check_filename((char *)p, *lenp);
 224	if (status)
 225		return status;
 226	*namp = svcxdr_savemem(argp, p, *lenp);
 227	if (!*namp)
 228		return nfserr_jukebox;
 229
 230	return nfs_ok;
 231}
 232
 233static __be32
 234nfsd4_decode_nfstime4(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 235{
 236	__be32 *p;
 237
 238	p = xdr_inline_decode(argp->xdr, XDR_UNIT * 3);
 239	if (!p)
 240		return nfserr_bad_xdr;
 241	p = xdr_decode_hyper(p, &tv->tv_sec);
 242	tv->tv_nsec = be32_to_cpup(p++);
 243	if (tv->tv_nsec >= (u32)1000000000)
 244		return nfserr_inval;
 245	return nfs_ok;
 
 
 
 
 246}
 247
 248static __be32
 249nfsd4_decode_verifier4(struct nfsd4_compoundargs *argp, nfs4_verifier *verf)
 250{
 251	__be32 *p;
 
 252
 253	p = xdr_inline_decode(argp->xdr, NFS4_VERIFIER_SIZE);
 254	if (!p)
 255		return nfserr_bad_xdr;
 256	memcpy(verf->data, p, sizeof(verf->data));
 257	return nfs_ok;
 258}
 259
 260/**
 261 * nfsd4_decode_bitmap4 - Decode an NFSv4 bitmap4
 262 * @argp: NFSv4 compound argument structure
 263 * @bmval: pointer to an array of u32's to decode into
 264 * @bmlen: size of the @bmval array
 265 *
 266 * The server needs to return nfs_ok rather than nfserr_bad_xdr when
 267 * encountering bitmaps containing bits it does not recognize. This
 268 * includes bits in bitmap words past WORDn, where WORDn is the last
 269 * bitmap WORD the implementation currently supports. Thus we are
 270 * careful here to simply ignore bits in bitmap words that this
 271 * implementation has yet to support explicitly.
 272 *
 273 * Return values:
 274 *   %nfs_ok: @bmval populated successfully
 275 *   %nfserr_bad_xdr: the encoded bitmap was invalid
 276 */
 277static __be32
 278nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen)
 279{
 280	u32 i, count;
 281	__be32 *p;
 282
 283	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
 284		return nfserr_bad_xdr;
 285	/* request sanity */
 286	if (count > 1000)
 287		return nfserr_bad_xdr;
 288	p = xdr_inline_decode(argp->xdr, count << 2);
 289	if (!p)
 290		return nfserr_bad_xdr;
 291	i = 0;
 292	while (i < count)
 293		bmval[i++] = be32_to_cpup(p++);
 294	while (i < bmlen)
 295		bmval[i++] = 0;
 296
 297	return nfs_ok;
 298}
 299
 300static __be32
 301nfsd4_decode_nfsace4(struct nfsd4_compoundargs *argp, struct nfs4_ace *ace)
 302{
 303	__be32 *p, status;
 304	u32 length;
 305
 306	if (xdr_stream_decode_u32(argp->xdr, &ace->type) < 0)
 307		return nfserr_bad_xdr;
 308	if (xdr_stream_decode_u32(argp->xdr, &ace->flag) < 0)
 309		return nfserr_bad_xdr;
 310	if (xdr_stream_decode_u32(argp->xdr, &ace->access_mask) < 0)
 311		return nfserr_bad_xdr;
 312
 313	if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
 314		return nfserr_bad_xdr;
 315	p = xdr_inline_decode(argp->xdr, length);
 316	if (!p)
 317		return nfserr_bad_xdr;
 318	ace->whotype = nfs4_acl_get_whotype((char *)p, length);
 319	if (ace->whotype != NFS4_ACL_WHO_NAMED)
 320		status = nfs_ok;
 321	else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
 322		status = nfsd_map_name_to_gid(argp->rqstp,
 323				(char *)p, length, &ace->who_gid);
 324	else
 325		status = nfsd_map_name_to_uid(argp->rqstp,
 326				(char *)p, length, &ace->who_uid);
 327
 328	return status;
 329}
 330
 331/* A counted array of nfsace4's */
 332static noinline __be32
 333nfsd4_decode_acl(struct nfsd4_compoundargs *argp, struct nfs4_acl **acl)
 334{
 335	struct nfs4_ace *ace;
 336	__be32 status;
 337	u32 count;
 338
 339	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
 340		return nfserr_bad_xdr;
 341
 342	if (count > xdr_stream_remaining(argp->xdr) / 20)
 343		/*
 344		 * Even with 4-byte names there wouldn't be
 345		 * space for that many aces; something fishy is
 346		 * going on:
 347		 */
 348		return nfserr_fbig;
 349
 350	*acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(count));
 351	if (*acl == NULL)
 352		return nfserr_jukebox;
 353
 354	(*acl)->naces = count;
 355	for (ace = (*acl)->aces; ace < (*acl)->aces + count; ace++) {
 356		status = nfsd4_decode_nfsace4(argp, ace);
 357		if (status)
 358			return status;
 359	}
 360
 361	return nfs_ok;
 362}
 363
 364static noinline __be32
 365nfsd4_decode_security_label(struct nfsd4_compoundargs *argp,
 366			    struct xdr_netobj *label)
 367{
 368	u32 lfs, pi, length;
 369	__be32 *p;
 370
 371	if (xdr_stream_decode_u32(argp->xdr, &lfs) < 0)
 372		return nfserr_bad_xdr;
 373	if (xdr_stream_decode_u32(argp->xdr, &pi) < 0)
 374		return nfserr_bad_xdr;
 375
 376	if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
 377		return nfserr_bad_xdr;
 378	if (length > NFS4_MAXLABELLEN)
 379		return nfserr_badlabel;
 380	p = xdr_inline_decode(argp->xdr, length);
 381	if (!p)
 382		return nfserr_bad_xdr;
 383	label->len = length;
 384	label->data = svcxdr_dupstr(argp, p, length);
 385	if (!label->data)
 386		return nfserr_jukebox;
 387
 388	return nfs_ok;
 389}
 390
 391static __be32
 392nfsd4_decode_fattr4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen,
 393		    struct iattr *iattr, struct nfs4_acl **acl,
 394		    struct xdr_netobj *label, int *umask)
 395{
 396	unsigned int starting_pos;
 397	u32 attrlist4_count;
 398	__be32 *p, status;
 399
 
 400	iattr->ia_valid = 0;
 401	status = nfsd4_decode_bitmap4(argp, bmval, bmlen);
 402	if (status)
 403		return nfserr_bad_xdr;
 404
 405	if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
 406	    || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
 407	    || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2) {
 408		if (nfsd_attrs_supported(argp->minorversion, bmval))
 409			return nfserr_inval;
 410		return nfserr_attrnotsupp;
 411	}
 412
 413	if (xdr_stream_decode_u32(argp->xdr, &attrlist4_count) < 0)
 414		return nfserr_bad_xdr;
 415	starting_pos = xdr_stream_pos(argp->xdr);
 416
 417	if (bmval[0] & FATTR4_WORD0_SIZE) {
 418		u64 size;
 419
 420		if (xdr_stream_decode_u64(argp->xdr, &size) < 0)
 421			return nfserr_bad_xdr;
 422		iattr->ia_size = size;
 423		iattr->ia_valid |= ATTR_SIZE;
 424	}
 425	if (bmval[0] & FATTR4_WORD0_ACL) {
 426		status = nfsd4_decode_acl(argp, acl);
 427		if (status)
 428			return status;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 429	} else
 430		*acl = NULL;
 431	if (bmval[1] & FATTR4_WORD1_MODE) {
 432		u32 mode;
 433
 434		if (xdr_stream_decode_u32(argp->xdr, &mode) < 0)
 435			return nfserr_bad_xdr;
 436		iattr->ia_mode = mode;
 437		iattr->ia_mode &= (S_IFMT | S_IALLUGO);
 438		iattr->ia_valid |= ATTR_MODE;
 439	}
 440	if (bmval[1] & FATTR4_WORD1_OWNER) {
 441		u32 length;
 442
 443		if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
 444			return nfserr_bad_xdr;
 445		p = xdr_inline_decode(argp->xdr, length);
 446		if (!p)
 447			return nfserr_bad_xdr;
 448		status = nfsd_map_name_to_uid(argp->rqstp, (char *)p, length,
 449					      &iattr->ia_uid);
 450		if (status)
 451			return status;
 452		iattr->ia_valid |= ATTR_UID;
 453	}
 454	if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
 455		u32 length;
 456
 457		if (xdr_stream_decode_u32(argp->xdr, &length) < 0)
 458			return nfserr_bad_xdr;
 459		p = xdr_inline_decode(argp->xdr, length);
 460		if (!p)
 461			return nfserr_bad_xdr;
 462		status = nfsd_map_name_to_gid(argp->rqstp, (char *)p, length,
 463					      &iattr->ia_gid);
 464		if (status)
 465			return status;
 466		iattr->ia_valid |= ATTR_GID;
 467	}
 468	if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
 469		u32 set_it;
 470
 471		if (xdr_stream_decode_u32(argp->xdr, &set_it) < 0)
 472			return nfserr_bad_xdr;
 473		switch (set_it) {
 474		case NFS4_SET_TO_CLIENT_TIME:
 475			status = nfsd4_decode_nfstime4(argp, &iattr->ia_atime);
 476			if (status)
 477				return status;
 
 
 
 
 
 
 
 
 478			iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
 479			break;
 480		case NFS4_SET_TO_SERVER_TIME:
 481			iattr->ia_valid |= ATTR_ATIME;
 482			break;
 483		default:
 484			return nfserr_bad_xdr;
 485		}
 486	}
 487	if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
 488		u32 set_it;
 489
 490		if (xdr_stream_decode_u32(argp->xdr, &set_it) < 0)
 491			return nfserr_bad_xdr;
 492		switch (set_it) {
 493		case NFS4_SET_TO_CLIENT_TIME:
 494			status = nfsd4_decode_nfstime4(argp, &iattr->ia_mtime);
 495			if (status)
 496				return status;
 
 
 
 
 
 
 
 
 497			iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
 498			break;
 499		case NFS4_SET_TO_SERVER_TIME:
 500			iattr->ia_valid |= ATTR_MTIME;
 501			break;
 502		default:
 503			return nfserr_bad_xdr;
 504		}
 505	}
 506	label->len = 0;
 507	if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
 508	    bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
 509		status = nfsd4_decode_security_label(argp, label);
 510		if (status)
 511			return status;
 512	}
 513	if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
 514		u32 mode, mask;
 515
 516		if (!umask)
 517			return nfserr_bad_xdr;
 518		if (xdr_stream_decode_u32(argp->xdr, &mode) < 0)
 519			return nfserr_bad_xdr;
 520		iattr->ia_mode = mode & (S_IFMT | S_IALLUGO);
 521		if (xdr_stream_decode_u32(argp->xdr, &mask) < 0)
 522			return nfserr_bad_xdr;
 523		*umask = mask & S_IRWXUGO;
 524		iattr->ia_valid |= ATTR_MODE;
 525	}
 526
 527	/* request sanity: did attrlist4 contain the expected number of words? */
 528	if (attrlist4_count != xdr_stream_pos(argp->xdr) - starting_pos)
 529		return nfserr_bad_xdr;
 530
 531	return nfs_ok;
 532}
 533
 534static __be32
 535nfsd4_decode_stateid4(struct nfsd4_compoundargs *argp, stateid_t *sid)
 536{
 537	__be32 *p;
 538
 539	p = xdr_inline_decode(argp->xdr, NFS4_STATEID_SIZE);
 540	if (!p)
 541		return nfserr_bad_xdr;
 542	sid->si_generation = be32_to_cpup(p++);
 543	memcpy(&sid->si_opaque, p, sizeof(sid->si_opaque));
 544	return nfs_ok;
 545}
 546
 547static __be32
 548nfsd4_decode_clientid4(struct nfsd4_compoundargs *argp, clientid_t *clientid)
 549{
 550	__be32 *p;
 551
 552	p = xdr_inline_decode(argp->xdr, sizeof(__be64));
 553	if (!p)
 554		return nfserr_bad_xdr;
 555	memcpy(clientid, p, sizeof(*clientid));
 556	return nfs_ok;
 557}
 558
 559static __be32
 560nfsd4_decode_state_owner4(struct nfsd4_compoundargs *argp,
 561			  clientid_t *clientid, struct xdr_netobj *owner)
 562{
 563	__be32 status;
 564
 565	status = nfsd4_decode_clientid4(argp, clientid);
 566	if (status)
 567		return status;
 568	return nfsd4_decode_opaque(argp, owner);
 569}
 570
 571#ifdef CONFIG_NFSD_PNFS
 572static __be32
 573nfsd4_decode_deviceid4(struct nfsd4_compoundargs *argp,
 574		       struct nfsd4_deviceid *devid)
 575{
 576	__be32 *p;
 577
 578	p = xdr_inline_decode(argp->xdr, NFS4_DEVICEID4_SIZE);
 579	if (!p)
 580		return nfserr_bad_xdr;
 581	memcpy(devid, p, sizeof(*devid));
 582	return nfs_ok;
 583}
 584
 585static __be32
 586nfsd4_decode_layoutupdate4(struct nfsd4_compoundargs *argp,
 587			   struct nfsd4_layoutcommit *lcp)
 588{
 589	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_layout_type) < 0)
 590		return nfserr_bad_xdr;
 591	if (lcp->lc_layout_type < LAYOUT_NFSV4_1_FILES)
 592		return nfserr_bad_xdr;
 593	if (lcp->lc_layout_type >= LAYOUT_TYPE_MAX)
 594		return nfserr_bad_xdr;
 595
 596	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_up_len) < 0)
 597		return nfserr_bad_xdr;
 598	if (lcp->lc_up_len > 0) {
 599		lcp->lc_up_layout = xdr_inline_decode(argp->xdr, lcp->lc_up_len);
 600		if (!lcp->lc_up_layout)
 601			return nfserr_bad_xdr;
 602	}
 603
 604	return nfs_ok;
 
 
 605}
 606
 607static __be32
 608nfsd4_decode_layoutreturn4(struct nfsd4_compoundargs *argp,
 609			   struct nfsd4_layoutreturn *lrp)
 610{
 611	__be32 status;
 612
 613	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_return_type) < 0)
 614		return nfserr_bad_xdr;
 615	switch (lrp->lr_return_type) {
 616	case RETURN_FILE:
 617		if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.offset) < 0)
 618			return nfserr_bad_xdr;
 619		if (xdr_stream_decode_u64(argp->xdr, &lrp->lr_seg.length) < 0)
 620			return nfserr_bad_xdr;
 621		status = nfsd4_decode_stateid4(argp, &lrp->lr_sid);
 622		if (status)
 623			return status;
 624		if (xdr_stream_decode_u32(argp->xdr, &lrp->lrf_body_len) < 0)
 625			return nfserr_bad_xdr;
 626		if (lrp->lrf_body_len > 0) {
 627			lrp->lrf_body = xdr_inline_decode(argp->xdr, lrp->lrf_body_len);
 628			if (!lrp->lrf_body)
 629				return nfserr_bad_xdr;
 630		}
 631		break;
 632	case RETURN_FSID:
 633	case RETURN_ALL:
 634		lrp->lr_seg.offset = 0;
 635		lrp->lr_seg.length = NFS4_MAX_UINT64;
 636		break;
 637	default:
 638		return nfserr_bad_xdr;
 639	}
 640
 641	return nfs_ok;
 642}
 643
 644#endif /* CONFIG_NFSD_PNFS */
 
 
 645
 646static __be32
 647nfsd4_decode_sessionid4(struct nfsd4_compoundargs *argp,
 648			struct nfs4_sessionid *sessionid)
 649{
 650	__be32 *p;
 651
 652	p = xdr_inline_decode(argp->xdr, NFS4_MAX_SESSIONID_LEN);
 653	if (!p)
 654		return nfserr_bad_xdr;
 655	memcpy(sessionid->data, p, sizeof(sessionid->data));
 656	return nfs_ok;
 657}
 658
 659/* Defined in Appendix A of RFC 5531 */
 660static __be32
 661nfsd4_decode_authsys_parms(struct nfsd4_compoundargs *argp,
 662			   struct nfsd4_cb_sec *cbs)
 663{
 664	u32 stamp, gidcount, uid, gid;
 665	__be32 *p, status;
 666
 667	if (xdr_stream_decode_u32(argp->xdr, &stamp) < 0)
 668		return nfserr_bad_xdr;
 669	/* machine name */
 670	status = nfsd4_decode_ignored_string(argp, 255);
 671	if (status)
 672		return status;
 673	if (xdr_stream_decode_u32(argp->xdr, &uid) < 0)
 674		return nfserr_bad_xdr;
 675	if (xdr_stream_decode_u32(argp->xdr, &gid) < 0)
 676		return nfserr_bad_xdr;
 677	if (xdr_stream_decode_u32(argp->xdr, &gidcount) < 0)
 678		return nfserr_bad_xdr;
 679	if (gidcount > 16)
 680		return nfserr_bad_xdr;
 681	p = xdr_inline_decode(argp->xdr, gidcount << 2);
 682	if (!p)
 683		return nfserr_bad_xdr;
 684	if (cbs->flavor == (u32)(-1)) {
 685		struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
 686
 687		kuid_t kuid = make_kuid(userns, uid);
 688		kgid_t kgid = make_kgid(userns, gid);
 689		if (uid_valid(kuid) && gid_valid(kgid)) {
 690			cbs->uid = kuid;
 691			cbs->gid = kgid;
 692			cbs->flavor = RPC_AUTH_UNIX;
 693		} else {
 694			dprintk("RPC_AUTH_UNIX with invalid uid or gid, ignoring!\n");
 695		}
 696	}
 697
 698	return nfs_ok;
 699}
 700
 701static __be32
 702nfsd4_decode_gss_cb_handles4(struct nfsd4_compoundargs *argp,
 703			     struct nfsd4_cb_sec *cbs)
 704{
 705	__be32 status;
 706	u32 service;
 707
 708	dprintk("RPC_AUTH_GSS callback secflavor not supported!\n");
 709
 710	if (xdr_stream_decode_u32(argp->xdr, &service) < 0)
 711		return nfserr_bad_xdr;
 712	if (service < RPC_GSS_SVC_NONE || service > RPC_GSS_SVC_PRIVACY)
 713		return nfserr_bad_xdr;
 714	/* gcbp_handle_from_server */
 715	status = nfsd4_decode_ignored_string(argp, 0);
 716	if (status)
 717		return status;
 718	/* gcbp_handle_from_client */
 719	status = nfsd4_decode_ignored_string(argp, 0);
 720	if (status)
 721		return status;
 722
 723	return nfs_ok;
 
 
 
 
 
 724}
 725
 726/* a counted array of callback_sec_parms4 items */
 727static __be32
 728nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 729{
 730	u32 i, secflavor, nr_secflavs;
 731	__be32 status;
 732
 733	/* callback_sec_params4 */
 734	if (xdr_stream_decode_u32(argp->xdr, &nr_secflavs) < 0)
 735		return nfserr_bad_xdr;
 736	if (nr_secflavs)
 737		cbs->flavor = (u32)(-1);
 738	else
 739		/* Is this legal? Be generous, take it to mean AUTH_NONE: */
 740		cbs->flavor = 0;
 741
 742	for (i = 0; i < nr_secflavs; ++i) {
 743		if (xdr_stream_decode_u32(argp->xdr, &secflavor) < 0)
 744			return nfserr_bad_xdr;
 745		switch (secflavor) {
 746		case RPC_AUTH_NULL:
 747			/* void */
 748			if (cbs->flavor == (u32)(-1))
 749				cbs->flavor = RPC_AUTH_NULL;
 750			break;
 751		case RPC_AUTH_UNIX:
 752			status = nfsd4_decode_authsys_parms(argp, cbs);
 753			if (status)
 754				return status;
 755			break;
 756		case RPC_AUTH_GSS:
 757			status = nfsd4_decode_gss_cb_handles4(argp, cbs);
 758			if (status)
 759				return status;
 760			break;
 761		default:
 762			return nfserr_inval;
 763		}
 764	}
 765
 766	return nfs_ok;
 767}
 768
 769
 770/*
 771 * NFSv4 operation argument decoders
 772 */
 773
 774static __be32
 775nfsd4_decode_access(struct nfsd4_compoundargs *argp,
 776		    struct nfsd4_access *access)
 777{
 778	if (xdr_stream_decode_u32(argp->xdr, &access->ac_req_access) < 0)
 779		return nfserr_bad_xdr;
 780	return nfs_ok;
 781}
 782
 783static __be32
 784nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 785{
 786	if (xdr_stream_decode_u32(argp->xdr, &close->cl_seqid) < 0)
 787		return nfserr_bad_xdr;
 788	return nfsd4_decode_stateid4(argp, &close->cl_stateid);
 789}
 790
 
 
 
 791
 792static __be32
 793nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
 794{
 795	if (xdr_stream_decode_u64(argp->xdr, &commit->co_offset) < 0)
 796		return nfserr_bad_xdr;
 797	if (xdr_stream_decode_u32(argp->xdr, &commit->co_count) < 0)
 798		return nfserr_bad_xdr;
 799	return nfs_ok;
 800}
 801
 802static __be32
 803nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
 804{
 805	__be32 *p, status;
 806
 807	if (xdr_stream_decode_u32(argp->xdr, &create->cr_type) < 0)
 808		return nfserr_bad_xdr;
 809	switch (create->cr_type) {
 810	case NF4LNK:
 811		if (xdr_stream_decode_u32(argp->xdr, &create->cr_datalen) < 0)
 812			return nfserr_bad_xdr;
 813		p = xdr_inline_decode(argp->xdr, create->cr_datalen);
 814		if (!p)
 815			return nfserr_bad_xdr;
 816		create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
 817		if (!create->cr_data)
 818			return nfserr_jukebox;
 819		break;
 820	case NF4BLK:
 821	case NF4CHR:
 822		if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata1) < 0)
 823			return nfserr_bad_xdr;
 824		if (xdr_stream_decode_u32(argp->xdr, &create->cr_specdata2) < 0)
 825			return nfserr_bad_xdr;
 826		break;
 827	case NF4SOCK:
 828	case NF4FIFO:
 829	case NF4DIR:
 830	default:
 831		break;
 832	}
 833	status = nfsd4_decode_component4(argp, &create->cr_name,
 834					 &create->cr_namelen);
 835	if (status)
 
 
 
 836		return status;
 837	status = nfsd4_decode_fattr4(argp, create->cr_bmval,
 838				    ARRAY_SIZE(create->cr_bmval),
 839				    &create->cr_iattr, &create->cr_acl,
 840				    &create->cr_label, &create->cr_umask);
 841	if (status)
 842		return status;
 843
 844	return nfs_ok;
 845}
 846
 847static inline __be32
 848nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
 849{
 850	return nfsd4_decode_stateid4(argp, &dr->dr_stateid);
 851}
 852
 853static inline __be32
 854nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
 855{
 856	return nfsd4_decode_bitmap4(argp, getattr->ga_bmval,
 857				    ARRAY_SIZE(getattr->ga_bmval));
 858}
 859
 860static __be32
 861nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 862{
 863	return nfsd4_decode_component4(argp, &link->li_name, &link->li_namelen);
 864}
 865
 866static __be32
 867nfsd4_decode_open_to_lock_owner4(struct nfsd4_compoundargs *argp,
 868				 struct nfsd4_lock *lock)
 869{
 870	__be32 status;
 871
 872	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_open_seqid) < 0)
 873		return nfserr_bad_xdr;
 874	status = nfsd4_decode_stateid4(argp, &lock->lk_new_open_stateid);
 875	if (status)
 876		return status;
 877	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_new_lock_seqid) < 0)
 878		return nfserr_bad_xdr;
 879	return nfsd4_decode_state_owner4(argp, &lock->lk_new_clientid,
 880					 &lock->lk_new_owner);
 881}
 882
 883static __be32
 884nfsd4_decode_exist_lock_owner4(struct nfsd4_compoundargs *argp,
 885			       struct nfsd4_lock *lock)
 886{
 887	__be32 status;
 888
 889	status = nfsd4_decode_stateid4(argp, &lock->lk_old_lock_stateid);
 890	if (status)
 891		return status;
 892	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_old_lock_seqid) < 0)
 893		return nfserr_bad_xdr;
 894
 895	return nfs_ok;
 896}
 897
 898static __be32
 899nfsd4_decode_locker4(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 900{
 901	if (xdr_stream_decode_bool(argp->xdr, &lock->lk_is_new) < 0)
 902		return nfserr_bad_xdr;
 903	if (lock->lk_is_new)
 904		return nfsd4_decode_open_to_lock_owner4(argp, lock);
 905	return nfsd4_decode_exist_lock_owner4(argp, lock);
 906}
 907
 908static __be32
 909nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 910{
 911	if (xdr_stream_decode_u32(argp->xdr, &lock->lk_type) < 0)
 912		return nfserr_bad_xdr;
 
 
 
 
 
 
 913	if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
 914		return nfserr_bad_xdr;
 915	if (xdr_stream_decode_bool(argp->xdr, &lock->lk_reclaim) < 0)
 916		return nfserr_bad_xdr;
 917	if (xdr_stream_decode_u64(argp->xdr, &lock->lk_offset) < 0)
 918		return nfserr_bad_xdr;
 919	if (xdr_stream_decode_u64(argp->xdr, &lock->lk_length) < 0)
 920		return nfserr_bad_xdr;
 921	return nfsd4_decode_locker4(argp, lock);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 922}
 923
 924static __be32
 925nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 926{
 927	if (xdr_stream_decode_u32(argp->xdr, &lockt->lt_type) < 0)
 928		return nfserr_bad_xdr;
 929	if ((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
 930		return nfserr_bad_xdr;
 931	if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_offset) < 0)
 932		return nfserr_bad_xdr;
 933	if (xdr_stream_decode_u64(argp->xdr, &lockt->lt_length) < 0)
 934		return nfserr_bad_xdr;
 935	return nfsd4_decode_state_owner4(argp, &lockt->lt_clientid,
 936					 &lockt->lt_owner);
 
 
 
 
 937}
 938
 939static __be32
 940nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 941{
 942	__be32 status;
 943
 944	if (xdr_stream_decode_u32(argp->xdr, &locku->lu_type) < 0)
 945		return nfserr_bad_xdr;
 
 946	if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
 947		return nfserr_bad_xdr;
 948	if (xdr_stream_decode_u32(argp->xdr, &locku->lu_seqid) < 0)
 949		return nfserr_bad_xdr;
 950	status = nfsd4_decode_stateid4(argp, &locku->lu_stateid);
 951	if (status)
 952		return status;
 953	if (xdr_stream_decode_u64(argp->xdr, &locku->lu_offset) < 0)
 954		return nfserr_bad_xdr;
 955	if (xdr_stream_decode_u64(argp->xdr, &locku->lu_length) < 0)
 956		return nfserr_bad_xdr;
 957
 958	return nfs_ok;
 959}
 960
 961static __be32
 962nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
 963{
 964	return nfsd4_decode_component4(argp, &lookup->lo_name, &lookup->lo_len);
 965}
 966
 967static __be32
 968nfsd4_decode_createhow4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 969{
 970	__be32 status;
 971
 972	if (xdr_stream_decode_u32(argp->xdr, &open->op_createmode) < 0)
 973		return nfserr_bad_xdr;
 974	switch (open->op_createmode) {
 975	case NFS4_CREATE_UNCHECKED:
 976	case NFS4_CREATE_GUARDED:
 977		status = nfsd4_decode_fattr4(argp, open->op_bmval,
 978					     ARRAY_SIZE(open->op_bmval),
 979					     &open->op_iattr, &open->op_acl,
 980					     &open->op_label, &open->op_umask);
 981		if (status)
 982			return status;
 983		break;
 984	case NFS4_CREATE_EXCLUSIVE:
 985		status = nfsd4_decode_verifier4(argp, &open->op_verf);
 986		if (status)
 987			return status;
 988		break;
 989	case NFS4_CREATE_EXCLUSIVE4_1:
 990		if (argp->minorversion < 1)
 991			return nfserr_bad_xdr;
 992		status = nfsd4_decode_verifier4(argp, &open->op_verf);
 993		if (status)
 994			return status;
 995		status = nfsd4_decode_fattr4(argp, open->op_bmval,
 996					     ARRAY_SIZE(open->op_bmval),
 997					     &open->op_iattr, &open->op_acl,
 998					     &open->op_label, &open->op_umask);
 999		if (status)
1000			return status;
1001		break;
1002	default:
1003		return nfserr_bad_xdr;
1004	}
1005
1006	return nfs_ok;
1007}
1008
1009static __be32
1010nfsd4_decode_openflag4(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
1011{
1012	__be32 status;
 
 
 
 
1013
1014	if (xdr_stream_decode_u32(argp->xdr, &open->op_create) < 0)
1015		return nfserr_bad_xdr;
 
 
 
 
 
 
 
 
 
 
1016	switch (open->op_create) {
1017	case NFS4_OPEN_NOCREATE:
1018		break;
1019	case NFS4_OPEN_CREATE:
1020		status = nfsd4_decode_createhow4(argp, open);
1021		if (status)
1022			return status;
1023		break;
1024	default:
1025		return nfserr_bad_xdr;
1026	}
1027
1028	return nfs_ok;
1029}
1030
1031static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
1032{
1033	u32 w;
1034
1035	if (xdr_stream_decode_u32(argp->xdr, &w) < 0)
1036		return nfserr_bad_xdr;
1037	*share_access = w & NFS4_SHARE_ACCESS_MASK;
1038	*deleg_want = w & NFS4_SHARE_WANT_MASK;
1039	if (deleg_when)
1040		*deleg_when = w & NFS4_SHARE_WHEN_MASK;
1041
1042	switch (w & NFS4_SHARE_ACCESS_MASK) {
1043	case NFS4_SHARE_ACCESS_READ:
1044	case NFS4_SHARE_ACCESS_WRITE:
1045	case NFS4_SHARE_ACCESS_BOTH:
1046		break;
1047	default:
1048		return nfserr_bad_xdr;
1049	}
1050	w &= ~NFS4_SHARE_ACCESS_MASK;
1051	if (!w)
1052		return nfs_ok;
1053	if (!argp->minorversion)
1054		return nfserr_bad_xdr;
1055	switch (w & NFS4_SHARE_WANT_MASK) {
1056	case NFS4_SHARE_WANT_NO_PREFERENCE:
1057	case NFS4_SHARE_WANT_READ_DELEG:
1058	case NFS4_SHARE_WANT_WRITE_DELEG:
1059	case NFS4_SHARE_WANT_ANY_DELEG:
1060	case NFS4_SHARE_WANT_NO_DELEG:
1061	case NFS4_SHARE_WANT_CANCEL:
1062		break;
1063	default:
1064		return nfserr_bad_xdr;
1065	}
1066	w &= ~NFS4_SHARE_WANT_MASK;
1067	if (!w)
1068		return nfs_ok;
1069
1070	if (!deleg_when)	/* open_downgrade */
1071		return nfserr_inval;
1072	switch (w) {
1073	case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
1074	case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
1075	case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL |
1076	      NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
1077		return nfs_ok;
1078	}
1079	return nfserr_bad_xdr;
1080}
1081
1082static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
1083{
1084	if (xdr_stream_decode_u32(argp->xdr, x) < 0)
1085		return nfserr_bad_xdr;
1086	/* Note: unlike access bits, deny bits may be zero. */
1087	if (*x & ~NFS4_SHARE_DENY_BOTH)
1088		return nfserr_bad_xdr;
1089
1090	return nfs_ok;
1091}
1092
1093static __be32
1094nfsd4_decode_open_claim4(struct nfsd4_compoundargs *argp,
1095			 struct nfsd4_open *open)
1096{
1097	__be32 status;
1098
1099	if (xdr_stream_decode_u32(argp->xdr, &open->op_claim_type) < 0)
1100		return nfserr_bad_xdr;
1101	switch (open->op_claim_type) {
1102	case NFS4_OPEN_CLAIM_NULL:
1103	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
1104		status = nfsd4_decode_component4(argp, &open->op_fname,
1105						 &open->op_fnamelen);
1106		if (status)
 
 
1107			return status;
1108		break;
1109	case NFS4_OPEN_CLAIM_PREVIOUS:
1110		if (xdr_stream_decode_u32(argp->xdr, &open->op_delegate_type) < 0)
1111			return nfserr_bad_xdr;
1112		break;
1113	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
1114		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
1115		if (status)
1116			return status;
1117		status = nfsd4_decode_component4(argp, &open->op_fname,
1118						 &open->op_fnamelen);
1119		if (status)
1120			return status;
1121		break;
1122	case NFS4_OPEN_CLAIM_FH:
1123	case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
1124		if (argp->minorversion < 1)
1125			return nfserr_bad_xdr;
1126		/* void */
1127		break;
1128	case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
1129		if (argp->minorversion < 1)
1130			return nfserr_bad_xdr;
1131		status = nfsd4_decode_stateid4(argp, &open->op_delegate_stateid);
1132		if (status)
1133			return status;
1134		break;
1135	default:
1136		return nfserr_bad_xdr;
1137	}
1138
1139	return nfs_ok;
1140}
1141
1142static __be32
1143nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
1144{
1145	__be32 status;
1146	u32 dummy;
1147
1148	memset(open->op_bmval, 0, sizeof(open->op_bmval));
1149	open->op_iattr.ia_valid = 0;
1150	open->op_openowner = NULL;
1151
1152	open->op_xdr_error = 0;
1153	if (xdr_stream_decode_u32(argp->xdr, &open->op_seqid) < 0)
1154		return nfserr_bad_xdr;
1155	/* deleg_want is ignored */
1156	status = nfsd4_decode_share_access(argp, &open->op_share_access,
1157					   &open->op_deleg_want, &dummy);
1158	if (status)
1159		return status;
1160	status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
1161	if (status)
1162		return status;
1163	status = nfsd4_decode_state_owner4(argp, &open->op_clientid,
1164					   &open->op_owner);
1165	if (status)
1166		return status;
1167	status = nfsd4_decode_openflag4(argp, open);
1168	if (status)
1169		return status;
1170	return nfsd4_decode_open_claim4(argp, open);
1171}
1172
1173static __be32
1174nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
1175{
1176	__be32 status;
1177
1178	if (argp->minorversion >= 1)
1179		return nfserr_notsupp;
1180
1181	status = nfsd4_decode_stateid4(argp, &open_conf->oc_req_stateid);
1182	if (status)
1183		return status;
1184	if (xdr_stream_decode_u32(argp->xdr, &open_conf->oc_seqid) < 0)
1185		return nfserr_bad_xdr;
1186
1187	return nfs_ok;
1188}
1189
1190static __be32
1191nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
1192{
1193	__be32 status;
1194
1195	status = nfsd4_decode_stateid4(argp, &open_down->od_stateid);
1196	if (status)
1197		return status;
1198	if (xdr_stream_decode_u32(argp->xdr, &open_down->od_seqid) < 0)
1199		return nfserr_bad_xdr;
1200	/* deleg_want is ignored */
1201	status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
1202					   &open_down->od_deleg_want, NULL);
1203	if (status)
1204		return status;
1205	return nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
 
 
 
 
 
1206}
1207
1208static __be32
1209nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
1210{
1211	__be32 *p;
1212
1213	if (xdr_stream_decode_u32(argp->xdr, &putfh->pf_fhlen) < 0)
1214		return nfserr_bad_xdr;
1215	if (putfh->pf_fhlen > NFS4_FHSIZE)
1216		return nfserr_bad_xdr;
1217	p = xdr_inline_decode(argp->xdr, putfh->pf_fhlen);
1218	if (!p)
1219		return nfserr_bad_xdr;
1220	putfh->pf_fhval = svcxdr_savemem(argp, p, putfh->pf_fhlen);
1221	if (!putfh->pf_fhval)
1222		return nfserr_jukebox;
1223
1224	return nfs_ok;
1225}
1226
1227static __be32
1228nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
1229{
1230	if (argp->minorversion == 0)
1231		return nfs_ok;
1232	return nfserr_notsupp;
1233}
1234
1235static __be32
1236nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
1237{
1238	__be32 status;
1239
1240	status = nfsd4_decode_stateid4(argp, &read->rd_stateid);
1241	if (status)
1242		return status;
1243	if (xdr_stream_decode_u64(argp->xdr, &read->rd_offset) < 0)
1244		return nfserr_bad_xdr;
1245	if (xdr_stream_decode_u32(argp->xdr, &read->rd_length) < 0)
1246		return nfserr_bad_xdr;
1247
1248	return nfs_ok;
1249}
1250
1251static __be32
1252nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
1253{
1254	__be32 status;
1255
1256	if (xdr_stream_decode_u64(argp->xdr, &readdir->rd_cookie) < 0)
1257		return nfserr_bad_xdr;
1258	status = nfsd4_decode_verifier4(argp, &readdir->rd_verf);
1259	if (status)
1260		return status;
1261	if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_dircount) < 0)
1262		return nfserr_bad_xdr;
1263	if (xdr_stream_decode_u32(argp->xdr, &readdir->rd_maxcount) < 0)
1264		return nfserr_bad_xdr;
1265	if (xdr_stream_decode_uint32_array(argp->xdr, readdir->rd_bmval,
1266					   ARRAY_SIZE(readdir->rd_bmval)) < 0)
1267		return nfserr_bad_xdr;
1268
1269	return nfs_ok;
1270}
1271
1272static __be32
1273nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
1274{
1275	return nfsd4_decode_component4(argp, &remove->rm_name, &remove->rm_namelen);
 
 
 
 
 
 
 
 
 
1276}
1277
1278static __be32
1279nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
1280{
1281	__be32 status;
1282
1283	status = nfsd4_decode_component4(argp, &rename->rn_sname, &rename->rn_snamelen);
1284	if (status)
 
 
 
 
 
 
 
 
1285		return status;
1286	return nfsd4_decode_component4(argp, &rename->rn_tname, &rename->rn_tnamelen);
 
1287}
1288
1289static __be32
1290nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
1291{
1292	return nfsd4_decode_clientid4(argp, clientid);
 
 
 
 
 
1293}
1294
1295static __be32
1296nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
1297		     struct nfsd4_secinfo *secinfo)
1298{
1299	return nfsd4_decode_component4(argp, &secinfo->si_name, &secinfo->si_namelen);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1300}
1301
1302static __be32
1303nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
1304{
1305	__be32 status;
1306
1307	status = nfsd4_decode_stateid4(argp, &setattr->sa_stateid);
1308	if (status)
1309		return status;
1310	return nfsd4_decode_fattr4(argp, setattr->sa_bmval,
1311				   ARRAY_SIZE(setattr->sa_bmval),
1312				   &setattr->sa_iattr, &setattr->sa_acl,
1313				   &setattr->sa_label, NULL);
1314}
1315
1316static __be32
1317nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
1318{
1319	__be32 *p, status;
1320
1321	if (argp->minorversion >= 1)
1322		return nfserr_notsupp;
1323
1324	status = nfsd4_decode_verifier4(argp, &setclientid->se_verf);
1325	if (status)
1326		return status;
1327	status = nfsd4_decode_opaque(argp, &setclientid->se_name);
1328	if (status)
1329		return status;
1330	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_prog) < 0)
1331		return nfserr_bad_xdr;
1332	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_netid_len) < 0)
1333		return nfserr_bad_xdr;
1334	p = xdr_inline_decode(argp->xdr, setclientid->se_callback_netid_len);
1335	if (!p)
1336		return nfserr_bad_xdr;
1337	setclientid->se_callback_netid_val = svcxdr_savemem(argp, p,
1338						setclientid->se_callback_netid_len);
1339	if (!setclientid->se_callback_netid_val)
1340		return nfserr_jukebox;
1341
1342	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_addr_len) < 0)
1343		return nfserr_bad_xdr;
1344	p = xdr_inline_decode(argp->xdr, setclientid->se_callback_addr_len);
1345	if (!p)
1346		return nfserr_bad_xdr;
1347	setclientid->se_callback_addr_val = svcxdr_savemem(argp, p,
1348						setclientid->se_callback_addr_len);
1349	if (!setclientid->se_callback_addr_val)
1350		return nfserr_jukebox;
1351	if (xdr_stream_decode_u32(argp->xdr, &setclientid->se_callback_ident) < 0)
1352		return nfserr_bad_xdr;
1353
1354	return nfs_ok;
1355}
1356
1357static __be32
1358nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
1359{
1360	__be32 status;
1361
1362	if (argp->minorversion >= 1)
1363		return nfserr_notsupp;
 
1364
1365	status = nfsd4_decode_clientid4(argp, &scd_c->sc_clientid);
1366	if (status)
1367		return status;
1368	return nfsd4_decode_verifier4(argp, &scd_c->sc_confirm);
1369}
1370
1371/* Also used for NVERIFY */
1372static __be32
1373nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
1374{
1375	__be32 *p, status;
 
 
 
 
 
 
 
 
 
 
1376
1377	status = nfsd4_decode_bitmap4(argp, verify->ve_bmval,
1378				      ARRAY_SIZE(verify->ve_bmval));
1379	if (status)
1380		return status;
1381
1382	/* For convenience's sake, we compare raw xdr'd attributes in
1383	 * nfsd4_proc_verify */
1384
1385	if (xdr_stream_decode_u32(argp->xdr, &verify->ve_attrlen) < 0)
1386		return nfserr_bad_xdr;
1387	p = xdr_inline_decode(argp->xdr, verify->ve_attrlen);
1388	if (!p)
1389		return nfserr_bad_xdr;
1390	verify->ve_attrval = svcxdr_savemem(argp, p, verify->ve_attrlen);
1391	if (!verify->ve_attrval)
1392		return nfserr_jukebox;
 
 
 
1393
1394	return nfs_ok;
1395}
1396
1397static __be32
1398nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1399{
1400	__be32 status;
1401
1402	status = nfsd4_decode_stateid4(argp, &write->wr_stateid);
1403	if (status)
1404		return status;
1405	if (xdr_stream_decode_u64(argp->xdr, &write->wr_offset) < 0)
1406		return nfserr_bad_xdr;
1407	if (xdr_stream_decode_u32(argp->xdr, &write->wr_stable_how) < 0)
1408		return nfserr_bad_xdr;
1409	if (write->wr_stable_how > NFS_FILE_SYNC)
1410		return nfserr_bad_xdr;
1411	if (xdr_stream_decode_u32(argp->xdr, &write->wr_buflen) < 0)
1412		return nfserr_bad_xdr;
1413	if (!xdr_stream_subsegment(argp->xdr, &write->wr_payload, write->wr_buflen))
1414		return nfserr_bad_xdr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1415
1416	return nfs_ok;
1417}
1418
1419static __be32
1420nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1421{
1422	__be32 status;
1423
1424	if (argp->minorversion >= 1)
1425		return nfserr_notsupp;
1426
1427	status = nfsd4_decode_state_owner4(argp, &rlockowner->rl_clientid,
1428					   &rlockowner->rl_owner);
1429	if (status)
1430		return status;
 
1431
1432	if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
1433		return nfserr_inval;
1434
1435	return nfs_ok;
1436}
1437
1438static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
1439{
1440	if (xdr_stream_decode_u32(argp->xdr, &bc->bc_cb_program) < 0)
1441		return nfserr_bad_xdr;
1442	return nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
1443}
1444
1445static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
1446{
1447	u32 use_conn_in_rdma_mode;
1448	__be32 status;
1449
1450	status = nfsd4_decode_sessionid4(argp, &bcts->sessionid);
1451	if (status)
1452		return status;
1453	if (xdr_stream_decode_u32(argp->xdr, &bcts->dir) < 0)
1454		return nfserr_bad_xdr;
1455	if (xdr_stream_decode_u32(argp->xdr, &use_conn_in_rdma_mode) < 0)
1456		return nfserr_bad_xdr;
1457
1458	return nfs_ok;
1459}
1460
1461static __be32
1462nfsd4_decode_state_protect_ops(struct nfsd4_compoundargs *argp,
1463			       struct nfsd4_exchange_id *exid)
1464{
1465	__be32 status;
1466
1467	status = nfsd4_decode_bitmap4(argp, exid->spo_must_enforce,
1468				      ARRAY_SIZE(exid->spo_must_enforce));
1469	if (status)
1470		return nfserr_bad_xdr;
1471	status = nfsd4_decode_bitmap4(argp, exid->spo_must_allow,
1472				      ARRAY_SIZE(exid->spo_must_allow));
1473	if (status)
1474		return nfserr_bad_xdr;
1475
1476	return nfs_ok;
1477}
1478
1479/*
1480 * This implementation currently does not support SP4_SSV.
1481 * This decoder simply skips over these arguments.
1482 */
1483static noinline __be32
1484nfsd4_decode_ssv_sp_parms(struct nfsd4_compoundargs *argp,
1485			  struct nfsd4_exchange_id *exid)
1486{
1487	u32 count, window, num_gss_handles;
1488	__be32 status;
1489
1490	/* ssp_ops */
1491	status = nfsd4_decode_state_protect_ops(argp, exid);
1492	if (status)
1493		return status;
1494
1495	/* ssp_hash_algs<> */
1496	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1497		return nfserr_bad_xdr;
1498	while (count--) {
1499		status = nfsd4_decode_ignored_string(argp, 0);
1500		if (status)
1501			return status;
1502	}
1503
1504	/* ssp_encr_algs<> */
1505	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1506		return nfserr_bad_xdr;
1507	while (count--) {
1508		status = nfsd4_decode_ignored_string(argp, 0);
1509		if (status)
1510			return status;
1511	}
1512
1513	if (xdr_stream_decode_u32(argp->xdr, &window) < 0)
1514		return nfserr_bad_xdr;
1515	if (xdr_stream_decode_u32(argp->xdr, &num_gss_handles) < 0)
1516		return nfserr_bad_xdr;
1517
1518	return nfs_ok;
1519}
1520
1521static __be32
1522nfsd4_decode_state_protect4_a(struct nfsd4_compoundargs *argp,
1523			      struct nfsd4_exchange_id *exid)
1524{
1525	__be32 status;
1526
1527	if (xdr_stream_decode_u32(argp->xdr, &exid->spa_how) < 0)
1528		return nfserr_bad_xdr;
 
1529	switch (exid->spa_how) {
1530	case SP4_NONE:
1531		break;
1532	case SP4_MACH_CRED:
1533		status = nfsd4_decode_state_protect_ops(argp, exid);
1534		if (status)
1535			return status;
 
 
 
 
 
 
 
 
1536		break;
1537	case SP4_SSV:
1538		status = nfsd4_decode_ssv_sp_parms(argp, exid);
1539		if (status)
1540			return status;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1541		break;
1542	default:
1543		return nfserr_bad_xdr;
1544	}
1545
1546	return nfs_ok;
1547}
1548
1549static __be32
1550nfsd4_decode_nfs_impl_id4(struct nfsd4_compoundargs *argp,
1551			  struct nfsd4_exchange_id *exid)
1552{
1553	__be32 status;
1554	u32 count;
1555
1556	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1557		return nfserr_bad_xdr;
1558	switch (count) {
1559	case 0:
1560		break;
1561	case 1:
1562		/* Note that RFC 8881 places no length limit on
1563		 * nii_domain, but this implementation permits no
1564		 * more than NFS4_OPAQUE_LIMIT bytes */
1565		status = nfsd4_decode_opaque(argp, &exid->nii_domain);
1566		if (status)
1567			return status;
1568		/* Note that RFC 8881 places no length limit on
1569		 * nii_name, but this implementation permits no
1570		 * more than NFS4_OPAQUE_LIMIT bytes */
1571		status = nfsd4_decode_opaque(argp, &exid->nii_name);
1572		if (status)
1573			return status;
1574		status = nfsd4_decode_nfstime4(argp, &exid->nii_time);
1575		if (status)
1576			return status;
1577		break;
1578	default:
1579		return nfserr_bad_xdr;
1580	}
1581
1582	return nfs_ok;
1583}
1584
1585static __be32
1586nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1587			 struct nfsd4_exchange_id *exid)
1588{
1589	__be32 status;
1590
1591	status = nfsd4_decode_verifier4(argp, &exid->verifier);
1592	if (status)
1593		return status;
1594	status = nfsd4_decode_opaque(argp, &exid->clname);
1595	if (status)
1596		return status;
1597	if (xdr_stream_decode_u32(argp->xdr, &exid->flags) < 0)
1598		return nfserr_bad_xdr;
1599	status = nfsd4_decode_state_protect4_a(argp, exid);
1600	if (status)
1601		return status;
1602	return nfsd4_decode_nfs_impl_id4(argp, exid);
1603}
1604
1605static __be32
1606nfsd4_decode_channel_attrs4(struct nfsd4_compoundargs *argp,
1607			    struct nfsd4_channel_attrs *ca)
1608{
1609	__be32 *p;
1610
1611	p = xdr_inline_decode(argp->xdr, XDR_UNIT * 7);
1612	if (!p)
1613		return nfserr_bad_xdr;
1614
1615	/* headerpadsz is ignored */
1616	p++;
1617	ca->maxreq_sz = be32_to_cpup(p++);
1618	ca->maxresp_sz = be32_to_cpup(p++);
1619	ca->maxresp_cached = be32_to_cpup(p++);
1620	ca->maxops = be32_to_cpup(p++);
1621	ca->maxreqs = be32_to_cpup(p++);
1622	ca->nr_rdma_attrs = be32_to_cpup(p);
1623	switch (ca->nr_rdma_attrs) {
1624	case 0:
1625		break;
1626	case 1:
1627		if (xdr_stream_decode_u32(argp->xdr, &ca->rdma_attrs) < 0)
1628			return nfserr_bad_xdr;
1629		break;
1630	default:
1631		return nfserr_bad_xdr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1632	}
1633
1634	return nfs_ok;
1635}
1636
1637static __be32
1638nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1639			    struct nfsd4_create_session *sess)
1640{
1641	__be32 status;
1642
1643	status = nfsd4_decode_clientid4(argp, &sess->clientid);
1644	if (status)
1645		return status;
1646	if (xdr_stream_decode_u32(argp->xdr, &sess->seqid) < 0)
1647		return nfserr_bad_xdr;
1648	if (xdr_stream_decode_u32(argp->xdr, &sess->flags) < 0)
1649		return nfserr_bad_xdr;
1650	status = nfsd4_decode_channel_attrs4(argp, &sess->fore_channel);
1651	if (status)
1652		return status;
1653	status = nfsd4_decode_channel_attrs4(argp, &sess->back_channel);
1654	if (status)
1655		return status;
1656	if (xdr_stream_decode_u32(argp->xdr, &sess->callback_prog) < 0)
1657		return nfserr_bad_xdr;
1658	status = nfsd4_decode_cb_sec(argp, &sess->cb_sec);
1659	if (status)
1660		return status;
1661
1662	return nfs_ok;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1663}
1664
1665static __be32
1666nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
1667			     struct nfsd4_destroy_session *destroy_session)
1668{
1669	return nfsd4_decode_sessionid4(argp, &destroy_session->sessionid);
 
 
 
 
1670}
1671
1672static __be32
1673nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1674			  struct nfsd4_free_stateid *free_stateid)
1675{
1676	return nfsd4_decode_stateid4(argp, &free_stateid->fr_stateid);
1677}
1678
1679#ifdef CONFIG_NFSD_PNFS
1680static __be32
1681nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
1682		struct nfsd4_getdeviceinfo *gdev)
1683{
1684	__be32 status;
1685
1686	status = nfsd4_decode_deviceid4(argp, &gdev->gd_devid);
1687	if (status)
1688		return status;
1689	if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_layout_type) < 0)
1690		return nfserr_bad_xdr;
1691	if (xdr_stream_decode_u32(argp->xdr, &gdev->gd_maxcount) < 0)
1692		return nfserr_bad_xdr;
1693	if (xdr_stream_decode_uint32_array(argp->xdr,
1694					   &gdev->gd_notify_types, 1) < 0)
1695		return nfserr_bad_xdr;
1696
1697	return nfs_ok;
1698}
1699
1700static __be32
1701nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
1702			  struct nfsd4_layoutcommit *lcp)
1703{
1704	__be32 *p, status;
1705
1706	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.offset) < 0)
1707		return nfserr_bad_xdr;
1708	if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_seg.length) < 0)
1709		return nfserr_bad_xdr;
1710	if (xdr_stream_decode_bool(argp->xdr, &lcp->lc_reclaim) < 0)
1711		return nfserr_bad_xdr;
1712	status = nfsd4_decode_stateid4(argp, &lcp->lc_sid);
1713	if (status)
1714		return status;
1715	if (xdr_stream_decode_u32(argp->xdr, &lcp->lc_newoffset) < 0)
1716		return nfserr_bad_xdr;
1717	if (lcp->lc_newoffset) {
1718		if (xdr_stream_decode_u64(argp->xdr, &lcp->lc_last_wr) < 0)
1719			return nfserr_bad_xdr;
1720	} else
1721		lcp->lc_last_wr = 0;
1722	p = xdr_inline_decode(argp->xdr, XDR_UNIT);
1723	if (!p)
1724		return nfserr_bad_xdr;
1725	if (xdr_item_is_present(p)) {
1726		status = nfsd4_decode_nfstime4(argp, &lcp->lc_mtime);
1727		if (status)
1728			return status;
1729	} else {
1730		lcp->lc_mtime.tv_nsec = UTIME_NOW;
1731	}
1732	return nfsd4_decode_layoutupdate4(argp, lcp);
1733}
1734
1735static __be32
1736nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
1737		struct nfsd4_layoutget *lgp)
1738{
1739	__be32 status;
1740
1741	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_signal) < 0)
1742		return nfserr_bad_xdr;
1743	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_layout_type) < 0)
1744		return nfserr_bad_xdr;
1745	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_seg.iomode) < 0)
1746		return nfserr_bad_xdr;
1747	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.offset) < 0)
1748		return nfserr_bad_xdr;
1749	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_seg.length) < 0)
1750		return nfserr_bad_xdr;
1751	if (xdr_stream_decode_u64(argp->xdr, &lgp->lg_minlength) < 0)
1752		return nfserr_bad_xdr;
1753	status = nfsd4_decode_stateid4(argp, &lgp->lg_sid);
1754	if (status)
1755		return status;
1756	if (xdr_stream_decode_u32(argp->xdr, &lgp->lg_maxcount) < 0)
1757		return nfserr_bad_xdr;
1758
1759	return nfs_ok;
1760}
1761
1762static __be32
1763nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
1764		struct nfsd4_layoutreturn *lrp)
1765{
1766	if (xdr_stream_decode_bool(argp->xdr, &lrp->lr_reclaim) < 0)
1767		return nfserr_bad_xdr;
1768	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_layout_type) < 0)
1769		return nfserr_bad_xdr;
1770	if (xdr_stream_decode_u32(argp->xdr, &lrp->lr_seg.iomode) < 0)
1771		return nfserr_bad_xdr;
1772	return nfsd4_decode_layoutreturn4(argp, lrp);
1773}
1774#endif /* CONFIG_NFSD_PNFS */
1775
1776static __be32 nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
1777					   struct nfsd4_secinfo_no_name *sin)
1778{
1779	if (xdr_stream_decode_u32(argp->xdr, &sin->sin_style) < 0)
1780		return nfserr_bad_xdr;
1781	return nfs_ok;
1782}
1783
1784static __be32
1785nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1786		      struct nfsd4_sequence *seq)
1787{
1788	__be32 *p, status;
1789
1790	status = nfsd4_decode_sessionid4(argp, &seq->sessionid);
1791	if (status)
1792		return status;
1793	p = xdr_inline_decode(argp->xdr, XDR_UNIT * 4);
1794	if (!p)
1795		return nfserr_bad_xdr;
1796	seq->seqid = be32_to_cpup(p++);
1797	seq->slotid = be32_to_cpup(p++);
1798	seq->maxslots = be32_to_cpup(p++);
1799	seq->cachethis = be32_to_cpup(p);
1800
1801	return nfs_ok;
1802}
1803
1804static __be32
1805nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1806{
1807	struct nfsd4_test_stateid_id *stateid;
1808	__be32 status;
1809	u32 i;
1810
1811	if (xdr_stream_decode_u32(argp->xdr, &test_stateid->ts_num_ids) < 0)
1812		return nfserr_bad_xdr;
1813
1814	INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
1815	for (i = 0; i < test_stateid->ts_num_ids; i++) {
1816		stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
1817		if (!stateid)
1818			return nfserrno(-ENOMEM);	/* XXX: not jukebox? */
1819		INIT_LIST_HEAD(&stateid->ts_id_list);
1820		list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
1821		status = nfsd4_decode_stateid4(argp, &stateid->ts_id_stateid);
1822		if (status)
1823			return status;
1824	}
1825
1826	return nfs_ok;
1827}
1828
1829static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp,
1830					    struct nfsd4_destroy_clientid *dc)
1831{
1832	return nfsd4_decode_clientid4(argp, &dc->clientid);
1833}
1834
1835static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp,
1836					    struct nfsd4_reclaim_complete *rc)
1837{
1838	if (xdr_stream_decode_bool(argp->xdr, &rc->rca_one_fs) < 0)
1839		return nfserr_bad_xdr;
1840	return nfs_ok;
1841}
1842
1843static __be32
1844nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
1845		       struct nfsd4_fallocate *fallocate)
1846{
1847	__be32 status;
1848
1849	status = nfsd4_decode_stateid4(argp, &fallocate->falloc_stateid);
1850	if (status)
1851		return status;
1852	if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_offset) < 0)
1853		return nfserr_bad_xdr;
1854	if (xdr_stream_decode_u64(argp->xdr, &fallocate->falloc_length) < 0)
1855		return nfserr_bad_xdr;
1856
1857	return nfs_ok;
1858}
1859
1860static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
1861				      struct nl4_server *ns)
1862{
1863	struct nfs42_netaddr *naddr;
1864	__be32 *p;
1865
1866	if (xdr_stream_decode_u32(argp->xdr, &ns->nl4_type) < 0)
1867		return nfserr_bad_xdr;
1868
1869	/* currently support for 1 inter-server source server */
1870	switch (ns->nl4_type) {
1871	case NL4_NETADDR:
1872		naddr = &ns->u.nl4_addr;
1873
1874		if (xdr_stream_decode_u32(argp->xdr, &naddr->netid_len) < 0)
1875			return nfserr_bad_xdr;
1876		if (naddr->netid_len > RPCBIND_MAXNETIDLEN)
1877			return nfserr_bad_xdr;
1878
1879		p = xdr_inline_decode(argp->xdr, naddr->netid_len);
1880		if (!p)
1881			return nfserr_bad_xdr;
1882		memcpy(naddr->netid, p, naddr->netid_len);
1883
1884		if (xdr_stream_decode_u32(argp->xdr, &naddr->addr_len) < 0)
1885			return nfserr_bad_xdr;
1886		if (naddr->addr_len > RPCBIND_MAXUADDRLEN)
1887			return nfserr_bad_xdr;
1888
1889		p = xdr_inline_decode(argp->xdr, naddr->addr_len);
1890		if (!p)
1891			return nfserr_bad_xdr;
1892		memcpy(naddr->addr, p, naddr->addr_len);
1893		break;
1894	default:
1895		return nfserr_bad_xdr;
1896	}
1897
1898	return nfs_ok;
1899}
1900
1901static __be32
1902nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
1903{
1904	struct nl4_server *ns_dummy;
1905	u32 consecutive, i, count;
1906	__be32 status;
1907
1908	status = nfsd4_decode_stateid4(argp, &copy->cp_src_stateid);
1909	if (status)
1910		return status;
1911	status = nfsd4_decode_stateid4(argp, &copy->cp_dst_stateid);
1912	if (status)
1913		return status;
1914	if (xdr_stream_decode_u64(argp->xdr, &copy->cp_src_pos) < 0)
1915		return nfserr_bad_xdr;
1916	if (xdr_stream_decode_u64(argp->xdr, &copy->cp_dst_pos) < 0)
1917		return nfserr_bad_xdr;
1918	if (xdr_stream_decode_u64(argp->xdr, &copy->cp_count) < 0)
1919		return nfserr_bad_xdr;
1920	/* ca_consecutive: we always do consecutive copies */
1921	if (xdr_stream_decode_u32(argp->xdr, &consecutive) < 0)
1922		return nfserr_bad_xdr;
1923	if (xdr_stream_decode_u32(argp->xdr, &copy->cp_synchronous) < 0)
1924		return nfserr_bad_xdr;
1925
1926	if (xdr_stream_decode_u32(argp->xdr, &count) < 0)
1927		return nfserr_bad_xdr;
1928	copy->cp_intra = false;
1929	if (count == 0) { /* intra-server copy */
1930		copy->cp_intra = true;
1931		return nfs_ok;
1932	}
1933
1934	/* decode all the supplied server addresses but use only the first */
1935	status = nfsd4_decode_nl4_server(argp, &copy->cp_src);
1936	if (status)
1937		return status;
1938
1939	ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL);
1940	if (ns_dummy == NULL)
1941		return nfserrno(-ENOMEM);	/* XXX: jukebox? */
1942	for (i = 0; i < count - 1; i++) {
1943		status = nfsd4_decode_nl4_server(argp, ns_dummy);
1944		if (status) {
1945			kfree(ns_dummy);
1946			return status;
1947		}
1948	}
1949	kfree(ns_dummy);
1950
1951	return nfs_ok;
1952}
1953
1954static __be32
1955nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
1956			 struct nfsd4_copy_notify *cn)
1957{
1958	__be32 status;
1959
1960	status = nfsd4_decode_stateid4(argp, &cn->cpn_src_stateid);
1961	if (status)
1962		return status;
1963	return nfsd4_decode_nl4_server(argp, &cn->cpn_dst);
1964}
1965
1966static __be32
1967nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
1968			    struct nfsd4_offload_status *os)
1969{
1970	return nfsd4_decode_stateid4(argp, &os->stateid);
1971}
1972
1973static __be32
1974nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
1975{
1976	__be32 status;
1977
1978	status = nfsd4_decode_stateid4(argp, &seek->seek_stateid);
1979	if (status)
1980		return status;
1981	if (xdr_stream_decode_u64(argp->xdr, &seek->seek_offset) < 0)
1982		return nfserr_bad_xdr;
1983	if (xdr_stream_decode_u32(argp->xdr, &seek->seek_whence) < 0)
1984		return nfserr_bad_xdr;
1985
1986	return nfs_ok;
1987}
1988
1989static __be32
1990nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
1991{
1992	__be32 status;
1993
1994	status = nfsd4_decode_stateid4(argp, &clone->cl_src_stateid);
1995	if (status)
1996		return status;
1997	status = nfsd4_decode_stateid4(argp, &clone->cl_dst_stateid);
1998	if (status)
1999		return status;
2000	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_src_pos) < 0)
2001		return nfserr_bad_xdr;
2002	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_dst_pos) < 0)
2003		return nfserr_bad_xdr;
2004	if (xdr_stream_decode_u64(argp->xdr, &clone->cl_count) < 0)
2005		return nfserr_bad_xdr;
2006
2007	return nfs_ok;
2008}
2009
2010/*
2011 * XDR data that is more than PAGE_SIZE in size is normally part of a
2012 * read or write. However, the size of extended attributes is limited
2013 * by the maximum request size, and then further limited by the underlying
2014 * filesystem limits. This can exceed PAGE_SIZE (currently, XATTR_SIZE_MAX
2015 * is 64k). Since there is no kvec- or page-based interface to xattrs,
2016 * and we're not dealing with contiguous pages, we need to do some copying.
2017 */
2018
2019/*
2020 * Decode data into buffer.
2021 */
2022static __be32
2023nfsd4_vbuf_from_vector(struct nfsd4_compoundargs *argp, struct xdr_buf *xdr,
2024		       char **bufp, u32 buflen)
2025{
2026	struct page **pages = xdr->pages;
2027	struct kvec *head = xdr->head;
2028	char *tmp, *dp;
2029	u32 len;
2030
2031	if (buflen <= head->iov_len) {
2032		/*
2033		 * We're in luck, the head has enough space. Just return
2034		 * the head, no need for copying.
2035		 */
2036		*bufp = head->iov_base;
2037		return 0;
2038	}
2039
2040	tmp = svcxdr_tmpalloc(argp, buflen);
2041	if (tmp == NULL)
2042		return nfserr_jukebox;
2043
2044	dp = tmp;
2045	memcpy(dp, head->iov_base, head->iov_len);
2046	buflen -= head->iov_len;
2047	dp += head->iov_len;
2048
2049	while (buflen > 0) {
2050		len = min_t(u32, buflen, PAGE_SIZE);
2051		memcpy(dp, page_address(*pages), len);
2052
2053		buflen -= len;
2054		dp += len;
2055		pages++;
2056	}
2057
2058	*bufp = tmp;
2059	return 0;
2060}
2061
2062/*
2063 * Get a user extended attribute name from the XDR buffer.
2064 * It will not have the "user." prefix, so prepend it.
2065 * Lastly, check for nul characters in the name.
2066 */
2067static __be32
2068nfsd4_decode_xattr_name(struct nfsd4_compoundargs *argp, char **namep)
2069{
2070	char *name, *sp, *dp;
2071	u32 namelen, cnt;
2072	__be32 *p;
2073
2074	if (xdr_stream_decode_u32(argp->xdr, &namelen) < 0)
2075		return nfserr_bad_xdr;
2076	if (namelen > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN))
2077		return nfserr_nametoolong;
2078	if (namelen == 0)
2079		return nfserr_bad_xdr;
2080	p = xdr_inline_decode(argp->xdr, namelen);
2081	if (!p)
2082		return nfserr_bad_xdr;
2083	name = svcxdr_tmpalloc(argp, namelen + XATTR_USER_PREFIX_LEN + 1);
2084	if (!name)
2085		return nfserr_jukebox;
2086	memcpy(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
2087
2088	/*
2089	 * Copy the extended attribute name over while checking for 0
2090	 * characters.
2091	 */
2092	sp = (char *)p;
2093	dp = name + XATTR_USER_PREFIX_LEN;
2094	cnt = namelen;
2095
2096	while (cnt-- > 0) {
2097		if (*sp == '\0')
2098			return nfserr_bad_xdr;
2099		*dp++ = *sp++;
2100	}
2101	*dp = '\0';
2102
2103	*namep = name;
2104
2105	return nfs_ok;
2106}
2107
2108/*
2109 * A GETXATTR op request comes without a length specifier. We just set the
2110 * maximum length for the reply based on XATTR_SIZE_MAX and the maximum
2111 * channel reply size. nfsd_getxattr will probe the length of the xattr,
2112 * check it against getxa_len, and allocate + return the value.
2113 */
2114static __be32
2115nfsd4_decode_getxattr(struct nfsd4_compoundargs *argp,
2116		      struct nfsd4_getxattr *getxattr)
2117{
2118	__be32 status;
2119	u32 maxcount;
2120
2121	status = nfsd4_decode_xattr_name(argp, &getxattr->getxa_name);
2122	if (status)
2123		return status;
2124
2125	maxcount = svc_max_payload(argp->rqstp);
2126	maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
2127
2128	getxattr->getxa_len = maxcount;
2129
 
 
2130	return status;
 
 
 
 
2131}
2132
2133static __be32
2134nfsd4_decode_setxattr(struct nfsd4_compoundargs *argp,
2135		      struct nfsd4_setxattr *setxattr)
2136{
2137	u32 flags, maxcount, size;
2138	__be32 status;
2139
2140	if (xdr_stream_decode_u32(argp->xdr, &flags) < 0)
2141		return nfserr_bad_xdr;
2142
2143	if (flags > SETXATTR4_REPLACE)
2144		return nfserr_inval;
2145	setxattr->setxa_flags = flags;
2146
2147	status = nfsd4_decode_xattr_name(argp, &setxattr->setxa_name);
2148	if (status)
2149		return status;
2150
2151	maxcount = svc_max_payload(argp->rqstp);
2152	maxcount = min_t(u32, XATTR_SIZE_MAX, maxcount);
2153
2154	if (xdr_stream_decode_u32(argp->xdr, &size) < 0)
2155		return nfserr_bad_xdr;
2156	if (size > maxcount)
2157		return nfserr_xattr2big;
2158
2159	setxattr->setxa_len = size;
2160	if (size > 0) {
2161		struct xdr_buf payload;
2162
2163		if (!xdr_stream_subsegment(argp->xdr, &payload, size))
2164			return nfserr_bad_xdr;
2165		status = nfsd4_vbuf_from_vector(argp, &payload,
2166						&setxattr->setxa_buf, size);
2167	}
2168
2169	return nfs_ok;
2170}
2171
2172static __be32
2173nfsd4_decode_listxattrs(struct nfsd4_compoundargs *argp,
2174			struct nfsd4_listxattrs *listxattrs)
2175{
2176	u32 maxcount;
2177
2178	if (xdr_stream_decode_u64(argp->xdr, &listxattrs->lsxa_cookie) < 0)
2179		return nfserr_bad_xdr;
2180
2181	/*
2182	 * If the cookie  is too large to have even one user.x attribute
2183	 * plus trailing '\0' left in a maximum size buffer, it's invalid.
2184	 */
2185	if (listxattrs->lsxa_cookie >=
2186	    (XATTR_LIST_MAX / (XATTR_USER_PREFIX_LEN + 2)))
2187		return nfserr_badcookie;
2188
2189	if (xdr_stream_decode_u32(argp->xdr, &maxcount) < 0)
2190		return nfserr_bad_xdr;
2191	if (maxcount < 8)
2192		/* Always need at least 2 words (length and one character) */
2193		return nfserr_inval;
2194
2195	maxcount = min(maxcount, svc_max_payload(argp->rqstp));
2196	listxattrs->lsxa_maxcount = maxcount;
2197
2198	return nfs_ok;
2199}
2200
2201static __be32
2202nfsd4_decode_removexattr(struct nfsd4_compoundargs *argp,
2203			 struct nfsd4_removexattr *removexattr)
2204{
2205	return nfsd4_decode_xattr_name(argp, &removexattr->rmxa_name);
2206}
2207
2208static __be32
2209nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
2210{
2211	return nfs_ok;
2212}
2213
2214static __be32
2215nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
2216{
2217	return nfserr_notsupp;
2218}
2219
2220typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
2221
2222static const nfsd4_dec nfsd4_dec_ops[] = {
2223	[OP_ACCESS]		= (nfsd4_dec)nfsd4_decode_access,
2224	[OP_CLOSE]		= (nfsd4_dec)nfsd4_decode_close,
2225	[OP_COMMIT]		= (nfsd4_dec)nfsd4_decode_commit,
2226	[OP_CREATE]		= (nfsd4_dec)nfsd4_decode_create,
2227	[OP_DELEGPURGE]		= (nfsd4_dec)nfsd4_decode_notsupp,
2228	[OP_DELEGRETURN]	= (nfsd4_dec)nfsd4_decode_delegreturn,
2229	[OP_GETATTR]		= (nfsd4_dec)nfsd4_decode_getattr,
2230	[OP_GETFH]		= (nfsd4_dec)nfsd4_decode_noop,
2231	[OP_LINK]		= (nfsd4_dec)nfsd4_decode_link,
2232	[OP_LOCK]		= (nfsd4_dec)nfsd4_decode_lock,
2233	[OP_LOCKT]		= (nfsd4_dec)nfsd4_decode_lockt,
2234	[OP_LOCKU]		= (nfsd4_dec)nfsd4_decode_locku,
2235	[OP_LOOKUP]		= (nfsd4_dec)nfsd4_decode_lookup,
2236	[OP_LOOKUPP]		= (nfsd4_dec)nfsd4_decode_noop,
2237	[OP_NVERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
2238	[OP_OPEN]		= (nfsd4_dec)nfsd4_decode_open,
2239	[OP_OPENATTR]		= (nfsd4_dec)nfsd4_decode_notsupp,
2240	[OP_OPEN_CONFIRM]	= (nfsd4_dec)nfsd4_decode_open_confirm,
2241	[OP_OPEN_DOWNGRADE]	= (nfsd4_dec)nfsd4_decode_open_downgrade,
2242	[OP_PUTFH]		= (nfsd4_dec)nfsd4_decode_putfh,
2243	[OP_PUTPUBFH]		= (nfsd4_dec)nfsd4_decode_putpubfh,
2244	[OP_PUTROOTFH]		= (nfsd4_dec)nfsd4_decode_noop,
2245	[OP_READ]		= (nfsd4_dec)nfsd4_decode_read,
2246	[OP_READDIR]		= (nfsd4_dec)nfsd4_decode_readdir,
2247	[OP_READLINK]		= (nfsd4_dec)nfsd4_decode_noop,
2248	[OP_REMOVE]		= (nfsd4_dec)nfsd4_decode_remove,
2249	[OP_RENAME]		= (nfsd4_dec)nfsd4_decode_rename,
2250	[OP_RENEW]		= (nfsd4_dec)nfsd4_decode_renew,
2251	[OP_RESTOREFH]		= (nfsd4_dec)nfsd4_decode_noop,
2252	[OP_SAVEFH]		= (nfsd4_dec)nfsd4_decode_noop,
2253	[OP_SECINFO]		= (nfsd4_dec)nfsd4_decode_secinfo,
2254	[OP_SETATTR]		= (nfsd4_dec)nfsd4_decode_setattr,
2255	[OP_SETCLIENTID]	= (nfsd4_dec)nfsd4_decode_setclientid,
2256	[OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
2257	[OP_VERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
2258	[OP_WRITE]		= (nfsd4_dec)nfsd4_decode_write,
2259	[OP_RELEASE_LOCKOWNER]	= (nfsd4_dec)nfsd4_decode_release_lockowner,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2260
2261	/* new operations for NFSv4.1 */
2262	[OP_BACKCHANNEL_CTL]	= (nfsd4_dec)nfsd4_decode_backchannel_ctl,
2263	[OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
2264	[OP_EXCHANGE_ID]	= (nfsd4_dec)nfsd4_decode_exchange_id,
2265	[OP_CREATE_SESSION]	= (nfsd4_dec)nfsd4_decode_create_session,
2266	[OP_DESTROY_SESSION]	= (nfsd4_dec)nfsd4_decode_destroy_session,
2267	[OP_FREE_STATEID]	= (nfsd4_dec)nfsd4_decode_free_stateid,
2268	[OP_GET_DIR_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
2269#ifdef CONFIG_NFSD_PNFS
2270	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_getdeviceinfo,
2271	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
2272	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_layoutcommit,
2273	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_layoutget,
2274	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_layoutreturn,
2275#else
2276	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_notsupp,
2277	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
2278	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_notsupp,
2279	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_notsupp,
2280	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_notsupp,
2281#endif
2282	[OP_SECINFO_NO_NAME]	= (nfsd4_dec)nfsd4_decode_secinfo_no_name,
2283	[OP_SEQUENCE]		= (nfsd4_dec)nfsd4_decode_sequence,
2284	[OP_SET_SSV]		= (nfsd4_dec)nfsd4_decode_notsupp,
2285	[OP_TEST_STATEID]	= (nfsd4_dec)nfsd4_decode_test_stateid,
2286	[OP_WANT_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
2287	[OP_DESTROY_CLIENTID]	= (nfsd4_dec)nfsd4_decode_destroy_clientid,
2288	[OP_RECLAIM_COMPLETE]	= (nfsd4_dec)nfsd4_decode_reclaim_complete,
 
2289
2290	/* new operations for NFSv4.2 */
2291	[OP_ALLOCATE]		= (nfsd4_dec)nfsd4_decode_fallocate,
2292	[OP_COPY]		= (nfsd4_dec)nfsd4_decode_copy,
2293	[OP_COPY_NOTIFY]	= (nfsd4_dec)nfsd4_decode_copy_notify,
2294	[OP_DEALLOCATE]		= (nfsd4_dec)nfsd4_decode_fallocate,
2295	[OP_IO_ADVISE]		= (nfsd4_dec)nfsd4_decode_notsupp,
2296	[OP_LAYOUTERROR]	= (nfsd4_dec)nfsd4_decode_notsupp,
2297	[OP_LAYOUTSTATS]	= (nfsd4_dec)nfsd4_decode_notsupp,
2298	[OP_OFFLOAD_CANCEL]	= (nfsd4_dec)nfsd4_decode_offload_status,
2299	[OP_OFFLOAD_STATUS]	= (nfsd4_dec)nfsd4_decode_offload_status,
2300	[OP_READ_PLUS]		= (nfsd4_dec)nfsd4_decode_read,
2301	[OP_SEEK]		= (nfsd4_dec)nfsd4_decode_seek,
2302	[OP_WRITE_SAME]		= (nfsd4_dec)nfsd4_decode_notsupp,
2303	[OP_CLONE]		= (nfsd4_dec)nfsd4_decode_clone,
2304	/* RFC 8276 extended atributes operations */
2305	[OP_GETXATTR]		= (nfsd4_dec)nfsd4_decode_getxattr,
2306	[OP_SETXATTR]		= (nfsd4_dec)nfsd4_decode_setxattr,
2307	[OP_LISTXATTRS]		= (nfsd4_dec)nfsd4_decode_listxattrs,
2308	[OP_REMOVEXATTR]	= (nfsd4_dec)nfsd4_decode_removexattr,
2309};
2310
2311static inline bool
2312nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
2313{
2314	if (op->opnum < FIRST_NFS4_OP)
2315		return false;
2316	else if (argp->minorversion == 0 && op->opnum > LAST_NFS40_OP)
2317		return false;
2318	else if (argp->minorversion == 1 && op->opnum > LAST_NFS41_OP)
2319		return false;
2320	else if (argp->minorversion == 2 && op->opnum > LAST_NFS42_OP)
2321		return false;
2322	return true;
2323}
2324
2325static int
2326nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
2327{
 
2328	struct nfsd4_op *op;
 
2329	bool cachethis = false;
2330	int auth_slack= argp->rqstp->rq_auth_slack;
2331	int max_reply = auth_slack + 8; /* opcnt, status */
2332	int readcount = 0;
2333	int readbytes = 0;
2334	__be32 *p;
2335	int i;
2336
2337	if (xdr_stream_decode_u32(argp->xdr, &argp->taglen) < 0)
2338		return 0;
2339	max_reply += XDR_UNIT;
2340	argp->tag = NULL;
2341	if (unlikely(argp->taglen)) {
2342		if (argp->taglen > NFSD4_MAX_TAGLEN)
2343			return 0;
2344		p = xdr_inline_decode(argp->xdr, argp->taglen);
2345		if (!p)
2346			return 0;
2347		argp->tag = svcxdr_savemem(argp, p, argp->taglen);
2348		if (!argp->tag)
2349			return 0;
2350		max_reply += xdr_align_size(argp->taglen);
2351	}
2352
2353	if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0)
2354		return 0;
2355	if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0)
2356		return 0;
2357
2358	/*
2359	 * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
2360	 * here, so we return success at the xdr level so that
2361	 * nfsd4_proc can handle this is an NFS-level error.
 
2362	 */
2363	if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
2364		return 1;
 
 
 
 
 
 
 
 
 
2365
2366	if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
2367		argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
2368		if (!argp->ops) {
2369			argp->ops = argp->iops;
2370			dprintk("nfsd: couldn't allocate room for COMPOUND\n");
2371			return 0;
2372		}
2373	}
2374
2375	if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
2376		argp->opcnt = 0;
2377
 
2378	for (i = 0; i < argp->opcnt; i++) {
2379		op = &argp->ops[i];
2380		op->replay = NULL;
2381
2382		if (xdr_stream_decode_u32(argp->xdr, &op->opnum) < 0)
2383			return 0;
2384		if (nfsd4_opnum_in_range(argp, op)) {
2385			op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
2386			if (op->status != nfs_ok)
2387				trace_nfsd_compound_decode_err(argp->rqstp,
2388							       argp->opcnt, i,
2389							       op->opnum,
2390							       op->status);
2391		} else {
2392			op->opnum = OP_ILLEGAL;
2393			op->status = nfserr_op_illegal;
2394		}
2395		op->opdesc = OPDESC(op);
2396		/*
2397		 * We'll try to cache the result in the DRC if any one
2398		 * op in the compound wants to be cached:
 
 
2399		 */
2400		cachethis |= nfsd4_cache_this_op(op);
2401
2402		if (op->opnum == OP_READ || op->opnum == OP_READ_PLUS) {
2403			readcount++;
2404			readbytes += nfsd4_max_reply(argp->rqstp, op);
2405		} else
2406			max_reply += nfsd4_max_reply(argp->rqstp, op);
2407		/*
2408		 * OP_LOCK and OP_LOCKT may return a conflicting lock.
2409		 * (Special case because it will just skip encoding this
2410		 * if it runs out of xdr buffer space, and it is the only
2411		 * operation that behaves this way.)
2412		 */
2413		if (op->opnum == OP_LOCK || op->opnum == OP_LOCKT)
2414			max_reply += NFS4_OPAQUE_LIMIT;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2415
2416		if (op->status) {
2417			argp->opcnt = i+1;
2418			break;
2419		}
 
 
 
 
 
2420	}
2421	/* Sessions make the DRC unnecessary: */
2422	if (argp->minorversion)
2423		cachethis = false;
2424	svc_reserve(argp->rqstp, max_reply + readbytes);
2425	argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
2426
2427	if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
2428		clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
2429
2430	return 1;
2431}
2432
2433static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
2434			     struct svc_export *exp)
 
 
 
 
 
 
 
 
 
 
2435{
2436	if (exp->ex_flags & NFSEXP_V4ROOT) {
2437		*p++ = cpu_to_be32(convert_to_wallclock(exp->cd->flush_time));
2438		*p++ = 0;
2439	} else
2440		p = xdr_encode_hyper(p, nfsd4_change_attribute(stat, inode));
2441	return p;
2442}
2443
2444/*
2445 * ctime (in NFSv4, time_metadata) is not writeable, and the client
2446 * doesn't really care what resolution could theoretically be stored by
2447 * the filesystem.
2448 *
2449 * The client cares how close together changes can be while still
2450 * guaranteeing ctime changes.  For most filesystems (which have
2451 * timestamps with nanosecond fields) that is limited by the resolution
2452 * of the time returned from current_time() (which I'm assuming to be
2453 * 1/HZ).
2454 */
2455static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
2456{
2457	struct timespec64 ts;
2458	u32 ns;
2459
2460	ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
2461	ts = ns_to_timespec64(ns);
2462
2463	p = xdr_encode_hyper(p, ts.tv_sec);
2464	*p++ = cpu_to_be32(ts.tv_nsec);
2465
2466	return p;
 
 
 
 
 
 
 
2467}
2468
2469static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
2470{
2471	*p++ = cpu_to_be32(c->atomic);
2472	p = xdr_encode_hyper(p, c->before_change);
2473	p = xdr_encode_hyper(p, c->after_change);
2474	return p;
 
 
 
 
 
 
2475}
2476
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2477/* Encode as an array of strings the string given with components
2478 * separated @sep, escaped with esc_enter and esc_exit.
2479 */
2480static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
2481					  char *components, char esc_enter,
2482					  char esc_exit)
2483{
2484	__be32 *p;
2485	__be32 pathlen;
2486	int pathlen_offset;
2487	int strlen, count=0;
2488	char *str, *end, *next;
2489
2490	dprintk("nfsd4_encode_components(%s)\n", components);
2491
2492	pathlen_offset = xdr->buf->len;
2493	p = xdr_reserve_space(xdr, 4);
2494	if (!p)
2495		return nfserr_resource;
2496	p++; /* We will fill this in with @count later */
2497
2498	end = str = components;
2499	while (*end) {
2500		bool found_esc = false;
2501
2502		/* try to parse as esc_start, ..., esc_end, sep */
2503		if (*str == esc_enter) {
2504			for (; *end && (*end != esc_exit); end++)
2505				/* find esc_exit or end of string */;
2506			next = end + 1;
2507			if (*end && (!*next || *next == sep)) {
2508				str++;
2509				found_esc = true;
2510			}
2511		}
2512
2513		if (!found_esc)
2514			for (; *end && (*end != sep); end++)
2515				/* find sep or end of string */;
2516
2517		strlen = end - str;
2518		if (strlen) {
2519			p = xdr_reserve_space(xdr, strlen + 4);
2520			if (!p)
2521				return nfserr_resource;
2522			p = xdr_encode_opaque(p, str, strlen);
 
2523			count++;
2524		}
2525		else
2526			end++;
2527		if (found_esc)
2528			end = next;
2529
2530		str = end;
2531	}
2532	pathlen = htonl(count);
2533	write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4);
 
2534	return 0;
2535}
2536
2537/* Encode as an array of strings the string given with components
2538 * separated @sep.
2539 */
2540static __be32 nfsd4_encode_components(struct xdr_stream *xdr, char sep,
2541				      char *components)
2542{
2543	return nfsd4_encode_components_esc(xdr, sep, components, 0, 0);
2544}
2545
2546/*
2547 * encode a location element of a fs_locations structure
2548 */
2549static __be32 nfsd4_encode_fs_location4(struct xdr_stream *xdr,
2550					struct nfsd4_fs_location *location)
2551{
2552	__be32 status;
 
2553
2554	status = nfsd4_encode_components_esc(xdr, ':', location->hosts,
2555						'[', ']');
2556	if (status)
2557		return status;
2558	status = nfsd4_encode_components(xdr, '/', location->path);
2559	if (status)
2560		return status;
 
2561	return 0;
2562}
2563
2564/*
2565 * Encode a path in RFC3530 'pathname4' format
 
 
2566 */
2567static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
2568				const struct path *root,
2569				const struct path *path)
2570{
2571	struct path cur = *path;
2572	__be32 *p;
2573	struct dentry **components = NULL;
2574	unsigned int ncomponents = 0;
2575	__be32 err = nfserr_jukebox;
2576
2577	dprintk("nfsd4_encode_components(");
2578
2579	path_get(&cur);
2580	/* First walk the path up to the nfsd root, and store the
2581	 * dentries/path components in an array.
2582	 */
2583	for (;;) {
2584		if (path_equal(&cur, root))
2585			break;
2586		if (cur.dentry == cur.mnt->mnt_root) {
2587			if (follow_up(&cur))
2588				continue;
2589			goto out_free;
2590		}
2591		if ((ncomponents & 15) == 0) {
2592			struct dentry **new;
2593			new = krealloc(components,
2594					sizeof(*new) * (ncomponents + 16),
2595					GFP_KERNEL);
2596			if (!new)
2597				goto out_free;
2598			components = new;
2599		}
2600		components[ncomponents++] = cur.dentry;
2601		cur.dentry = dget_parent(cur.dentry);
2602	}
2603	err = nfserr_resource;
2604	p = xdr_reserve_space(xdr, 4);
2605	if (!p)
2606		goto out_free;
2607	*p++ = cpu_to_be32(ncomponents);
2608
2609	while (ncomponents) {
2610		struct dentry *dentry = components[ncomponents - 1];
2611		unsigned int len;
2612
2613		spin_lock(&dentry->d_lock);
2614		len = dentry->d_name.len;
2615		p = xdr_reserve_space(xdr, len + 4);
2616		if (!p) {
2617			spin_unlock(&dentry->d_lock);
2618			goto out_free;
2619		}
2620		p = xdr_encode_opaque(p, dentry->d_name.name, len);
2621		dprintk("/%pd", dentry);
2622		spin_unlock(&dentry->d_lock);
2623		dput(dentry);
2624		ncomponents--;
2625	}
2626
2627	err = 0;
2628out_free:
2629	dprintk(")\n");
2630	while (ncomponents)
2631		dput(components[--ncomponents]);
2632	kfree(components);
2633	path_put(&cur);
2634	return err;
2635}
2636
2637static __be32 nfsd4_encode_fsloc_fsroot(struct xdr_stream *xdr,
2638			struct svc_rqst *rqstp, const struct path *path)
2639{
2640	struct svc_export *exp_ps;
2641	__be32 res;
2642
2643	exp_ps = rqst_find_fsidzero_export(rqstp);
2644	if (IS_ERR(exp_ps))
2645		return nfserrno(PTR_ERR(exp_ps));
2646	res = nfsd4_encode_path(xdr, &exp_ps->ex_path, path);
2647	exp_put(exp_ps);
2648	return res;
2649}
2650
2651/*
2652 *  encode a fs_locations structure
2653 */
2654static __be32 nfsd4_encode_fs_locations(struct xdr_stream *xdr,
2655			struct svc_rqst *rqstp, struct svc_export *exp)
 
2656{
2657	__be32 status;
2658	int i;
2659	__be32 *p;
2660	struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
 
2661
2662	status = nfsd4_encode_fsloc_fsroot(xdr, rqstp, &exp->ex_path);
2663	if (status)
2664		return status;
2665	p = xdr_reserve_space(xdr, 4);
2666	if (!p)
 
 
2667		return nfserr_resource;
2668	*p++ = cpu_to_be32(fslocs->locations_count);
2669	for (i=0; i<fslocs->locations_count; i++) {
2670		status = nfsd4_encode_fs_location4(xdr, &fslocs->locations[i]);
 
2671		if (status)
2672			return status;
2673	}
 
2674	return 0;
2675}
2676
2677static u32 nfs4_file_type(umode_t mode)
 
 
 
 
 
 
 
 
 
2678{
2679	switch (mode & S_IFMT) {
2680	case S_IFIFO:	return NF4FIFO;
2681	case S_IFCHR:	return NF4CHR;
2682	case S_IFDIR:	return NF4DIR;
2683	case S_IFBLK:	return NF4BLK;
2684	case S_IFLNK:	return NF4LNK;
2685	case S_IFREG:	return NF4REG;
2686	case S_IFSOCK:	return NF4SOCK;
2687	default:	return NF4BAD;
2688	}
 
 
 
 
 
 
2689}
2690
2691static inline __be32
2692nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2693		     struct nfs4_ace *ace)
2694{
2695	if (ace->whotype != NFS4_ACL_WHO_NAMED)
2696		return nfs4_acl_write_who(xdr, ace->whotype);
2697	else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
2698		return nfsd4_encode_group(xdr, rqstp, ace->who_gid);
2699	else
2700		return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
2701}
2702
2703static inline __be32
2704nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 layout_types)
2705{
2706	__be32		*p;
2707	unsigned long	i = hweight_long(layout_types);
2708
2709	p = xdr_reserve_space(xdr, 4 + 4 * i);
2710	if (!p)
2711		return nfserr_resource;
2712
2713	*p++ = cpu_to_be32(i);
2714
2715	for (i = LAYOUT_NFSV4_1_FILES; i < LAYOUT_TYPE_MAX; ++i)
2716		if (layout_types & (1 << i))
2717			*p++ = cpu_to_be32(i);
2718
2719	return 0;
 
 
 
 
2720}
2721
2722#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
2723			      FATTR4_WORD0_RDATTR_ERROR)
2724#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
2725#define WORD2_ABSENT_FS_ATTRS 0
2726
2727#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2728static inline __be32
2729nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2730			    void *context, int len)
2731{
2732	__be32 *p;
2733
2734	p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
2735	if (!p)
2736		return nfserr_resource;
2737
2738	/*
2739	 * For now we use a 0 here to indicate the null translation; in
2740	 * the future we may place a call to translation code here.
2741	 */
2742	*p++ = cpu_to_be32(0); /* lfs */
2743	*p++ = cpu_to_be32(0); /* pi */
2744	p = xdr_encode_opaque(p, context, len);
2745	return 0;
2746}
2747#else
2748static inline __be32
2749nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2750			    void *context, int len)
2751{ return 0; }
2752#endif
2753
2754static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32 *rdattr_err)
2755{
2756	/* As per referral draft:  */
2757	if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
2758	    *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
2759		if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
2760	            *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
2761			*rdattr_err = NFSERR_MOVED;
2762		else
2763			return nfserr_moved;
2764	}
2765	*bmval0 &= WORD0_ABSENT_FS_ATTRS;
2766	*bmval1 &= WORD1_ABSENT_FS_ATTRS;
2767	*bmval2 &= WORD2_ABSENT_FS_ATTRS;
2768	return 0;
2769}
2770
2771
2772static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
2773{
2774	struct path path = exp->ex_path;
2775	int err;
2776
2777	path_get(&path);
2778	while (follow_up(&path)) {
2779		if (path.dentry != path.mnt->mnt_root)
2780			break;
2781	}
2782	err = vfs_getattr(&path, stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
2783	path_put(&path);
2784	return err;
2785}
2786
2787static __be32
2788nfsd4_encode_bitmap(struct xdr_stream *xdr, u32 bmval0, u32 bmval1, u32 bmval2)
2789{
2790	__be32 *p;
2791
2792	if (bmval2) {
2793		p = xdr_reserve_space(xdr, 16);
2794		if (!p)
2795			goto out_resource;
2796		*p++ = cpu_to_be32(3);
2797		*p++ = cpu_to_be32(bmval0);
2798		*p++ = cpu_to_be32(bmval1);
2799		*p++ = cpu_to_be32(bmval2);
2800	} else if (bmval1) {
2801		p = xdr_reserve_space(xdr, 12);
2802		if (!p)
2803			goto out_resource;
2804		*p++ = cpu_to_be32(2);
2805		*p++ = cpu_to_be32(bmval0);
2806		*p++ = cpu_to_be32(bmval1);
2807	} else {
2808		p = xdr_reserve_space(xdr, 8);
2809		if (!p)
2810			goto out_resource;
2811		*p++ = cpu_to_be32(1);
2812		*p++ = cpu_to_be32(bmval0);
2813	}
2814
2815	return 0;
2816out_resource:
2817	return nfserr_resource;
2818}
2819
2820/*
2821 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
2822 * ourselves.
 
 
 
2823 */
2824static __be32
2825nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
2826		struct svc_export *exp,
2827		struct dentry *dentry, u32 *bmval,
2828		struct svc_rqst *rqstp, int ignore_crossmnt)
2829{
2830	u32 bmval0 = bmval[0];
2831	u32 bmval1 = bmval[1];
2832	u32 bmval2 = bmval[2];
2833	struct kstat stat;
2834	struct svc_fh *tempfh = NULL;
2835	struct kstatfs statfs;
2836	__be32 *p;
2837	int starting_len = xdr->buf->len;
2838	int attrlen_offset;
2839	__be32 attrlen;
2840	u32 dummy;
2841	u64 dummy64;
2842	u32 rdattr_err = 0;
 
2843	__be32 status;
2844	int err;
 
2845	struct nfs4_acl *acl = NULL;
2846#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2847	void *context = NULL;
2848	int contextlen;
2849#endif
2850	bool contextsupport = false;
2851	struct nfsd4_compoundres *resp = rqstp->rq_resp;
2852	u32 minorversion = resp->cstate.minorversion;
2853	struct path path = {
2854		.mnt	= exp->ex_path.mnt,
2855		.dentry	= dentry,
2856	};
2857	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2858
2859	BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2860	BUG_ON(!nfsd_attrs_supported(minorversion, bmval));
 
 
2861
2862	if (exp->ex_fslocs.migrated) {
2863		status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err);
 
2864		if (status)
2865			goto out;
2866	}
2867
2868	err = vfs_getattr(&path, &stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
2869	if (err)
2870		goto out_nfserr;
2871	if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
2872			FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
2873	    (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
2874		       FATTR4_WORD1_SPACE_TOTAL))) {
2875		err = vfs_statfs(&path, &statfs);
2876		if (err)
2877			goto out_nfserr;
2878	}
2879	if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
2880		tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
2881		status = nfserr_jukebox;
2882		if (!tempfh)
2883			goto out;
2884		fh_init(tempfh, NFS4_FHSIZE);
2885		status = fh_compose(tempfh, exp, dentry, NULL);
2886		if (status)
2887			goto out;
2888		fhp = tempfh;
2889	}
2890	if (bmval0 & FATTR4_WORD0_ACL) {
 
2891		err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
2892		if (err == -EOPNOTSUPP)
2893			bmval0 &= ~FATTR4_WORD0_ACL;
2894		else if (err == -EINVAL) {
2895			status = nfserr_attrnotsupp;
2896			goto out;
2897		} else if (err != 0)
2898			goto out_nfserr;
2899	}
2900
2901#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2902	if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
2903	     bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2904		if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
2905			err = security_inode_getsecctx(d_inode(dentry),
2906						&context, &contextlen);
2907		else
2908			err = -EOPNOTSUPP;
2909		contextsupport = (err == 0);
2910		if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2911			if (err == -EOPNOTSUPP)
2912				bmval2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2913			else if (err)
 
 
 
2914				goto out_nfserr;
2915		}
2916	}
2917#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2918
2919	status = nfsd4_encode_bitmap(xdr, bmval0, bmval1, bmval2);
2920	if (status)
2921		goto out;
2922
2923	attrlen_offset = xdr->buf->len;
2924	p = xdr_reserve_space(xdr, 4);
2925	if (!p)
2926		goto out_resource;
2927	p++;                /* to be backfilled later */
 
 
 
 
 
 
 
 
 
 
 
2928
2929	if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2930		u32 supp[3];
2931
2932		memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
2933
2934		if (!IS_POSIXACL(dentry->d_inode))
2935			supp[0] &= ~FATTR4_WORD0_ACL;
2936		if (!contextsupport)
2937			supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2938		if (!supp[2]) {
2939			p = xdr_reserve_space(xdr, 12);
2940			if (!p)
2941				goto out_resource;
2942			*p++ = cpu_to_be32(2);
2943			*p++ = cpu_to_be32(supp[0]);
2944			*p++ = cpu_to_be32(supp[1]);
2945		} else {
2946			p = xdr_reserve_space(xdr, 16);
2947			if (!p)
2948				goto out_resource;
2949			*p++ = cpu_to_be32(3);
2950			*p++ = cpu_to_be32(supp[0]);
2951			*p++ = cpu_to_be32(supp[1]);
2952			*p++ = cpu_to_be32(supp[2]);
2953		}
2954	}
2955	if (bmval0 & FATTR4_WORD0_TYPE) {
2956		p = xdr_reserve_space(xdr, 4);
2957		if (!p)
2958			goto out_resource;
2959		dummy = nfs4_file_type(stat.mode);
2960		if (dummy == NF4BAD) {
2961			status = nfserr_serverfault;
2962			goto out;
2963		}
2964		*p++ = cpu_to_be32(dummy);
2965	}
2966	if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
2967		p = xdr_reserve_space(xdr, 4);
2968		if (!p)
2969			goto out_resource;
2970		if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
2971			*p++ = cpu_to_be32(NFS4_FH_PERSISTENT);
2972		else
2973			*p++ = cpu_to_be32(NFS4_FH_PERSISTENT|
2974						NFS4_FH_VOL_RENAME);
2975	}
2976	if (bmval0 & FATTR4_WORD0_CHANGE) {
2977		p = xdr_reserve_space(xdr, 8);
2978		if (!p)
2979			goto out_resource;
2980		p = encode_change(p, &stat, d_inode(dentry), exp);
2981	}
2982	if (bmval0 & FATTR4_WORD0_SIZE) {
2983		p = xdr_reserve_space(xdr, 8);
2984		if (!p)
2985			goto out_resource;
2986		p = xdr_encode_hyper(p, stat.size);
2987	}
2988	if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
2989		p = xdr_reserve_space(xdr, 4);
2990		if (!p)
2991			goto out_resource;
2992		*p++ = cpu_to_be32(1);
2993	}
2994	if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
2995		p = xdr_reserve_space(xdr, 4);
2996		if (!p)
2997			goto out_resource;
2998		*p++ = cpu_to_be32(1);
2999	}
3000	if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
3001		p = xdr_reserve_space(xdr, 4);
3002		if (!p)
3003			goto out_resource;
3004		*p++ = cpu_to_be32(0);
3005	}
3006	if (bmval0 & FATTR4_WORD0_FSID) {
3007		p = xdr_reserve_space(xdr, 16);
3008		if (!p)
3009			goto out_resource;
3010		if (exp->ex_fslocs.migrated) {
3011			p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MAJOR);
3012			p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
3013		} else switch(fsid_source(fhp)) {
3014		case FSIDSOURCE_FSID:
3015			p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
3016			p = xdr_encode_hyper(p, (u64)0);
3017			break;
3018		case FSIDSOURCE_DEV:
3019			*p++ = cpu_to_be32(0);
3020			*p++ = cpu_to_be32(MAJOR(stat.dev));
3021			*p++ = cpu_to_be32(0);
3022			*p++ = cpu_to_be32(MINOR(stat.dev));
3023			break;
3024		case FSIDSOURCE_UUID:
3025			p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
3026								EX_UUID_LEN);
3027			break;
3028		}
3029	}
3030	if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
3031		p = xdr_reserve_space(xdr, 4);
3032		if (!p)
3033			goto out_resource;
3034		*p++ = cpu_to_be32(0);
3035	}
3036	if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
3037		p = xdr_reserve_space(xdr, 4);
3038		if (!p)
3039			goto out_resource;
3040		*p++ = cpu_to_be32(nn->nfsd4_lease);
3041	}
3042	if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
3043		p = xdr_reserve_space(xdr, 4);
3044		if (!p)
3045			goto out_resource;
3046		*p++ = cpu_to_be32(rdattr_err);
3047	}
3048	if (bmval0 & FATTR4_WORD0_ACL) {
3049		struct nfs4_ace *ace;
3050
3051		if (acl == NULL) {
3052			p = xdr_reserve_space(xdr, 4);
3053			if (!p)
3054				goto out_resource;
3055
3056			*p++ = cpu_to_be32(0);
3057			goto out_acl;
3058		}
3059		p = xdr_reserve_space(xdr, 4);
3060		if (!p)
3061			goto out_resource;
3062		*p++ = cpu_to_be32(acl->naces);
3063
3064		for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
3065			p = xdr_reserve_space(xdr, 4*3);
3066			if (!p)
 
 
 
 
 
 
 
3067				goto out_resource;
3068			*p++ = cpu_to_be32(ace->type);
3069			*p++ = cpu_to_be32(ace->flag);
3070			*p++ = cpu_to_be32(ace->access_mask &
3071							NFS4_ACE_MASK_ALL);
3072			status = nfsd4_encode_aclname(xdr, rqstp, ace);
3073			if (status)
3074				goto out;
3075		}
3076	}
3077out_acl:
3078	if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
3079		p = xdr_reserve_space(xdr, 4);
3080		if (!p)
3081			goto out_resource;
3082		*p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ?
3083			ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
3084	}
3085	if (bmval0 & FATTR4_WORD0_CANSETTIME) {
3086		p = xdr_reserve_space(xdr, 4);
3087		if (!p)
3088			goto out_resource;
3089		*p++ = cpu_to_be32(1);
3090	}
3091	if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
3092		p = xdr_reserve_space(xdr, 4);
3093		if (!p)
3094			goto out_resource;
3095		*p++ = cpu_to_be32(0);
3096	}
3097	if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
3098		p = xdr_reserve_space(xdr, 4);
3099		if (!p)
3100			goto out_resource;
3101		*p++ = cpu_to_be32(1);
3102	}
3103	if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
3104		p = xdr_reserve_space(xdr, 4);
3105		if (!p)
3106			goto out_resource;
3107		*p++ = cpu_to_be32(1);
3108	}
3109	if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
3110		p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4);
3111		if (!p)
3112			goto out_resource;
3113		p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base,
3114					fhp->fh_handle.fh_size);
3115	}
3116	if (bmval0 & FATTR4_WORD0_FILEID) {
3117		p = xdr_reserve_space(xdr, 8);
3118		if (!p)
3119			goto out_resource;
3120		p = xdr_encode_hyper(p, stat.ino);
3121	}
3122	if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
3123		p = xdr_reserve_space(xdr, 8);
3124		if (!p)
3125			goto out_resource;
3126		p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
3127	}
3128	if (bmval0 & FATTR4_WORD0_FILES_FREE) {
3129		p = xdr_reserve_space(xdr, 8);
3130		if (!p)
3131			goto out_resource;
3132		p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
3133	}
3134	if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
3135		p = xdr_reserve_space(xdr, 8);
3136		if (!p)
3137			goto out_resource;
3138		p = xdr_encode_hyper(p, (u64) statfs.f_files);
3139	}
3140	if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
3141		status = nfsd4_encode_fs_locations(xdr, rqstp, exp);
 
 
3142		if (status)
3143			goto out;
3144	}
3145	if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
3146		p = xdr_reserve_space(xdr, 4);
3147		if (!p)
3148			goto out_resource;
3149		*p++ = cpu_to_be32(1);
3150	}
3151	if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
3152		p = xdr_reserve_space(xdr, 8);
3153		if (!p)
3154			goto out_resource;
3155		p = xdr_encode_hyper(p, exp->ex_path.mnt->mnt_sb->s_maxbytes);
3156	}
3157	if (bmval0 & FATTR4_WORD0_MAXLINK) {
3158		p = xdr_reserve_space(xdr, 4);
3159		if (!p)
3160			goto out_resource;
3161		*p++ = cpu_to_be32(255);
3162	}
3163	if (bmval0 & FATTR4_WORD0_MAXNAME) {
3164		p = xdr_reserve_space(xdr, 4);
3165		if (!p)
3166			goto out_resource;
3167		*p++ = cpu_to_be32(statfs.f_namelen);
3168	}
3169	if (bmval0 & FATTR4_WORD0_MAXREAD) {
3170		p = xdr_reserve_space(xdr, 8);
3171		if (!p)
3172			goto out_resource;
3173		p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
3174	}
3175	if (bmval0 & FATTR4_WORD0_MAXWRITE) {
3176		p = xdr_reserve_space(xdr, 8);
3177		if (!p)
3178			goto out_resource;
3179		p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
3180	}
3181	if (bmval1 & FATTR4_WORD1_MODE) {
3182		p = xdr_reserve_space(xdr, 4);
3183		if (!p)
3184			goto out_resource;
3185		*p++ = cpu_to_be32(stat.mode & S_IALLUGO);
3186	}
3187	if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
3188		p = xdr_reserve_space(xdr, 4);
3189		if (!p)
3190			goto out_resource;
3191		*p++ = cpu_to_be32(1);
3192	}
3193	if (bmval1 & FATTR4_WORD1_NUMLINKS) {
3194		p = xdr_reserve_space(xdr, 4);
3195		if (!p)
3196			goto out_resource;
3197		*p++ = cpu_to_be32(stat.nlink);
3198	}
3199	if (bmval1 & FATTR4_WORD1_OWNER) {
3200		status = nfsd4_encode_user(xdr, rqstp, stat.uid);
 
 
3201		if (status)
3202			goto out;
3203	}
3204	if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
3205		status = nfsd4_encode_group(xdr, rqstp, stat.gid);
 
 
3206		if (status)
3207			goto out;
3208	}
3209	if (bmval1 & FATTR4_WORD1_RAWDEV) {
3210		p = xdr_reserve_space(xdr, 8);
3211		if (!p)
3212			goto out_resource;
3213		*p++ = cpu_to_be32((u32) MAJOR(stat.rdev));
3214		*p++ = cpu_to_be32((u32) MINOR(stat.rdev));
3215	}
3216	if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
3217		p = xdr_reserve_space(xdr, 8);
3218		if (!p)
3219			goto out_resource;
3220		dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
3221		p = xdr_encode_hyper(p, dummy64);
3222	}
3223	if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
3224		p = xdr_reserve_space(xdr, 8);
3225		if (!p)
3226			goto out_resource;
3227		dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
3228		p = xdr_encode_hyper(p, dummy64);
3229	}
3230	if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
3231		p = xdr_reserve_space(xdr, 8);
3232		if (!p)
3233			goto out_resource;
3234		dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
3235		p = xdr_encode_hyper(p, dummy64);
3236	}
3237	if (bmval1 & FATTR4_WORD1_SPACE_USED) {
3238		p = xdr_reserve_space(xdr, 8);
3239		if (!p)
3240			goto out_resource;
3241		dummy64 = (u64)stat.blocks << 9;
3242		p = xdr_encode_hyper(p, dummy64);
3243	}
3244	if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
3245		p = xdr_reserve_space(xdr, 12);
3246		if (!p)
3247			goto out_resource;
3248		p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
3249		*p++ = cpu_to_be32(stat.atime.tv_nsec);
 
3250	}
3251	if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
3252		p = xdr_reserve_space(xdr, 12);
3253		if (!p)
3254			goto out_resource;
3255		p = encode_time_delta(p, d_inode(dentry));
 
 
3256	}
3257	if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
3258		p = xdr_reserve_space(xdr, 12);
3259		if (!p)
3260			goto out_resource;
3261		p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec);
3262		*p++ = cpu_to_be32(stat.ctime.tv_nsec);
 
3263	}
3264	if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
3265		p = xdr_reserve_space(xdr, 12);
3266		if (!p)
3267			goto out_resource;
3268		p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec);
3269		*p++ = cpu_to_be32(stat.mtime.tv_nsec);
 
3270	}
3271	if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
3272		struct kstat parent_stat;
3273		u64 ino = stat.ino;
3274
3275		p = xdr_reserve_space(xdr, 8);
3276		if (!p)
3277                	goto out_resource;
3278		/*
3279		 * Get parent's attributes if not ignoring crossmount
3280		 * and this is the root of a cross-mounted filesystem.
3281		 */
3282		if (ignore_crossmnt == 0 &&
3283		    dentry == exp->ex_path.mnt->mnt_root) {
3284			err = get_parent_attributes(exp, &parent_stat);
 
 
 
 
 
 
 
3285			if (err)
3286				goto out_nfserr;
3287			ino = parent_stat.ino;
3288		}
3289		p = xdr_encode_hyper(p, ino);
3290	}
3291#ifdef CONFIG_NFSD_PNFS
3292	if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
3293		status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
3294		if (status)
3295			goto out;
3296	}
3297
3298	if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
3299		status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
3300		if (status)
3301			goto out;
3302	}
3303
3304	if (bmval2 & FATTR4_WORD2_LAYOUT_BLKSIZE) {
3305		p = xdr_reserve_space(xdr, 4);
3306		if (!p)
3307			goto out_resource;
3308		*p++ = cpu_to_be32(stat.blksize);
3309	}
3310#endif /* CONFIG_NFSD_PNFS */
3311	if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
3312		u32 supp[3];
3313
3314		memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
3315		supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0;
3316		supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1;
3317		supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2;
3318
3319		status = nfsd4_encode_bitmap(xdr, supp[0], supp[1], supp[2]);
3320		if (status)
3321			goto out;
3322	}
3323
3324#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3325	if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
3326		status = nfsd4_encode_security_label(xdr, rqstp, context,
3327								contextlen);
3328		if (status)
3329			goto out;
3330	}
3331#endif
3332
3333	if (bmval2 & FATTR4_WORD2_XATTR_SUPPORT) {
3334		p = xdr_reserve_space(xdr, 4);
3335		if (!p)
3336			goto out_resource;
3337		err = xattr_supported_namespace(d_inode(dentry),
3338						XATTR_USER_PREFIX);
3339		*p++ = cpu_to_be32(err == 0);
3340	}
3341
3342	attrlen = htonl(xdr->buf->len - attrlen_offset - 4);
3343	write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4);
3344	status = nfs_ok;
3345
3346out:
3347#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3348	if (context)
3349		security_release_secctx(context, contextlen);
3350#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
3351	kfree(acl);
3352	if (tempfh) {
3353		fh_put(tempfh);
3354		kfree(tempfh);
3355	}
3356	if (status)
3357		xdr_truncate_encode(xdr, starting_len);
3358	return status;
3359out_nfserr:
3360	status = nfserrno(err);
3361	goto out;
3362out_resource:
 
3363	status = nfserr_resource;
3364	goto out;
3365}
3366
3367static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr,
3368				struct xdr_buf *buf, __be32 *p, int bytes)
3369{
3370	xdr->scratch.iov_len = 0;
3371	memset(buf, 0, sizeof(struct xdr_buf));
3372	buf->head[0].iov_base = p;
3373	buf->head[0].iov_len = 0;
3374	buf->len = 0;
3375	xdr->buf = buf;
3376	xdr->iov = buf->head;
3377	xdr->p = p;
3378	xdr->end = (void *)p + bytes;
3379	buf->buflen = bytes;
3380}
3381
3382__be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
3383			struct svc_fh *fhp, struct svc_export *exp,
3384			struct dentry *dentry, u32 *bmval,
3385			struct svc_rqst *rqstp, int ignore_crossmnt)
3386{
3387	struct xdr_buf dummy;
3388	struct xdr_stream xdr;
3389	__be32 ret;
3390
3391	svcxdr_init_encode_from_buffer(&xdr, &dummy, *p, words << 2);
3392	ret = nfsd4_encode_fattr(&xdr, fhp, exp, dentry, bmval, rqstp,
3393							ignore_crossmnt);
3394	*p = xdr.p;
3395	return ret;
3396}
3397
3398static inline int attributes_need_mount(u32 *bmval)
3399{
3400	if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
3401		return 1;
3402	if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
3403		return 1;
3404	return 0;
3405}
3406
3407static __be32
3408nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
3409			const char *name, int namlen)
3410{
3411	struct svc_export *exp = cd->rd_fhp->fh_export;
3412	struct dentry *dentry;
3413	__be32 nfserr;
3414	int ignore_crossmnt = 0;
3415
3416	dentry = lookup_positive_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
3417	if (IS_ERR(dentry))
3418		return nfserrno(PTR_ERR(dentry));
 
 
 
 
 
 
 
 
 
3419
3420	exp_get(exp);
3421	/*
3422	 * In the case of a mountpoint, the client may be asking for
3423	 * attributes that are only properties of the underlying filesystem
3424	 * as opposed to the cross-mounted file system. In such a case,
3425	 * we will not follow the cross mount and will fill the attribtutes
3426	 * directly from the mountpoint dentry.
3427	 */
3428	if (nfsd_mountpoint(dentry, exp)) {
3429		int err;
3430
3431		if (!(exp->ex_flags & NFSEXP_V4ROOT)
3432				&& !attributes_need_mount(cd->rd_bmval)) {
3433			ignore_crossmnt = 1;
3434			goto out_encode;
3435		}
3436		/*
3437		 * Why the heck aren't we just using nfsd_lookup??
3438		 * Different "."/".." handling?  Something else?
3439		 * At least, add a comment here to explain....
3440		 */
3441		err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
3442		if (err) {
3443			nfserr = nfserrno(err);
3444			goto out_put;
3445		}
3446		nfserr = check_nfsd_access(exp, cd->rd_rqstp);
3447		if (nfserr)
3448			goto out_put;
3449
3450	}
3451out_encode:
3452	nfserr = nfsd4_encode_fattr(xdr, NULL, exp, dentry, cd->rd_bmval,
3453					cd->rd_rqstp, ignore_crossmnt);
3454out_put:
3455	dput(dentry);
3456	exp_put(exp);
3457	return nfserr;
3458}
3459
3460static __be32 *
3461nfsd4_encode_rdattr_error(struct xdr_stream *xdr, __be32 nfserr)
3462{
3463	__be32 *p;
3464
3465	p = xdr_reserve_space(xdr, 20);
3466	if (!p)
3467		return NULL;
3468	*p++ = htonl(2);
3469	*p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
3470	*p++ = htonl(0);			 /* bmval1 */
3471
3472	*p++ = htonl(4);     /* attribute length */
3473	*p++ = nfserr;       /* no htonl */
 
3474	return p;
3475}
3476
3477static int
3478nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
3479		    loff_t offset, u64 ino, unsigned int d_type)
3480{
3481	struct readdir_cd *ccd = ccdv;
3482	struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
3483	struct xdr_stream *xdr = cd->xdr;
3484	int start_offset = xdr->buf->len;
3485	int cookie_offset;
3486	u32 name_and_cookie;
3487	int entry_bytes;
3488	__be32 nfserr = nfserr_toosmall;
3489	__be64 wire_offset;
3490	__be32 *p;
3491
3492	/* In nfsv4, "." and ".." never make it onto the wire.. */
3493	if (name && isdotent(name, namlen)) {
3494		cd->common.err = nfs_ok;
3495		return 0;
3496	}
3497
3498	if (cd->cookie_offset) {
3499		wire_offset = cpu_to_be64(offset);
3500		write_bytes_to_xdr_buf(xdr->buf, cd->cookie_offset,
3501							&wire_offset, 8);
3502	}
3503
3504	p = xdr_reserve_space(xdr, 4);
3505	if (!p)
3506		goto fail;
 
3507	*p++ = xdr_one;                             /* mark entry present */
3508	cookie_offset = xdr->buf->len;
3509	p = xdr_reserve_space(xdr, 3*4 + namlen);
3510	if (!p)
3511		goto fail;
3512	p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
3513	p = xdr_encode_array(p, name, namlen);      /* name length & name */
3514
3515	nfserr = nfsd4_encode_dirent_fattr(xdr, cd, name, namlen);
3516	switch (nfserr) {
3517	case nfs_ok:
 
3518		break;
3519	case nfserr_resource:
3520		nfserr = nfserr_toosmall;
3521		goto fail;
3522	case nfserr_noent:
3523		xdr_truncate_encode(xdr, start_offset);
3524		goto skip_entry;
3525	default:
3526		/*
3527		 * If the client requested the RDATTR_ERROR attribute,
3528		 * we stuff the error code into this attribute
3529		 * and continue.  If this attribute was not requested,
3530		 * then in accordance with the spec, we fail the
3531		 * entire READDIR operation(!)
3532		 */
3533		if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
3534			goto fail;
3535		p = nfsd4_encode_rdattr_error(xdr, nfserr);
3536		if (p == NULL) {
3537			nfserr = nfserr_toosmall;
3538			goto fail;
3539		}
3540	}
3541	nfserr = nfserr_toosmall;
3542	entry_bytes = xdr->buf->len - start_offset;
3543	if (entry_bytes > cd->rd_maxcount)
3544		goto fail;
3545	cd->rd_maxcount -= entry_bytes;
3546	/*
3547	 * RFC 3530 14.2.24 describes rd_dircount as only a "hint", and
3548	 * notes that it could be zero. If it is zero, then the server
3549	 * should enforce only the rd_maxcount value.
3550	 */
3551	if (cd->rd_dircount) {
3552		name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
3553		if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
3554			goto fail;
3555		cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
3556		if (!cd->rd_dircount)
3557			cd->rd_maxcount = 0;
3558	}
3559
3560	cd->cookie_offset = cookie_offset;
3561skip_entry:
3562	cd->common.err = nfs_ok;
3563	return 0;
3564fail:
3565	xdr_truncate_encode(xdr, start_offset);
3566	cd->common.err = nfserr;
3567	return -EINVAL;
3568}
3569
3570static __be32
3571nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
3572{
3573	__be32 *p;
3574
3575	p = xdr_reserve_space(xdr, sizeof(stateid_t));
3576	if (!p)
3577		return nfserr_resource;
3578	*p++ = cpu_to_be32(sid->si_generation);
3579	p = xdr_encode_opaque_fixed(p, &sid->si_opaque,
3580					sizeof(stateid_opaque_t));
3581	return 0;
3582}
3583
3584static __be32
3585nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
3586{
3587	struct xdr_stream *xdr = resp->xdr;
3588	__be32 *p;
3589
3590	p = xdr_reserve_space(xdr, 8);
3591	if (!p)
3592		return nfserr_resource;
3593	*p++ = cpu_to_be32(access->ac_supported);
3594	*p++ = cpu_to_be32(access->ac_resp_access);
3595	return 0;
 
3596}
3597
3598static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
3599{
3600	struct xdr_stream *xdr = resp->xdr;
3601	__be32 *p;
3602
3603	p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
3604	if (!p)
3605		return nfserr_resource;
3606	p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
3607					NFS4_MAX_SESSIONID_LEN);
3608	*p++ = cpu_to_be32(bcts->dir);
3609	/* Upshifting from TCP to RDMA is not supported */
3610	*p++ = cpu_to_be32(0);
3611	return 0;
3612}
3613
3614static __be32
3615nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
3616{
3617	struct xdr_stream *xdr = resp->xdr;
3618
3619	return nfsd4_encode_stateid(xdr, &close->cl_stateid);
 
 
 
 
3620}
3621
3622
3623static __be32
3624nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
3625{
3626	struct xdr_stream *xdr = resp->xdr;
3627	__be32 *p;
3628
3629	p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
3630	if (!p)
3631		return nfserr_resource;
3632	p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
3633						NFS4_VERIFIER_SIZE);
3634	return 0;
3635}
3636
3637static __be32
3638nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
3639{
3640	struct xdr_stream *xdr = resp->xdr;
3641	__be32 *p;
3642
3643	p = xdr_reserve_space(xdr, 20);
3644	if (!p)
3645		return nfserr_resource;
3646	encode_cinfo(p, &create->cr_cinfo);
3647	return nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
3648			create->cr_bmval[1], create->cr_bmval[2]);
 
 
 
3649}
3650
3651static __be32
3652nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
3653{
3654	struct svc_fh *fhp = getattr->ga_fhp;
3655	struct xdr_stream *xdr = resp->xdr;
3656
3657	return nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
3658				    getattr->ga_bmval, resp->rqstp, 0);
 
 
 
 
 
 
 
 
3659}
3660
3661static __be32
3662nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
3663{
3664	struct xdr_stream *xdr = resp->xdr;
3665	struct svc_fh *fhp = *fhpp;
3666	unsigned int len;
3667	__be32 *p;
3668
3669	len = fhp->fh_handle.fh_size;
3670	p = xdr_reserve_space(xdr, len + 4);
3671	if (!p)
3672		return nfserr_resource;
3673	p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len);
3674	return 0;
 
 
3675}
3676
3677/*
3678* Including all fields other than the name, a LOCK4denied structure requires
3679*   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
3680*/
3681static __be32
3682nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
3683{
3684	struct xdr_netobj *conf = &ld->ld_owner;
3685	__be32 *p;
3686
3687again:
3688	p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
3689	if (!p) {
3690		/*
3691		 * Don't fail to return the result just because we can't
3692		 * return the conflicting open:
3693		 */
3694		if (conf->len) {
3695			kfree(conf->data);
3696			conf->len = 0;
3697			conf->data = NULL;
3698			goto again;
3699		}
3700		return nfserr_resource;
3701	}
3702	p = xdr_encode_hyper(p, ld->ld_start);
3703	p = xdr_encode_hyper(p, ld->ld_length);
3704	*p++ = cpu_to_be32(ld->ld_type);
3705	if (conf->len) {
3706		p = xdr_encode_opaque_fixed(p, &ld->ld_clientid, 8);
3707		p = xdr_encode_opaque(p, conf->data, conf->len);
3708		kfree(conf->data);
3709	}  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
3710		p = xdr_encode_hyper(p, (u64)0); /* clientid */
3711		*p++ = cpu_to_be32(0); /* length of owner name */
3712	}
3713	return nfserr_denied;
3714}
3715
3716static __be32
3717nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
3718{
3719	struct xdr_stream *xdr = resp->xdr;
3720
3721	if (!nfserr)
3722		nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
3723	else if (nfserr == nfserr_denied)
3724		nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
3725
 
3726	return nfserr;
3727}
3728
3729static __be32
3730nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
3731{
3732	struct xdr_stream *xdr = resp->xdr;
3733
3734	if (nfserr == nfserr_denied)
3735		nfsd4_encode_lock_denied(xdr, &lockt->lt_denied);
3736	return nfserr;
3737}
3738
3739static __be32
3740nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
3741{
3742	struct xdr_stream *xdr = resp->xdr;
3743
3744	return nfsd4_encode_stateid(xdr, &locku->lu_stateid);
 
 
 
 
3745}
3746
3747
3748static __be32
3749nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
3750{
3751	struct xdr_stream *xdr = resp->xdr;
3752	__be32 *p;
3753
3754	p = xdr_reserve_space(xdr, 20);
3755	if (!p)
3756		return nfserr_resource;
3757	p = encode_cinfo(p, &link->li_cinfo);
3758	return 0;
 
3759}
3760
3761
3762static __be32
3763nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
3764{
3765	struct xdr_stream *xdr = resp->xdr;
3766	__be32 *p;
 
3767
3768	nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
3769	if (nfserr)
3770		return nfserr;
3771	p = xdr_reserve_space(xdr, 24);
3772	if (!p)
3773		return nfserr_resource;
3774	p = encode_cinfo(p, &open->op_cinfo);
3775	*p++ = cpu_to_be32(open->op_rflags);
3776
3777	nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1],
3778					open->op_bmval[2]);
3779	if (nfserr)
3780		return nfserr;
3781
3782	p = xdr_reserve_space(xdr, 4);
3783	if (!p)
3784		return nfserr_resource;
 
 
 
 
 
 
3785
3786	*p++ = cpu_to_be32(open->op_delegate_type);
3787	switch (open->op_delegate_type) {
3788	case NFS4_OPEN_DELEGATE_NONE:
3789		break;
3790	case NFS4_OPEN_DELEGATE_READ:
3791		nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3792		if (nfserr)
3793			return nfserr;
3794		p = xdr_reserve_space(xdr, 20);
3795		if (!p)
3796			return nfserr_resource;
3797		*p++ = cpu_to_be32(open->op_recall);
3798
3799		/*
3800		 * TODO: ACE's in delegations
3801		 */
3802		*p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3803		*p++ = cpu_to_be32(0);
3804		*p++ = cpu_to_be32(0);
3805		*p++ = cpu_to_be32(0);   /* XXX: is NULL principal ok? */
 
3806		break;
3807	case NFS4_OPEN_DELEGATE_WRITE:
3808		nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3809		if (nfserr)
3810			return nfserr;
3811		p = xdr_reserve_space(xdr, 32);
3812		if (!p)
3813			return nfserr_resource;
3814		*p++ = cpu_to_be32(0);
3815
3816		/*
3817		 * TODO: space_limit's in delegations
3818		 */
3819		*p++ = cpu_to_be32(NFS4_LIMIT_SIZE);
3820		*p++ = cpu_to_be32(~(u32)0);
3821		*p++ = cpu_to_be32(~(u32)0);
3822
3823		/*
3824		 * TODO: ACE's in delegations
3825		 */
3826		*p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3827		*p++ = cpu_to_be32(0);
3828		*p++ = cpu_to_be32(0);
3829		*p++ = cpu_to_be32(0);   /* XXX: is NULL principal ok? */
3830		break;
3831	case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
3832		switch (open->op_why_no_deleg) {
3833		case WND4_CONTENTION:
3834		case WND4_RESOURCE:
3835			p = xdr_reserve_space(xdr, 8);
3836			if (!p)
3837				return nfserr_resource;
3838			*p++ = cpu_to_be32(open->op_why_no_deleg);
3839			/* deleg signaling not supported yet: */
3840			*p++ = cpu_to_be32(0);
3841			break;
3842		default:
3843			p = xdr_reserve_space(xdr, 4);
3844			if (!p)
3845				return nfserr_resource;
3846			*p++ = cpu_to_be32(open->op_why_no_deleg);
3847		}
3848		break;
3849	default:
3850		BUG();
3851	}
3852	/* XXX save filehandle here */
3853	return 0;
 
 
3854}
3855
3856static __be32
3857nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
3858{
3859	struct xdr_stream *xdr = resp->xdr;
 
 
 
3860
3861	return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
 
3862}
3863
3864static __be32
3865nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
3866{
3867	struct xdr_stream *xdr = resp->xdr;
3868
3869	return nfsd4_encode_stateid(xdr, &od->od_stateid);
3870}
3871
3872static __be32 nfsd4_encode_splice_read(
3873				struct nfsd4_compoundres *resp,
3874				struct nfsd4_read *read,
3875				struct file *file, unsigned long maxcount)
3876{
3877	struct xdr_stream *xdr = resp->xdr;
3878	struct xdr_buf *buf = xdr->buf;
3879	int status, space_left;
3880	u32 eof;
3881	__be32 nfserr;
3882	__be32 *p = xdr->p - 2;
3883
3884	/* Make sure there will be room for padding if needed */
3885	if (xdr->end - xdr->p < 1)
3886		return nfserr_resource;
3887
3888	nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
3889				  file, read->rd_offset, &maxcount, &eof);
3890	read->rd_length = maxcount;
3891	if (nfserr)
3892		goto out_err;
3893	status = svc_encode_result_payload(read->rd_rqstp,
3894					   buf->head[0].iov_len, maxcount);
3895	if (status) {
3896		nfserr = nfserrno(status);
3897		goto out_err;
3898	}
3899
3900	*(p++) = htonl(eof);
3901	*(p++) = htonl(maxcount);
3902
3903	buf->page_len = maxcount;
3904	buf->len += maxcount;
3905	xdr->page_ptr += (buf->page_base + maxcount + PAGE_SIZE - 1)
3906							/ PAGE_SIZE;
3907
3908	/* Use rest of head for padding and remaining ops: */
3909	buf->tail[0].iov_base = xdr->p;
3910	buf->tail[0].iov_len = 0;
3911	xdr->iov = buf->tail;
3912	if (maxcount&3) {
3913		int pad = 4 - (maxcount&3);
3914
3915		*(xdr->p++) = 0;
3916
3917		buf->tail[0].iov_base += maxcount&3;
3918		buf->tail[0].iov_len = pad;
3919		buf->len += pad;
3920	}
3921
3922	space_left = min_t(int, (void *)xdr->end - (void *)xdr->p,
3923				buf->buflen - buf->len);
3924	buf->buflen = buf->len + space_left;
3925	xdr->end = (__be32 *)((void *)xdr->end + space_left);
3926
3927	return 0;
3928
3929out_err:
3930	/*
3931	 * nfsd_splice_actor may have already messed with the
3932	 * page length; reset it so as not to confuse
3933	 * xdr_truncate_encode in our caller.
3934	 */
3935	buf->page_len = 0;
3936	return nfserr;
3937}
3938
3939static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
3940				 struct nfsd4_read *read,
3941				 struct file *file, unsigned long maxcount)
3942{
3943	struct xdr_stream *xdr = resp->xdr;
3944	u32 eof;
3945	int starting_len = xdr->buf->len - 8;
3946	__be32 nfserr;
3947	__be32 tmp;
3948	int pad;
3949
3950	read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, maxcount);
3951	if (read->rd_vlen < 0)
3952		return nfserr_resource;
3953
3954	nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
3955			    resp->rqstp->rq_vec, read->rd_vlen, &maxcount,
3956			    &eof);
3957	read->rd_length = maxcount;
3958	if (nfserr)
3959		return nfserr;
3960	if (svc_encode_result_payload(resp->rqstp, starting_len + 8, maxcount))
3961		return nfserr_io;
3962	xdr_truncate_encode(xdr, starting_len + 8 + xdr_align_size(maxcount));
3963
3964	tmp = htonl(eof);
3965	write_bytes_to_xdr_buf(xdr->buf, starting_len    , &tmp, 4);
3966	tmp = htonl(maxcount);
3967	write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
3968
3969	tmp = xdr_zero;
3970	pad = (maxcount&3) ? 4 - (maxcount&3) : 0;
3971	write_bytes_to_xdr_buf(xdr->buf, starting_len + 8 + maxcount,
3972								&tmp, pad);
3973	return 0;
3974
3975}
3976
3977static __be32
3978nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3979		  struct nfsd4_read *read)
3980{
3981	unsigned long maxcount;
3982	struct xdr_stream *xdr = resp->xdr;
3983	struct file *file;
3984	int starting_len = xdr->buf->len;
3985	__be32 *p;
3986
3987	if (nfserr)
3988		return nfserr;
3989	file = read->rd_nf->nf_file;
3990
3991	p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
3992	if (!p) {
3993		WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags));
3994		return nfserr_resource;
3995	}
3996	if (resp->xdr->buf->page_len &&
3997	    test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) {
3998		WARN_ON_ONCE(1);
3999		return nfserr_resource;
4000	}
4001	xdr_commit_encode(xdr);
4002
4003	maxcount = svc_max_payload(resp->rqstp);
4004	maxcount = min_t(unsigned long, maxcount,
4005			 (xdr->buf->buflen - xdr->buf->len));
4006	maxcount = min_t(unsigned long, maxcount, read->rd_length);
4007
4008	if (file->f_op->splice_read &&
4009	    test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
4010		nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
4011	else
4012		nfserr = nfsd4_encode_readv(resp, read, file, maxcount);
4013
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4014	if (nfserr)
4015		xdr_truncate_encode(xdr, starting_len);
 
 
4016
4017	return nfserr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4018}
4019
4020static __be32
4021nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
4022{
4023	int maxcount;
4024	__be32 wire_count;
4025	int zero = 0;
4026	struct xdr_stream *xdr = resp->xdr;
4027	int length_offset = xdr->buf->len;
4028	int status;
4029	__be32 *p;
4030
4031	p = xdr_reserve_space(xdr, 4);
4032	if (!p)
 
4033		return nfserr_resource;
 
 
 
4034	maxcount = PAGE_SIZE;
 
4035
4036	p = xdr_reserve_space(xdr, maxcount);
4037	if (!p)
4038		return nfserr_resource;
4039	/*
4040	 * XXX: By default, vfs_readlink() will truncate symlinks if they
4041	 * would overflow the buffer.  Is this kosher in NFSv4?  If not, one
4042	 * easy fix is: if vfs_readlink() precisely fills the buffer, assume
4043	 * that truncation occurred, and return NFS4ERR_RESOURCE.
4044	 */
4045	nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
4046						(char *)p, &maxcount);
4047	if (nfserr == nfserr_isdir)
4048		nfserr = nfserr_inval;
4049	if (nfserr)
4050		goto out_err;
4051	status = svc_encode_result_payload(readlink->rl_rqstp, length_offset,
4052					   maxcount);
4053	if (status) {
4054		nfserr = nfserrno(status);
4055		goto out_err;
4056	}
4057
4058	wire_count = htonl(maxcount);
4059	write_bytes_to_xdr_buf(xdr->buf, length_offset, &wire_count, 4);
4060	xdr_truncate_encode(xdr, length_offset + 4 + ALIGN(maxcount, 4));
4061	if (maxcount & 3)
4062		write_bytes_to_xdr_buf(xdr->buf, length_offset + 4 + maxcount,
4063						&zero, 4 - (maxcount&3));
4064	return 0;
4065
4066out_err:
4067	xdr_truncate_encode(xdr, length_offset);
4068	return nfserr;
 
 
 
 
 
 
 
 
4069}
4070
4071static __be32
4072nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
4073{
4074	int maxcount;
4075	int bytes_left;
4076	loff_t offset;
4077	__be64 wire_offset;
4078	struct xdr_stream *xdr = resp->xdr;
4079	int starting_len = xdr->buf->len;
4080	__be32 *p;
4081
4082	p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
4083	if (!p)
 
4084		return nfserr_resource;
4085
 
 
 
4086	/* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
4087	*p++ = cpu_to_be32(0);
4088	*p++ = cpu_to_be32(0);
4089	xdr->buf->head[0].iov_len = (char *)xdr->p -
4090				    (char *)xdr->buf->head[0].iov_base;
 
 
 
 
 
4091
4092	/*
4093	 * Number of bytes left for directory entries allowing for the
4094	 * final 8 bytes of the readdir and a following failed op:
4095	 */
4096	bytes_left = xdr->buf->buflen - xdr->buf->len
4097			- COMPOUND_ERR_SLACK_SPACE - 8;
4098	if (bytes_left < 0) {
4099		nfserr = nfserr_resource;
4100		goto err_no_verf;
4101	}
4102	maxcount = svc_max_payload(resp->rqstp);
4103	maxcount = min_t(u32, readdir->rd_maxcount, maxcount);
4104	/*
4105	 * Note the rfc defines rd_maxcount as the size of the
4106	 * READDIR4resok structure, which includes the verifier above
4107	 * and the 8 bytes encoded at the end of this function:
4108	 */
4109	if (maxcount < 16) {
4110		nfserr = nfserr_toosmall;
 
4111		goto err_no_verf;
4112	}
4113	maxcount = min_t(int, maxcount-16, bytes_left);
4114
4115	/* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */
4116	if (!readdir->rd_dircount)
4117		readdir->rd_dircount = svc_max_payload(resp->rqstp);
4118
4119	readdir->xdr = xdr;
4120	readdir->rd_maxcount = maxcount;
4121	readdir->common.err = 0;
4122	readdir->cookie_offset = 0;
 
 
4123
4124	offset = readdir->rd_cookie;
4125	nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
4126			      &offset,
4127			      &readdir->common, nfsd4_encode_dirent);
4128	if (nfserr == nfs_ok &&
4129	    readdir->common.err == nfserr_toosmall &&
4130	    xdr->buf->len == starting_len + 8) {
4131		/* nothing encoded; which limit did we hit?: */
4132		if (maxcount - 16 < bytes_left)
4133			/* It was the fault of rd_maxcount: */
4134			nfserr = nfserr_toosmall;
4135		else
4136			/* We ran out of buffer space: */
4137			nfserr = nfserr_resource;
4138	}
4139	if (nfserr)
4140		goto err_no_verf;
4141
4142	if (readdir->cookie_offset) {
4143		wire_offset = cpu_to_be64(offset);
4144		write_bytes_to_xdr_buf(xdr->buf, readdir->cookie_offset,
4145							&wire_offset, 8);
4146	}
4147
4148	p = xdr_reserve_space(xdr, 8);
4149	if (!p) {
4150		WARN_ON_ONCE(1);
4151		goto err_no_verf;
4152	}
4153	*p++ = 0;	/* no more entries */
4154	*p++ = htonl(readdir->common.err == nfserr_eof);
 
 
 
 
 
 
 
 
4155
4156	return 0;
4157err_no_verf:
4158	xdr_truncate_encode(xdr, starting_len);
 
4159	return nfserr;
4160}
4161
4162static __be32
4163nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
4164{
4165	struct xdr_stream *xdr = resp->xdr;
4166	__be32 *p;
4167
4168	p = xdr_reserve_space(xdr, 20);
4169	if (!p)
4170		return nfserr_resource;
4171	p = encode_cinfo(p, &remove->rm_cinfo);
4172	return 0;
 
4173}
4174
4175static __be32
4176nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
4177{
4178	struct xdr_stream *xdr = resp->xdr;
4179	__be32 *p;
4180
4181	p = xdr_reserve_space(xdr, 40);
4182	if (!p)
4183		return nfserr_resource;
4184	p = encode_cinfo(p, &rename->rn_sinfo);
4185	p = encode_cinfo(p, &rename->rn_tinfo);
4186	return 0;
 
4187}
4188
4189static __be32
4190nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
 
4191{
4192	u32 i, nflavs, supported;
 
4193	struct exp_flavor_info *flavs;
4194	struct exp_flavor_info def_flavs[2];
4195	__be32 *p, *flavorsp;
4196	static bool report = true;
4197
 
 
4198	if (exp->ex_nflavors) {
4199		flavs = exp->ex_flavors;
4200		nflavs = exp->ex_nflavors;
4201	} else { /* Handling of some defaults in absence of real secinfo: */
4202		flavs = def_flavs;
4203		if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
4204			nflavs = 2;
4205			flavs[0].pseudoflavor = RPC_AUTH_UNIX;
4206			flavs[1].pseudoflavor = RPC_AUTH_NULL;
4207		} else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
4208			nflavs = 1;
4209			flavs[0].pseudoflavor
4210					= svcauth_gss_flavor(exp->ex_client);
4211		} else {
4212			nflavs = 1;
4213			flavs[0].pseudoflavor
4214					= exp->ex_client->flavour->flavour;
4215		}
4216	}
4217
4218	supported = 0;
4219	p = xdr_reserve_space(xdr, 4);
4220	if (!p)
4221		return nfserr_resource;
4222	flavorsp = p++;		/* to be backfilled later */
4223
4224	for (i = 0; i < nflavs; i++) {
4225		rpc_authflavor_t pf = flavs[i].pseudoflavor;
4226		struct rpcsec_gss_info info;
4227
4228		if (rpcauth_get_gssinfo(pf, &info) == 0) {
4229			supported++;
4230			p = xdr_reserve_space(xdr, 4 + 4 +
4231					      XDR_LEN(info.oid.len) + 4 + 4);
4232			if (!p)
4233				return nfserr_resource;
4234			*p++ = cpu_to_be32(RPC_AUTH_GSS);
4235			p = xdr_encode_opaque(p,  info.oid.data, info.oid.len);
4236			*p++ = cpu_to_be32(info.qop);
4237			*p++ = cpu_to_be32(info.service);
4238		} else if (pf < RPC_AUTH_MAXFLAVOR) {
4239			supported++;
4240			p = xdr_reserve_space(xdr, 4);
4241			if (!p)
4242				return nfserr_resource;
4243			*p++ = cpu_to_be32(pf);
4244		} else {
4245			if (report)
4246				pr_warn("NFS: SECINFO: security flavor %u "
4247					"is not supported\n", pf);
4248		}
4249	}
4250
4251	if (nflavs != supported)
4252		report = false;
4253	*flavorsp = htonl(supported);
4254	return 0;
4255}
4256
4257static __be32
4258nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
4259		     struct nfsd4_secinfo *secinfo)
4260{
4261	struct xdr_stream *xdr = resp->xdr;
4262
4263	return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp);
4264}
4265
4266static __be32
4267nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
4268		     struct nfsd4_secinfo_no_name *secinfo)
4269{
4270	struct xdr_stream *xdr = resp->xdr;
4271
4272	return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp);
4273}
4274
4275/*
4276 * The SETATTR encode routine is special -- it always encodes a bitmap,
4277 * regardless of the error status.
4278 */
4279static __be32
4280nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
4281{
4282	struct xdr_stream *xdr = resp->xdr;
4283	__be32 *p;
4284
4285	p = xdr_reserve_space(xdr, 16);
4286	if (!p)
4287		return nfserr_resource;
4288	if (nfserr) {
4289		*p++ = cpu_to_be32(3);
4290		*p++ = cpu_to_be32(0);
4291		*p++ = cpu_to_be32(0);
4292		*p++ = cpu_to_be32(0);
4293	}
4294	else {
4295		*p++ = cpu_to_be32(3);
4296		*p++ = cpu_to_be32(setattr->sa_bmval[0]);
4297		*p++ = cpu_to_be32(setattr->sa_bmval[1]);
4298		*p++ = cpu_to_be32(setattr->sa_bmval[2]);
4299	}
 
4300	return nfserr;
4301}
4302
4303static __be32
4304nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
4305{
4306	struct xdr_stream *xdr = resp->xdr;
4307	__be32 *p;
4308
4309	if (!nfserr) {
4310		p = xdr_reserve_space(xdr, 8 + NFS4_VERIFIER_SIZE);
4311		if (!p)
4312			return nfserr_resource;
4313		p = xdr_encode_opaque_fixed(p, &scd->se_clientid, 8);
4314		p = xdr_encode_opaque_fixed(p, &scd->se_confirm,
4315						NFS4_VERIFIER_SIZE);
4316	}
4317	else if (nfserr == nfserr_clid_inuse) {
4318		p = xdr_reserve_space(xdr, 8);
4319		if (!p)
4320			return nfserr_resource;
4321		*p++ = cpu_to_be32(0);
4322		*p++ = cpu_to_be32(0);
4323	}
4324	return nfserr;
4325}
4326
4327static __be32
4328nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
4329{
4330	struct xdr_stream *xdr = resp->xdr;
4331	__be32 *p;
4332
4333	p = xdr_reserve_space(xdr, 16);
4334	if (!p)
4335		return nfserr_resource;
4336	*p++ = cpu_to_be32(write->wr_bytes_written);
4337	*p++ = cpu_to_be32(write->wr_how_written);
4338	p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
4339						NFS4_VERIFIER_SIZE);
4340	return 0;
4341}
4342
4343static __be32
4344nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
4345			 struct nfsd4_exchange_id *exid)
4346{
4347	struct xdr_stream *xdr = resp->xdr;
4348	__be32 *p;
4349	char *major_id;
4350	char *server_scope;
4351	int major_id_sz;
4352	int server_scope_sz;
4353	uint64_t minor_id = 0;
4354	struct nfsd_net *nn = net_generic(SVC_NET(resp->rqstp), nfsd_net_id);
4355
4356	major_id = nn->nfsd_name;
4357	major_id_sz = strlen(nn->nfsd_name);
4358	server_scope = nn->nfsd_name;
4359	server_scope_sz = strlen(nn->nfsd_name);
 
 
 
4360
4361	p = xdr_reserve_space(xdr,
4362		8 /* eir_clientid */ +
4363		4 /* eir_sequenceid */ +
4364		4 /* eir_flags */ +
4365		4 /* spr_how */);
4366	if (!p)
4367		return nfserr_resource;
4368
4369	p = xdr_encode_opaque_fixed(p, &exid->clientid, 8);
4370	*p++ = cpu_to_be32(exid->seqid);
4371	*p++ = cpu_to_be32(exid->flags);
4372
4373	*p++ = cpu_to_be32(exid->spa_how);
4374
4375	switch (exid->spa_how) {
4376	case SP4_NONE:
4377		break;
4378	case SP4_MACH_CRED:
4379		/* spo_must_enforce bitmap: */
4380		nfserr = nfsd4_encode_bitmap(xdr,
4381					exid->spo_must_enforce[0],
4382					exid->spo_must_enforce[1],
4383					exid->spo_must_enforce[2]);
4384		if (nfserr)
4385			return nfserr;
4386		/* spo_must_allow bitmap: */
4387		nfserr = nfsd4_encode_bitmap(xdr,
4388					exid->spo_must_allow[0],
4389					exid->spo_must_allow[1],
4390					exid->spo_must_allow[2]);
4391		if (nfserr)
4392			return nfserr;
4393		break;
4394	default:
4395		WARN_ON_ONCE(1);
4396	}
4397
4398	p = xdr_reserve_space(xdr,
4399		8 /* so_minor_id */ +
4400		4 /* so_major_id.len */ +
4401		(XDR_QUADLEN(major_id_sz) * 4) +
4402		4 /* eir_server_scope.len */ +
4403		(XDR_QUADLEN(server_scope_sz) * 4) +
4404		4 /* eir_server_impl_id.count (0) */);
4405	if (!p)
4406		return nfserr_resource;
 
 
 
 
 
 
4407
4408	/* The server_owner struct */
4409	p = xdr_encode_hyper(p, minor_id);      /* Minor id */
4410	/* major id */
4411	p = xdr_encode_opaque(p, major_id, major_id_sz);
 
4412
4413	/* Server scope */
4414	p = xdr_encode_opaque(p, server_scope, server_scope_sz);
 
4415
4416	/* Implementation id */
4417	*p++ = cpu_to_be32(0);	/* zero length nfs_impl_id4 array */
 
4418	return 0;
4419}
4420
4421static __be32
4422nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
4423			    struct nfsd4_create_session *sess)
4424{
4425	struct xdr_stream *xdr = resp->xdr;
4426	__be32 *p;
4427
4428	p = xdr_reserve_space(xdr, 24);
4429	if (!p)
4430		return nfserr_resource;
4431	p = xdr_encode_opaque_fixed(p, sess->sessionid.data,
4432					NFS4_MAX_SESSIONID_LEN);
4433	*p++ = cpu_to_be32(sess->seqid);
4434	*p++ = cpu_to_be32(sess->flags);
4435
4436	p = xdr_reserve_space(xdr, 28);
4437	if (!p)
4438		return nfserr_resource;
4439	*p++ = cpu_to_be32(0); /* headerpadsz */
4440	*p++ = cpu_to_be32(sess->fore_channel.maxreq_sz);
4441	*p++ = cpu_to_be32(sess->fore_channel.maxresp_sz);
4442	*p++ = cpu_to_be32(sess->fore_channel.maxresp_cached);
4443	*p++ = cpu_to_be32(sess->fore_channel.maxops);
4444	*p++ = cpu_to_be32(sess->fore_channel.maxreqs);
4445	*p++ = cpu_to_be32(sess->fore_channel.nr_rdma_attrs);
 
 
 
 
 
4446
4447	if (sess->fore_channel.nr_rdma_attrs) {
4448		p = xdr_reserve_space(xdr, 4);
4449		if (!p)
4450			return nfserr_resource;
4451		*p++ = cpu_to_be32(sess->fore_channel.rdma_attrs);
4452	}
4453
4454	p = xdr_reserve_space(xdr, 28);
4455	if (!p)
4456		return nfserr_resource;
4457	*p++ = cpu_to_be32(0); /* headerpadsz */
4458	*p++ = cpu_to_be32(sess->back_channel.maxreq_sz);
4459	*p++ = cpu_to_be32(sess->back_channel.maxresp_sz);
4460	*p++ = cpu_to_be32(sess->back_channel.maxresp_cached);
4461	*p++ = cpu_to_be32(sess->back_channel.maxops);
4462	*p++ = cpu_to_be32(sess->back_channel.maxreqs);
4463	*p++ = cpu_to_be32(sess->back_channel.nr_rdma_attrs);
4464
4465	if (sess->back_channel.nr_rdma_attrs) {
4466		p = xdr_reserve_space(xdr, 4);
4467		if (!p)
4468			return nfserr_resource;
4469		*p++ = cpu_to_be32(sess->back_channel.rdma_attrs);
4470	}
4471	return 0;
4472}
4473
4474static __be32
4475nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
4476		      struct nfsd4_sequence *seq)
4477{
4478	struct xdr_stream *xdr = resp->xdr;
4479	__be32 *p;
4480
4481	p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
4482	if (!p)
4483		return nfserr_resource;
4484	p = xdr_encode_opaque_fixed(p, seq->sessionid.data,
4485					NFS4_MAX_SESSIONID_LEN);
4486	*p++ = cpu_to_be32(seq->seqid);
4487	*p++ = cpu_to_be32(seq->slotid);
4488	/* Note slotid's are numbered from zero: */
4489	*p++ = cpu_to_be32(seq->maxslots - 1); /* sr_highest_slotid */
4490	*p++ = cpu_to_be32(seq->maxslots - 1); /* sr_target_highest_slotid */
4491	*p++ = cpu_to_be32(seq->status_flags);
4492
4493	resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
4494	return 0;
4495}
4496
4497static __be32
4498nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
4499			  struct nfsd4_test_stateid *test_stateid)
4500{
4501	struct xdr_stream *xdr = resp->xdr;
4502	struct nfsd4_test_stateid_id *stateid, *next;
4503	__be32 *p;
4504
4505	p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
4506	if (!p)
4507		return nfserr_resource;
4508	*p++ = htonl(test_stateid->ts_num_ids);
4509
4510	list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
4511		*p++ = stateid->ts_id_status;
4512	}
4513
4514	return 0;
4515}
4516
4517#ifdef CONFIG_NFSD_PNFS
4518static __be32
4519nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
4520		struct nfsd4_getdeviceinfo *gdev)
4521{
4522	struct xdr_stream *xdr = resp->xdr;
4523	const struct nfsd4_layout_ops *ops;
4524	u32 starting_len = xdr->buf->len, needed_len;
4525	__be32 *p;
4526
4527	p = xdr_reserve_space(xdr, 4);
4528	if (!p)
4529		return nfserr_resource;
4530
4531	*p++ = cpu_to_be32(gdev->gd_layout_type);
4532
4533	/* If maxcount is 0 then just update notifications */
4534	if (gdev->gd_maxcount != 0) {
4535		ops = nfsd4_layout_ops[gdev->gd_layout_type];
4536		nfserr = ops->encode_getdeviceinfo(xdr, gdev);
4537		if (nfserr) {
4538			/*
4539			 * We don't bother to burden the layout drivers with
4540			 * enforcing gd_maxcount, just tell the client to
4541			 * come back with a bigger buffer if it's not enough.
4542			 */
4543			if (xdr->buf->len + 4 > gdev->gd_maxcount)
4544				goto toosmall;
4545			return nfserr;
4546		}
4547	}
4548
4549	if (gdev->gd_notify_types) {
4550		p = xdr_reserve_space(xdr, 4 + 4);
4551		if (!p)
4552			return nfserr_resource;
4553		*p++ = cpu_to_be32(1);			/* bitmap length */
4554		*p++ = cpu_to_be32(gdev->gd_notify_types);
4555	} else {
4556		p = xdr_reserve_space(xdr, 4);
4557		if (!p)
4558			return nfserr_resource;
4559		*p++ = 0;
4560	}
4561
4562	return 0;
4563toosmall:
4564	dprintk("%s: maxcount too small\n", __func__);
4565	needed_len = xdr->buf->len + 4 /* notifications */;
4566	xdr_truncate_encode(xdr, starting_len);
4567	p = xdr_reserve_space(xdr, 4);
4568	if (!p)
4569		return nfserr_resource;
4570	*p++ = cpu_to_be32(needed_len);
4571	return nfserr_toosmall;
4572}
4573
4574static __be32
4575nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
4576		struct nfsd4_layoutget *lgp)
4577{
4578	struct xdr_stream *xdr = resp->xdr;
4579	const struct nfsd4_layout_ops *ops;
4580	__be32 *p;
4581
4582	p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t));
4583	if (!p)
4584		return nfserr_resource;
4585
4586	*p++ = cpu_to_be32(1);	/* we always set return-on-close */
4587	*p++ = cpu_to_be32(lgp->lg_sid.si_generation);
4588	p = xdr_encode_opaque_fixed(p, &lgp->lg_sid.si_opaque,
4589				    sizeof(stateid_opaque_t));
4590
4591	*p++ = cpu_to_be32(1);	/* we always return a single layout */
4592	p = xdr_encode_hyper(p, lgp->lg_seg.offset);
4593	p = xdr_encode_hyper(p, lgp->lg_seg.length);
4594	*p++ = cpu_to_be32(lgp->lg_seg.iomode);
4595	*p++ = cpu_to_be32(lgp->lg_layout_type);
4596
4597	ops = nfsd4_layout_ops[lgp->lg_layout_type];
4598	return ops->encode_layoutget(xdr, lgp);
4599}
4600
4601static __be32
4602nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr,
4603			  struct nfsd4_layoutcommit *lcp)
4604{
4605	struct xdr_stream *xdr = resp->xdr;
4606	__be32 *p;
4607
4608	p = xdr_reserve_space(xdr, 4);
4609	if (!p)
4610		return nfserr_resource;
4611	*p++ = cpu_to_be32(lcp->lc_size_chg);
4612	if (lcp->lc_size_chg) {
4613		p = xdr_reserve_space(xdr, 8);
4614		if (!p)
4615			return nfserr_resource;
4616		p = xdr_encode_hyper(p, lcp->lc_newsize);
4617	}
4618
4619	return 0;
4620}
4621
4622static __be32
4623nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
4624		struct nfsd4_layoutreturn *lrp)
4625{
4626	struct xdr_stream *xdr = resp->xdr;
4627	__be32 *p;
4628
4629	p = xdr_reserve_space(xdr, 4);
4630	if (!p)
4631		return nfserr_resource;
4632	*p++ = cpu_to_be32(lrp->lrs_present);
4633	if (lrp->lrs_present)
4634		return nfsd4_encode_stateid(xdr, &lrp->lr_sid);
4635	return 0;
4636}
4637#endif /* CONFIG_NFSD_PNFS */
4638
4639static __be32
4640nfsd42_encode_write_res(struct nfsd4_compoundres *resp,
4641		struct nfsd42_write_res *write, bool sync)
4642{
4643	__be32 *p;
4644	p = xdr_reserve_space(resp->xdr, 4);
4645	if (!p)
4646		return nfserr_resource;
4647
4648	if (sync)
4649		*p++ = cpu_to_be32(0);
4650	else {
4651		__be32 nfserr;
4652		*p++ = cpu_to_be32(1);
4653		nfserr = nfsd4_encode_stateid(resp->xdr, &write->cb_stateid);
4654		if (nfserr)
4655			return nfserr;
4656	}
4657	p = xdr_reserve_space(resp->xdr, 8 + 4 + NFS4_VERIFIER_SIZE);
4658	if (!p)
4659		return nfserr_resource;
4660
4661	p = xdr_encode_hyper(p, write->wr_bytes_written);
4662	*p++ = cpu_to_be32(write->wr_stable_how);
4663	p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
4664				    NFS4_VERIFIER_SIZE);
4665	return nfs_ok;
4666}
4667
4668static __be32
4669nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
4670{
4671	struct xdr_stream *xdr = resp->xdr;
4672	struct nfs42_netaddr *addr;
4673	__be32 *p;
4674
4675	p = xdr_reserve_space(xdr, 4);
4676	*p++ = cpu_to_be32(ns->nl4_type);
4677
4678	switch (ns->nl4_type) {
4679	case NL4_NETADDR:
4680		addr = &ns->u.nl4_addr;
4681
4682		/* netid_len, netid, uaddr_len, uaddr (port included
4683		 * in RPCBIND_MAXUADDRLEN)
4684		 */
4685		p = xdr_reserve_space(xdr,
4686			4 /* netid len */ +
4687			(XDR_QUADLEN(addr->netid_len) * 4) +
4688			4 /* uaddr len */ +
4689			(XDR_QUADLEN(addr->addr_len) * 4));
4690		if (!p)
4691			return nfserr_resource;
4692
4693		*p++ = cpu_to_be32(addr->netid_len);
4694		p = xdr_encode_opaque_fixed(p, addr->netid,
4695					    addr->netid_len);
4696		*p++ = cpu_to_be32(addr->addr_len);
4697		p = xdr_encode_opaque_fixed(p, addr->addr,
4698					addr->addr_len);
4699		break;
4700	default:
4701		WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR);
4702		return nfserr_inval;
4703	}
4704
4705	return 0;
4706}
4707
4708static __be32
4709nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
4710		  struct nfsd4_copy *copy)
4711{
4712	__be32 *p;
4713
4714	nfserr = nfsd42_encode_write_res(resp, &copy->cp_res,
4715					 !!copy->cp_synchronous);
4716	if (nfserr)
4717		return nfserr;
4718
4719	p = xdr_reserve_space(resp->xdr, 4 + 4);
4720	*p++ = xdr_one; /* cr_consecutive */
4721	*p++ = cpu_to_be32(copy->cp_synchronous);
4722	return 0;
4723}
4724
4725static __be32
4726nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
4727			    struct nfsd4_offload_status *os)
4728{
4729	struct xdr_stream *xdr = resp->xdr;
4730	__be32 *p;
4731
4732	p = xdr_reserve_space(xdr, 8 + 4);
4733	if (!p)
4734		return nfserr_resource;
4735	p = xdr_encode_hyper(p, os->count);
4736	*p++ = cpu_to_be32(0);
4737	return nfserr;
4738}
4739
4740static __be32
4741nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp,
4742			    struct nfsd4_read *read,
4743			    unsigned long *maxcount, u32 *eof,
4744			    loff_t *pos)
4745{
4746	struct xdr_stream *xdr = resp->xdr;
4747	struct file *file = read->rd_nf->nf_file;
4748	int starting_len = xdr->buf->len;
4749	loff_t hole_pos;
4750	__be32 nfserr;
4751	__be32 *p, tmp;
4752	__be64 tmp64;
4753
4754	hole_pos = pos ? *pos : vfs_llseek(file, read->rd_offset, SEEK_HOLE);
4755	if (hole_pos > read->rd_offset)
4756		*maxcount = min_t(unsigned long, *maxcount, hole_pos - read->rd_offset);
4757	*maxcount = min_t(unsigned long, *maxcount, (xdr->buf->buflen - xdr->buf->len));
4758
4759	/* Content type, offset, byte count */
4760	p = xdr_reserve_space(xdr, 4 + 8 + 4);
4761	if (!p)
4762		return nfserr_resource;
4763
4764	read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, *maxcount);
4765	if (read->rd_vlen < 0)
4766		return nfserr_resource;
4767
4768	nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
4769			    resp->rqstp->rq_vec, read->rd_vlen, maxcount, eof);
4770	if (nfserr)
4771		return nfserr;
4772	xdr_truncate_encode(xdr, starting_len + 16 + xdr_align_size(*maxcount));
4773
4774	tmp = htonl(NFS4_CONTENT_DATA);
4775	write_bytes_to_xdr_buf(xdr->buf, starting_len,      &tmp,   4);
4776	tmp64 = cpu_to_be64(read->rd_offset);
4777	write_bytes_to_xdr_buf(xdr->buf, starting_len + 4,  &tmp64, 8);
4778	tmp = htonl(*maxcount);
4779	write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp,   4);
4780
4781	tmp = xdr_zero;
4782	write_bytes_to_xdr_buf(xdr->buf, starting_len + 16 + *maxcount, &tmp,
4783			       xdr_pad_size(*maxcount));
4784	return nfs_ok;
4785}
4786
4787static __be32
4788nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp,
4789			    struct nfsd4_read *read,
4790			    unsigned long *maxcount, u32 *eof)
4791{
4792	struct file *file = read->rd_nf->nf_file;
4793	loff_t data_pos = vfs_llseek(file, read->rd_offset, SEEK_DATA);
4794	loff_t f_size = i_size_read(file_inode(file));
4795	unsigned long count;
4796	__be32 *p;
4797
4798	if (data_pos == -ENXIO)
4799		data_pos = f_size;
4800	else if (data_pos <= read->rd_offset || (data_pos < f_size && data_pos % PAGE_SIZE))
4801		return nfsd4_encode_read_plus_data(resp, read, maxcount, eof, &f_size);
4802	count = data_pos - read->rd_offset;
4803
4804	/* Content type, offset, byte count */
4805	p = xdr_reserve_space(resp->xdr, 4 + 8 + 8);
4806	if (!p)
4807		return nfserr_resource;
4808
4809	*p++ = htonl(NFS4_CONTENT_HOLE);
4810	 p   = xdr_encode_hyper(p, read->rd_offset);
4811	 p   = xdr_encode_hyper(p, count);
4812
4813	*eof = (read->rd_offset + count) >= f_size;
4814	*maxcount = min_t(unsigned long, count, *maxcount);
4815	return nfs_ok;
4816}
4817
4818static __be32
4819nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr,
4820		       struct nfsd4_read *read)
4821{
4822	unsigned long maxcount, count;
4823	struct xdr_stream *xdr = resp->xdr;
4824	struct file *file;
4825	int starting_len = xdr->buf->len;
4826	int last_segment = xdr->buf->len;
4827	int segments = 0;
4828	__be32 *p, tmp;
4829	bool is_data;
4830	loff_t pos;
4831	u32 eof;
4832
4833	if (nfserr)
4834		return nfserr;
4835	file = read->rd_nf->nf_file;
4836
4837	/* eof flag, segment count */
4838	p = xdr_reserve_space(xdr, 4 + 4);
4839	if (!p)
4840		return nfserr_resource;
4841	xdr_commit_encode(xdr);
4842
4843	maxcount = svc_max_payload(resp->rqstp);
4844	maxcount = min_t(unsigned long, maxcount,
4845			 (xdr->buf->buflen - xdr->buf->len));
4846	maxcount = min_t(unsigned long, maxcount, read->rd_length);
4847	count    = maxcount;
4848
4849	eof = read->rd_offset >= i_size_read(file_inode(file));
4850	if (eof)
4851		goto out;
4852
4853	pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE);
4854	is_data = pos > read->rd_offset;
4855
4856	while (count > 0 && !eof) {
4857		maxcount = count;
4858		if (is_data)
4859			nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof,
4860						segments == 0 ? &pos : NULL);
4861		else
4862			nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof);
4863		if (nfserr)
4864			goto out;
4865		count -= maxcount;
4866		read->rd_offset += maxcount;
4867		is_data = !is_data;
4868		last_segment = xdr->buf->len;
4869		segments++;
4870	}
4871
4872out:
4873	if (nfserr && segments == 0)
4874		xdr_truncate_encode(xdr, starting_len);
4875	else {
4876		if (nfserr) {
4877			xdr_truncate_encode(xdr, last_segment);
4878			nfserr = nfs_ok;
4879			eof = 0;
4880		}
4881		tmp = htonl(eof);
4882		write_bytes_to_xdr_buf(xdr->buf, starting_len,     &tmp, 4);
4883		tmp = htonl(segments);
4884		write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
4885	}
4886
 
 
 
4887	return nfserr;
4888}
4889
4890static __be32
4891nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
4892			 struct nfsd4_copy_notify *cn)
4893{
4894	struct xdr_stream *xdr = resp->xdr;
4895	__be32 *p;
4896
4897	if (nfserr)
4898		return nfserr;
4899
4900	/* 8 sec, 4 nsec */
4901	p = xdr_reserve_space(xdr, 12);
4902	if (!p)
4903		return nfserr_resource;
4904
4905	/* cnr_lease_time */
4906	p = xdr_encode_hyper(p, cn->cpn_sec);
4907	*p++ = cpu_to_be32(cn->cpn_nsec);
4908
4909	/* cnr_stateid */
4910	nfserr = nfsd4_encode_stateid(xdr, &cn->cpn_cnr_stateid);
4911	if (nfserr)
4912		return nfserr;
4913
4914	/* cnr_src.nl_nsvr */
4915	p = xdr_reserve_space(xdr, 4);
4916	if (!p)
4917		return nfserr_resource;
4918
4919	*p++ = cpu_to_be32(1);
4920
4921	return nfsd42_encode_nl4_server(resp, &cn->cpn_src);
4922}
4923
4924static __be32
4925nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
4926		  struct nfsd4_seek *seek)
4927{
4928	__be32 *p;
4929
4930	p = xdr_reserve_space(resp->xdr, 4 + 8);
4931	*p++ = cpu_to_be32(seek->seek_eof);
4932	p = xdr_encode_hyper(p, seek->seek_pos);
4933
4934	return 0;
4935}
4936
4937static __be32
4938nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
4939{
4940	return nfserr;
4941}
4942
4943/*
4944 * Encode kmalloc-ed buffer in to XDR stream.
4945 */
4946static __be32
4947nfsd4_vbuf_to_stream(struct xdr_stream *xdr, char *buf, u32 buflen)
4948{
4949	u32 cplen;
4950	__be32 *p;
4951
4952	cplen = min_t(unsigned long, buflen,
4953		      ((void *)xdr->end - (void *)xdr->p));
4954	p = xdr_reserve_space(xdr, cplen);
4955	if (!p)
4956		return nfserr_resource;
4957
4958	memcpy(p, buf, cplen);
4959	buf += cplen;
4960	buflen -= cplen;
4961
4962	while (buflen) {
4963		cplen = min_t(u32, buflen, PAGE_SIZE);
4964		p = xdr_reserve_space(xdr, cplen);
4965		if (!p)
4966			return nfserr_resource;
4967
4968		memcpy(p, buf, cplen);
4969
4970		if (cplen < PAGE_SIZE) {
4971			/*
4972			 * We're done, with a length that wasn't page
4973			 * aligned, so possibly not word aligned. Pad
4974			 * any trailing bytes with 0.
4975			 */
4976			xdr_encode_opaque_fixed(p, NULL, cplen);
4977			break;
4978		}
4979
4980		buflen -= PAGE_SIZE;
4981		buf += PAGE_SIZE;
4982	}
4983
4984	return 0;
4985}
4986
4987static __be32
4988nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
4989		      struct nfsd4_getxattr *getxattr)
4990{
4991	struct xdr_stream *xdr = resp->xdr;
4992	__be32 *p, err;
4993
4994	p = xdr_reserve_space(xdr, 4);
4995	if (!p)
4996		return nfserr_resource;
4997
4998	*p = cpu_to_be32(getxattr->getxa_len);
4999
5000	if (getxattr->getxa_len == 0)
5001		return 0;
5002
5003	err = nfsd4_vbuf_to_stream(xdr, getxattr->getxa_buf,
5004				    getxattr->getxa_len);
5005
5006	kvfree(getxattr->getxa_buf);
5007
5008	return err;
5009}
5010
5011static __be32
5012nfsd4_encode_setxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
5013		      struct nfsd4_setxattr *setxattr)
5014{
5015	struct xdr_stream *xdr = resp->xdr;
5016	__be32 *p;
5017
5018	p = xdr_reserve_space(xdr, 20);
5019	if (!p)
5020		return nfserr_resource;
5021
5022	encode_cinfo(p, &setxattr->setxa_cinfo);
5023
 
 
5024	return 0;
5025}
5026
5027/*
5028 * See if there are cookie values that can be rejected outright.
5029 */
5030static __be32
5031nfsd4_listxattr_validate_cookie(struct nfsd4_listxattrs *listxattrs,
5032				u32 *offsetp)
5033{
5034	u64 cookie = listxattrs->lsxa_cookie;
5035
5036	/*
5037	 * If the cookie is larger than the maximum number we can fit
5038	 * in either the buffer we just got back from vfs_listxattr, or,
5039	 * XDR-encoded, in the return buffer, it's invalid.
5040	 */
5041	if (cookie > (listxattrs->lsxa_len) / (XATTR_USER_PREFIX_LEN + 2))
5042		return nfserr_badcookie;
5043
5044	if (cookie > (listxattrs->lsxa_maxcount /
5045		      (XDR_QUADLEN(XATTR_USER_PREFIX_LEN + 2) + 4)))
5046		return nfserr_badcookie;
5047
5048	*offsetp = (u32)cookie;
5049	return 0;
5050}
5051
5052static __be32
5053nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr,
5054			struct nfsd4_listxattrs *listxattrs)
5055{
5056	struct xdr_stream *xdr = resp->xdr;
5057	u32 cookie_offset, count_offset, eof;
5058	u32 left, xdrleft, slen, count;
5059	u32 xdrlen, offset;
5060	u64 cookie;
5061	char *sp;
5062	__be32 status, tmp;
5063	__be32 *p;
5064	u32 nuser;
5065
5066	eof = 1;
5067
5068	status = nfsd4_listxattr_validate_cookie(listxattrs, &offset);
5069	if (status)
5070		goto out;
5071
5072	/*
5073	 * Reserve space for the cookie and the name array count. Record
5074	 * the offsets to save them later.
5075	 */
5076	cookie_offset = xdr->buf->len;
5077	count_offset = cookie_offset + 8;
5078	p = xdr_reserve_space(xdr, 12);
5079	if (!p) {
5080		status = nfserr_resource;
5081		goto out;
5082	}
5083
5084	count = 0;
5085	left = listxattrs->lsxa_len;
5086	sp = listxattrs->lsxa_buf;
5087	nuser = 0;
5088
5089	xdrleft = listxattrs->lsxa_maxcount;
5090
5091	while (left > 0 && xdrleft > 0) {
5092		slen = strlen(sp);
5093
5094		/*
5095		 * Check if this is a "user." attribute, skip it if not.
5096		 */
5097		if (strncmp(sp, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
5098			goto contloop;
5099
5100		slen -= XATTR_USER_PREFIX_LEN;
5101		xdrlen = 4 + ((slen + 3) & ~3);
5102		if (xdrlen > xdrleft) {
5103			if (count == 0) {
5104				/*
5105				 * Can't even fit the first attribute name.
5106				 */
5107				status = nfserr_toosmall;
5108				goto out;
5109			}
5110			eof = 0;
5111			goto wreof;
5112		}
5113
5114		left -= XATTR_USER_PREFIX_LEN;
5115		sp += XATTR_USER_PREFIX_LEN;
5116		if (nuser++ < offset)
5117			goto contloop;
5118
5119
5120		p = xdr_reserve_space(xdr, xdrlen);
5121		if (!p) {
5122			status = nfserr_resource;
5123			goto out;
5124		}
5125
5126		xdr_encode_opaque(p, sp, slen);
 
5127
5128		xdrleft -= xdrlen;
5129		count++;
5130contloop:
5131		sp += slen + 1;
5132		left -= slen + 1;
5133	}
5134
5135	/*
5136	 * If there were user attributes to copy, but we didn't copy
5137	 * any, the offset was too large (e.g. the cookie was invalid).
5138	 */
5139	if (nuser > 0 && count == 0) {
5140		status = nfserr_badcookie;
5141		goto out;
5142	}
5143
5144wreof:
5145	p = xdr_reserve_space(xdr, 4);
5146	if (!p) {
5147		status = nfserr_resource;
5148		goto out;
 
 
5149	}
5150	*p = cpu_to_be32(eof);
5151
5152	cookie = offset + count;
5153
5154	write_bytes_to_xdr_buf(xdr->buf, cookie_offset, &cookie, 8);
5155	tmp = cpu_to_be32(count);
5156	write_bytes_to_xdr_buf(xdr->buf, count_offset, &tmp, 4);
5157out:
5158	if (listxattrs->lsxa_len)
5159		kvfree(listxattrs->lsxa_buf);
5160	return status;
5161}
5162
5163static __be32
5164nfsd4_encode_removexattr(struct nfsd4_compoundres *resp, __be32 nfserr,
5165			 struct nfsd4_removexattr *removexattr)
5166{
5167	struct xdr_stream *xdr = resp->xdr;
5168	__be32 *p;
5169
5170	p = xdr_reserve_space(xdr, 20);
5171	if (!p)
5172		return nfserr_resource;
5173
5174	p = encode_cinfo(p, &removexattr->rmxa_cinfo);
5175	return 0;
5176}
5177
5178typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
5179
5180/*
5181 * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
5182 * since we don't need to filter out obsolete ops as this is
5183 * done in the decoding phase.
5184 */
5185static const nfsd4_enc nfsd4_enc_ops[] = {
5186	[OP_ACCESS]		= (nfsd4_enc)nfsd4_encode_access,
5187	[OP_CLOSE]		= (nfsd4_enc)nfsd4_encode_close,
5188	[OP_COMMIT]		= (nfsd4_enc)nfsd4_encode_commit,
5189	[OP_CREATE]		= (nfsd4_enc)nfsd4_encode_create,
5190	[OP_DELEGPURGE]		= (nfsd4_enc)nfsd4_encode_noop,
5191	[OP_DELEGRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
5192	[OP_GETATTR]		= (nfsd4_enc)nfsd4_encode_getattr,
5193	[OP_GETFH]		= (nfsd4_enc)nfsd4_encode_getfh,
5194	[OP_LINK]		= (nfsd4_enc)nfsd4_encode_link,
5195	[OP_LOCK]		= (nfsd4_enc)nfsd4_encode_lock,
5196	[OP_LOCKT]		= (nfsd4_enc)nfsd4_encode_lockt,
5197	[OP_LOCKU]		= (nfsd4_enc)nfsd4_encode_locku,
5198	[OP_LOOKUP]		= (nfsd4_enc)nfsd4_encode_noop,
5199	[OP_LOOKUPP]		= (nfsd4_enc)nfsd4_encode_noop,
5200	[OP_NVERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
5201	[OP_OPEN]		= (nfsd4_enc)nfsd4_encode_open,
5202	[OP_OPENATTR]		= (nfsd4_enc)nfsd4_encode_noop,
5203	[OP_OPEN_CONFIRM]	= (nfsd4_enc)nfsd4_encode_open_confirm,
5204	[OP_OPEN_DOWNGRADE]	= (nfsd4_enc)nfsd4_encode_open_downgrade,
5205	[OP_PUTFH]		= (nfsd4_enc)nfsd4_encode_noop,
5206	[OP_PUTPUBFH]		= (nfsd4_enc)nfsd4_encode_noop,
5207	[OP_PUTROOTFH]		= (nfsd4_enc)nfsd4_encode_noop,
5208	[OP_READ]		= (nfsd4_enc)nfsd4_encode_read,
5209	[OP_READDIR]		= (nfsd4_enc)nfsd4_encode_readdir,
5210	[OP_READLINK]		= (nfsd4_enc)nfsd4_encode_readlink,
5211	[OP_REMOVE]		= (nfsd4_enc)nfsd4_encode_remove,
5212	[OP_RENAME]		= (nfsd4_enc)nfsd4_encode_rename,
5213	[OP_RENEW]		= (nfsd4_enc)nfsd4_encode_noop,
5214	[OP_RESTOREFH]		= (nfsd4_enc)nfsd4_encode_noop,
5215	[OP_SAVEFH]		= (nfsd4_enc)nfsd4_encode_noop,
5216	[OP_SECINFO]		= (nfsd4_enc)nfsd4_encode_secinfo,
5217	[OP_SETATTR]		= (nfsd4_enc)nfsd4_encode_setattr,
5218	[OP_SETCLIENTID]	= (nfsd4_enc)nfsd4_encode_setclientid,
5219	[OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
5220	[OP_VERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
5221	[OP_WRITE]		= (nfsd4_enc)nfsd4_encode_write,
5222	[OP_RELEASE_LOCKOWNER]	= (nfsd4_enc)nfsd4_encode_noop,
5223
5224	/* NFSv4.1 operations */
5225	[OP_BACKCHANNEL_CTL]	= (nfsd4_enc)nfsd4_encode_noop,
5226	[OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
5227	[OP_EXCHANGE_ID]	= (nfsd4_enc)nfsd4_encode_exchange_id,
5228	[OP_CREATE_SESSION]	= (nfsd4_enc)nfsd4_encode_create_session,
5229	[OP_DESTROY_SESSION]	= (nfsd4_enc)nfsd4_encode_noop,
5230	[OP_FREE_STATEID]	= (nfsd4_enc)nfsd4_encode_noop,
5231	[OP_GET_DIR_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
5232#ifdef CONFIG_NFSD_PNFS
5233	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_getdeviceinfo,
5234	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
5235	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_layoutcommit,
5236	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_layoutget,
5237	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_layoutreturn,
5238#else
5239	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_noop,
5240	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
5241	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_noop,
5242	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_noop,
5243	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
5244#endif
5245	[OP_SECINFO_NO_NAME]	= (nfsd4_enc)nfsd4_encode_secinfo_no_name,
5246	[OP_SEQUENCE]		= (nfsd4_enc)nfsd4_encode_sequence,
5247	[OP_SET_SSV]		= (nfsd4_enc)nfsd4_encode_noop,
5248	[OP_TEST_STATEID]	= (nfsd4_enc)nfsd4_encode_test_stateid,
5249	[OP_WANT_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
5250	[OP_DESTROY_CLIENTID]	= (nfsd4_enc)nfsd4_encode_noop,
5251	[OP_RECLAIM_COMPLETE]	= (nfsd4_enc)nfsd4_encode_noop,
5252
5253	/* NFSv4.2 operations */
5254	[OP_ALLOCATE]		= (nfsd4_enc)nfsd4_encode_noop,
5255	[OP_COPY]		= (nfsd4_enc)nfsd4_encode_copy,
5256	[OP_COPY_NOTIFY]	= (nfsd4_enc)nfsd4_encode_copy_notify,
5257	[OP_DEALLOCATE]		= (nfsd4_enc)nfsd4_encode_noop,
5258	[OP_IO_ADVISE]		= (nfsd4_enc)nfsd4_encode_noop,
5259	[OP_LAYOUTERROR]	= (nfsd4_enc)nfsd4_encode_noop,
5260	[OP_LAYOUTSTATS]	= (nfsd4_enc)nfsd4_encode_noop,
5261	[OP_OFFLOAD_CANCEL]	= (nfsd4_enc)nfsd4_encode_noop,
5262	[OP_OFFLOAD_STATUS]	= (nfsd4_enc)nfsd4_encode_offload_status,
5263	[OP_READ_PLUS]		= (nfsd4_enc)nfsd4_encode_read_plus,
5264	[OP_SEEK]		= (nfsd4_enc)nfsd4_encode_seek,
5265	[OP_WRITE_SAME]		= (nfsd4_enc)nfsd4_encode_noop,
5266	[OP_CLONE]		= (nfsd4_enc)nfsd4_encode_noop,
5267
5268	/* RFC 8276 extended atributes operations */
5269	[OP_GETXATTR]		= (nfsd4_enc)nfsd4_encode_getxattr,
5270	[OP_SETXATTR]		= (nfsd4_enc)nfsd4_encode_setxattr,
5271	[OP_LISTXATTRS]		= (nfsd4_enc)nfsd4_encode_listxattrs,
5272	[OP_REMOVEXATTR]	= (nfsd4_enc)nfsd4_encode_removexattr,
5273};
5274
5275/*
5276 * Calculate whether we still have space to encode repsize bytes.
5277 * There are two considerations:
5278 *     - For NFS versions >=4.1, the size of the reply must stay within
5279 *       session limits
5280 *     - For all NFS versions, we must stay within limited preallocated
5281 *       buffer space.
5282 *
5283 * This is called before the operation is processed, so can only provide
5284 * an upper estimate.  For some nonidempotent operations (such as
5285 * getattr), it's not necessarily a problem if that estimate is wrong,
5286 * as we can fail it after processing without significant side effects.
 
 
 
5287 */
5288__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize)
5289{
5290	struct xdr_buf *buf = &resp->rqstp->rq_res;
 
 
 
5291	struct nfsd4_slot *slot = resp->cstate.slot;
 
5292
5293	if (buf->len + respsize <= buf->buflen)
5294		return nfs_ok;
5295	if (!nfsd4_has_session(&resp->cstate))
5296		return nfserr_resource;
5297	if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) {
5298		WARN_ON_ONCE(1);
5299		return nfserr_rep_too_big_to_cache;
 
 
 
 
 
 
 
 
 
 
 
 
5300	}
5301	return nfserr_rep_too_big;
 
 
 
 
 
 
5302}
5303
5304void
5305nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
5306{
5307	struct xdr_stream *xdr = resp->xdr;
5308	struct nfs4_stateowner *so = resp->cstate.replay_owner;
5309	struct svc_rqst *rqstp = resp->rqstp;
5310	const struct nfsd4_operation *opdesc = op->opdesc;
5311	int post_err_offset;
5312	nfsd4_enc encoder;
5313	__be32 *p;
5314
5315	p = xdr_reserve_space(xdr, 8);
5316	if (!p) {
5317		WARN_ON_ONCE(1);
5318		return;
5319	}
5320	*p++ = cpu_to_be32(op->opnum);
5321	post_err_offset = xdr->buf->len;
5322
5323	if (op->opnum == OP_ILLEGAL)
5324		goto status;
5325	if (op->status && opdesc &&
5326			!(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
5327		goto status;
5328	BUG_ON(op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
5329	       !nfsd4_enc_ops[op->opnum]);
5330	encoder = nfsd4_enc_ops[op->opnum];
5331	op->status = encoder(resp, op->status, &op->u);
5332	if (op->status)
5333		trace_nfsd_compound_encode_err(rqstp, op->opnum, op->status);
5334	if (opdesc && opdesc->op_release)
5335		opdesc->op_release(&op->u);
5336	xdr_commit_encode(xdr);
5337
5338	/* nfsd4_check_resp_size guarantees enough room for error status */
5339	if (!op->status) {
5340		int space_needed = 0;
5341		if (!nfsd4_last_compound_op(rqstp))
5342			space_needed = COMPOUND_ERR_SLACK_SPACE;
5343		op->status = nfsd4_check_resp_size(resp, space_needed);
5344	}
5345	if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
5346		struct nfsd4_slot *slot = resp->cstate.slot;
5347
5348		if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
5349			op->status = nfserr_rep_too_big_to_cache;
5350		else
5351			op->status = nfserr_rep_too_big;
5352	}
5353	if (op->status == nfserr_resource ||
5354	    op->status == nfserr_rep_too_big ||
5355	    op->status == nfserr_rep_too_big_to_cache) {
5356		/*
5357		 * The operation may have already been encoded or
5358		 * partially encoded.  No op returns anything additional
5359		 * in the case of one of these three errors, so we can
5360		 * just truncate back to after the status.  But it's a
5361		 * bug if we had to do this on a non-idempotent op:
5362		 */
5363		warn_on_nonidempotent_op(op);
5364		xdr_truncate_encode(xdr, post_err_offset);
5365	}
5366	if (so) {
5367		int len = xdr->buf->len - post_err_offset;
5368
5369		so->so_replay.rp_status = op->status;
5370		so->so_replay.rp_buflen = len;
5371		read_bytes_from_xdr_buf(xdr->buf, post_err_offset,
5372						so->so_replay.rp_buf, len);
5373	}
5374status:
5375	/* Note that op->status is already in network byte order: */
5376	write_bytes_to_xdr_buf(xdr->buf, post_err_offset - 4, &op->status, 4);
 
 
 
5377}
5378
5379/* 
5380 * Encode the reply stored in the stateowner reply cache 
5381 * 
5382 * XDR note: do not encode rp->rp_buflen: the buffer contains the
5383 * previously sent already encoded operation.
 
 
5384 */
5385void
5386nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
5387{
5388	__be32 *p;
5389	struct nfs4_replay *rp = op->replay;
5390
5391	p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
5392	if (!p) {
5393		WARN_ON_ONCE(1);
5394		return;
5395	}
5396	*p++ = cpu_to_be32(op->opnum);
5397	*p++ = rp->rp_status;  /* already xdr'ed */
 
5398
5399	p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
 
 
5400}
5401
5402void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
 
5403{
 
 
 
 
 
 
5404	struct nfsd4_compoundargs *args = rqstp->rq_argp;
5405
5406	if (args->ops != args->iops) {
5407		kfree(args->ops);
5408		args->ops = args->iops;
5409	}
 
 
5410	while (args->to_free) {
5411		struct svcxdr_tmpbuf *tb = args->to_free;
5412		args->to_free = tb->next;
 
5413		kfree(tb);
5414	}
 
5415}
5416
5417int
5418nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
5419{
5420	struct nfsd4_compoundargs *args = rqstp->rq_argp;
5421
5422	/* svcxdr_tmp_alloc */
 
 
5423	args->to_free = NULL;
5424
5425	args->xdr = &rqstp->rq_arg_stream;
5426	args->ops = args->iops;
5427	args->rqstp = rqstp;
5428
5429	return nfsd4_decode_compound(args);
5430}
5431
5432int
5433nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p)
5434{
5435	struct nfsd4_compoundres *resp = rqstp->rq_resp;
5436	struct xdr_buf *buf = resp->xdr->buf;
5437
5438	WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len +
5439				 buf->tail[0].iov_len);
5440
5441	*p = resp->cstate.status;
5442
5443	rqstp->rq_next_page = resp->xdr->page_ptr + 1;
5444
5445	p = resp->tagp;
5446	*p++ = htonl(resp->taglen);
5447	memcpy(p, resp->tag, resp->taglen);
5448	p += XDR_QUADLEN(resp->taglen);
5449	*p++ = htonl(resp->opcnt);
5450
5451	nfsd4_sequence_done(resp);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5452	return 1;
5453}
v3.1
   1/*
   2 *  Server-side XDR for NFSv4
   3 *
   4 *  Copyright (c) 2002 The Regents of the University of Michigan.
   5 *  All rights reserved.
   6 *
   7 *  Kendrick Smith <kmsmith@umich.edu>
   8 *  Andy Adamson   <andros@umich.edu>
   9 *
  10 *  Redistribution and use in source and binary forms, with or without
  11 *  modification, are permitted provided that the following conditions
  12 *  are met:
  13 *
  14 *  1. Redistributions of source code must retain the above copyright
  15 *     notice, this list of conditions and the following disclaimer.
  16 *  2. Redistributions in binary form must reproduce the above copyright
  17 *     notice, this list of conditions and the following disclaimer in the
  18 *     documentation and/or other materials provided with the distribution.
  19 *  3. Neither the name of the University nor the names of its
  20 *     contributors may be used to endorse or promote products derived
  21 *     from this software without specific prior written permission.
  22 *
  23 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  24 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  25 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  30 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34 *
  35 * TODO: Neil Brown made the following observation:  We currently
  36 * initially reserve NFSD_BUFSIZE space on the transmit queue and
  37 * never release any of that until the request is complete.
  38 * It would be good to calculate a new maximum response size while
  39 * decoding the COMPOUND, and call svc_reserve with this number
  40 * at the end of nfs4svc_decode_compoundargs.
  41 */
  42
 
  43#include <linux/slab.h>
  44#include <linux/namei.h>
  45#include <linux/statfs.h>
  46#include <linux/utsname.h>
  47#include <linux/pagemap.h>
  48#include <linux/sunrpc/svcauth_gss.h>
 
 
 
  49
  50#include "idmap.h"
  51#include "acl.h"
  52#include "xdr4.h"
  53#include "vfs.h"
  54#include "state.h"
  55#include "cache.h"
 
 
 
 
 
 
 
 
 
 
  56
  57#define NFSDDBG_FACILITY		NFSDDBG_XDR
  58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  59/*
  60 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
  61 * directory in order to indicate to the client that a filesystem boundary is present
  62 * We use a fixed fsid for a referral
  63 */
  64#define NFS4_REFERRAL_FSID_MAJOR	0x8000000ULL
  65#define NFS4_REFERRAL_FSID_MINOR	0x8000000ULL
  66
  67static __be32
  68check_filename(char *str, int len, __be32 err)
  69{
  70	int i;
  71
  72	if (len == 0)
  73		return nfserr_inval;
 
 
  74	if (isdotent(str, len))
  75		return err;
  76	for (i = 0; i < len; i++)
  77		if (str[i] == '/')
  78			return err;
  79	return 0;
  80}
  81
  82#define DECODE_HEAD				\
  83	__be32 *p;				\
  84	__be32 status
  85#define DECODE_TAIL				\
  86	status = 0;				\
  87out:						\
  88	return status;				\
  89xdr_error:					\
  90	dprintk("NFSD: xdr error (%s:%d)\n",	\
  91			__FILE__, __LINE__);	\
  92	status = nfserr_bad_xdr;		\
  93	goto out
  94
  95#define READ32(x)         (x) = ntohl(*p++)
  96#define READ64(x)         do {			\
  97	(x) = (u64)ntohl(*p++) << 32;		\
  98	(x) |= ntohl(*p++);			\
  99} while (0)
 100#define READTIME(x)       do {			\
 101	p++;					\
 102	(x) = ntohl(*p++);			\
 103	p++;					\
 104} while (0)
 105#define READMEM(x,nbytes) do {			\
 106	x = (char *)p;				\
 107	p += XDR_QUADLEN(nbytes);		\
 108} while (0)
 109#define SAVEMEM(x,nbytes) do {			\
 110	if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
 111 		savemem(argp, p, nbytes) :	\
 112 		(char *)p)) {			\
 113		dprintk("NFSD: xdr error (%s:%d)\n", \
 114				__FILE__, __LINE__); \
 115		goto xdr_error;			\
 116		}				\
 117	p += XDR_QUADLEN(nbytes);		\
 118} while (0)
 119#define COPYMEM(x,nbytes) do {			\
 120	memcpy((x), p, nbytes);			\
 121	p += XDR_QUADLEN(nbytes);		\
 122} while (0)
 123
 124/* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
 125#define READ_BUF(nbytes)  do {			\
 126	if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) {	\
 127		p = argp->p;			\
 128		argp->p += XDR_QUADLEN(nbytes);	\
 129	} else if (!(p = read_buf(argp, nbytes))) { \
 130		dprintk("NFSD: xdr error (%s:%d)\n", \
 131				__FILE__, __LINE__); \
 132		goto xdr_error;			\
 133	}					\
 134} while (0)
 135
 136static void save_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
 137{
 138	savep->p        = argp->p;
 139	savep->end      = argp->end;
 140	savep->pagelen  = argp->pagelen;
 141	savep->pagelist = argp->pagelist;
 142}
 143
 144static void restore_buf(struct nfsd4_compoundargs *argp, struct nfsd4_saved_compoundargs *savep)
 145{
 146	argp->p        = savep->p;
 147	argp->end      = savep->end;
 148	argp->pagelen  = savep->pagelen;
 149	argp->pagelist = savep->pagelist;
 150}
 151
 152static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
 
 
 
 
 
 
 
 
 
 153{
 154	/* We want more bytes than seem to be available.
 155	 * Maybe we need a new page, maybe we have just run out
 156	 */
 157	unsigned int avail = (char *)argp->end - (char *)argp->p;
 158	__be32 *p;
 159	if (avail + argp->pagelen < nbytes)
 160		return NULL;
 161	if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 162		return NULL;
 163	/* ok, we can do it with the current plus the next page */
 164	if (nbytes <= sizeof(argp->tmp))
 165		p = argp->tmp;
 166	else {
 167		kfree(argp->tmpp);
 168		p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
 169		if (!p)
 170			return NULL;
 171		
 172	}
 173	/*
 174	 * The following memcpy is safe because read_buf is always
 175	 * called with nbytes > avail, and the two cases above both
 176	 * guarantee p points to at least nbytes bytes.
 177	 */
 178	memcpy(p, argp->p, avail);
 179	/* step to next page */
 180	argp->p = page_address(argp->pagelist[0]);
 181	argp->pagelist++;
 182	if (argp->pagelen < PAGE_SIZE) {
 183		argp->end = argp->p + (argp->pagelen>>2);
 184		argp->pagelen = 0;
 185	} else {
 186		argp->end = argp->p + (PAGE_SIZE>>2);
 187		argp->pagelen -= PAGE_SIZE;
 188	}
 189	memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
 190	argp->p += XDR_QUADLEN(nbytes - avail);
 191	return p;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 192}
 193
 194static int zero_clientid(clientid_t *clid)
 
 195{
 196	return (clid->cl_boot == 0) && (clid->cl_id == 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 197}
 198
 199static int
 200defer_free(struct nfsd4_compoundargs *argp,
 201		void (*release)(const void *), void *p)
 202{
 203	struct tmpbuf *tb;
 204
 205	tb = kmalloc(sizeof(*tb), GFP_KERNEL);
 206	if (!tb)
 207		return -ENOMEM;
 208	tb->buf = p;
 209	tb->release = release;
 210	tb->next = argp->to_free;
 211	argp->to_free = tb;
 212	return 0;
 
 
 
 
 
 213}
 214
 215static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 
 216{
 217	if (p == argp->tmp) {
 218		p = kmalloc(nbytes, GFP_KERNEL);
 219		if (!p)
 220			return NULL;
 221		memcpy(p, argp->tmp, nbytes);
 222	} else {
 223		BUG_ON(p != argp->tmpp);
 224		argp->tmpp = NULL;
 225	}
 226	if (defer_free(argp, kfree, p)) {
 227		kfree(p);
 228		return NULL;
 229	} else
 230		return (char *)p;
 231}
 232
 233static __be32
 234nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
 235{
 236	u32 bmlen;
 237	DECODE_HEAD;
 238
 239	bmval[0] = 0;
 240	bmval[1] = 0;
 241	bmval[2] = 0;
 
 
 
 242
 243	READ_BUF(4);
 244	READ32(bmlen);
 245	if (bmlen > 1000)
 246		goto xdr_error;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 247
 248	READ_BUF(bmlen << 2);
 249	if (bmlen > 0)
 250		READ32(bmval[0]);
 251	if (bmlen > 1)
 252		READ32(bmval[1]);
 253	if (bmlen > 2)
 254		READ32(bmval[2]);
 
 
 
 
 
 
 255
 256	DECODE_TAIL;
 257}
 258
 259static __be32
 260nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 261		   struct iattr *iattr, struct nfs4_acl **acl)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 262{
 263	int expected_len, len = 0;
 264	u32 dummy32;
 265	char *buf;
 266	int host_err;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 267
 268	DECODE_HEAD;
 269	iattr->ia_valid = 0;
 270	if ((status = nfsd4_decode_bitmap(argp, bmval)))
 271		return status;
 
 
 
 
 
 
 
 
 
 272
 273	READ_BUF(4);
 274	READ32(expected_len);
 
 275
 276	if (bmval[0] & FATTR4_WORD0_SIZE) {
 277		READ_BUF(8);
 278		len += 8;
 279		READ64(iattr->ia_size);
 
 
 280		iattr->ia_valid |= ATTR_SIZE;
 281	}
 282	if (bmval[0] & FATTR4_WORD0_ACL) {
 283		int nace;
 284		struct nfs4_ace *ace;
 285
 286		READ_BUF(4); len += 4;
 287		READ32(nace);
 288
 289		if (nace > NFS4_ACL_MAX)
 290			return nfserr_resource;
 291
 292		*acl = nfs4_acl_new(nace);
 293		if (*acl == NULL) {
 294			host_err = -ENOMEM;
 295			goto out_nfserr;
 296		}
 297		defer_free(argp, kfree, *acl);
 298
 299		(*acl)->naces = nace;
 300		for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
 301			READ_BUF(16); len += 16;
 302			READ32(ace->type);
 303			READ32(ace->flag);
 304			READ32(ace->access_mask);
 305			READ32(dummy32);
 306			READ_BUF(dummy32);
 307			len += XDR_QUADLEN(dummy32) << 2;
 308			READMEM(buf, dummy32);
 309			ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
 310			status = nfs_ok;
 311			if (ace->whotype != NFS4_ACL_WHO_NAMED)
 312				ace->who = 0;
 313			else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
 314				status = nfsd_map_name_to_gid(argp->rqstp,
 315						buf, dummy32, &ace->who);
 316			else
 317				status = nfsd_map_name_to_uid(argp->rqstp,
 318						buf, dummy32, &ace->who);
 319			if (status)
 320				return status;
 321		}
 322	} else
 323		*acl = NULL;
 324	if (bmval[1] & FATTR4_WORD1_MODE) {
 325		READ_BUF(4);
 326		len += 4;
 327		READ32(iattr->ia_mode);
 
 
 328		iattr->ia_mode &= (S_IFMT | S_IALLUGO);
 329		iattr->ia_valid |= ATTR_MODE;
 330	}
 331	if (bmval[1] & FATTR4_WORD1_OWNER) {
 332		READ_BUF(4);
 333		len += 4;
 334		READ32(dummy32);
 335		READ_BUF(dummy32);
 336		len += (XDR_QUADLEN(dummy32) << 2);
 337		READMEM(buf, dummy32);
 338		if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
 
 
 
 339			return status;
 340		iattr->ia_valid |= ATTR_UID;
 341	}
 342	if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
 343		READ_BUF(4);
 344		len += 4;
 345		READ32(dummy32);
 346		READ_BUF(dummy32);
 347		len += (XDR_QUADLEN(dummy32) << 2);
 348		READMEM(buf, dummy32);
 349		if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
 
 
 
 350			return status;
 351		iattr->ia_valid |= ATTR_GID;
 352	}
 353	if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
 354		READ_BUF(4);
 355		len += 4;
 356		READ32(dummy32);
 357		switch (dummy32) {
 
 358		case NFS4_SET_TO_CLIENT_TIME:
 359			/* We require the high 32 bits of 'seconds' to be 0, and we ignore
 360			   all 32 bits of 'nseconds'. */
 361			READ_BUF(12);
 362			len += 12;
 363			READ32(dummy32);
 364			if (dummy32)
 365				return nfserr_inval;
 366			READ32(iattr->ia_atime.tv_sec);
 367			READ32(iattr->ia_atime.tv_nsec);
 368			if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
 369				return nfserr_inval;
 370			iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
 371			break;
 372		case NFS4_SET_TO_SERVER_TIME:
 373			iattr->ia_valid |= ATTR_ATIME;
 374			break;
 375		default:
 376			goto xdr_error;
 377		}
 378	}
 379	if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
 380		READ_BUF(4);
 381		len += 4;
 382		READ32(dummy32);
 383		switch (dummy32) {
 
 384		case NFS4_SET_TO_CLIENT_TIME:
 385			/* We require the high 32 bits of 'seconds' to be 0, and we ignore
 386			   all 32 bits of 'nseconds'. */
 387			READ_BUF(12);
 388			len += 12;
 389			READ32(dummy32);
 390			if (dummy32)
 391				return nfserr_inval;
 392			READ32(iattr->ia_mtime.tv_sec);
 393			READ32(iattr->ia_mtime.tv_nsec);
 394			if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
 395				return nfserr_inval;
 396			iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
 397			break;
 398		case NFS4_SET_TO_SERVER_TIME:
 399			iattr->ia_valid |= ATTR_MTIME;
 400			break;
 401		default:
 402			goto xdr_error;
 403		}
 404	}
 405	if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
 406	    || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
 407	    || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2)
 408		READ_BUF(expected_len - len);
 409	else if (len != expected_len)
 410		goto xdr_error;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 411
 412	DECODE_TAIL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 413
 414out_nfserr:
 415	status = nfserrno(host_err);
 416	goto out;
 417}
 418
 419static __be32
 420nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
 
 421{
 422	DECODE_HEAD;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 423
 424	READ_BUF(sizeof(stateid_t));
 425	READ32(sid->si_generation);
 426	COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
 427
 428	DECODE_TAIL;
 
 
 
 
 
 
 
 
 
 
 429}
 430
 
 431static __be32
 432nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
 
 433{
 434	DECODE_HEAD;
 
 435
 436	READ_BUF(4);
 437	READ32(access->ac_req_access);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 438
 439	DECODE_TAIL;
 440}
 441
 442static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
 
 
 443{
 444	DECODE_HEAD;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 445
 446	READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
 447	COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
 448	READ32(bcts->dir);
 449	/* XXX: skipping ctsa_use_conn_in_rdma_mode.  Perhaps Tom Tucker
 450	 * could help us figure out we should be using it. */
 451	DECODE_TAIL;
 452}
 453
 
 454static __be32
 455nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 456{
 457	DECODE_HEAD;
 
 
 
 
 
 
 
 
 
 
 458
 459	close->cl_stateowner = NULL;
 460	READ_BUF(4);
 461	READ32(close->cl_seqid);
 462	return nfsd4_decode_stateid(argp, &close->cl_stateid);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 463
 464	DECODE_TAIL;
 465}
 466
 467
 
 
 
 
 468static __be32
 469nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
 
 
 
 
 
 
 
 
 
 470{
 471	DECODE_HEAD;
 
 
 
 472
 473	READ_BUF(12);
 474	READ64(commit->co_offset);
 475	READ32(commit->co_count);
 476
 477	DECODE_TAIL;
 
 
 
 
 
 
 
 478}
 479
 480static __be32
 481nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
 482{
 483	DECODE_HEAD;
 484
 485	READ_BUF(4);
 486	READ32(create->cr_type);
 487	switch (create->cr_type) {
 488	case NF4LNK:
 489		READ_BUF(4);
 490		READ32(create->cr_linklen);
 491		READ_BUF(create->cr_linklen);
 492		SAVEMEM(create->cr_linkname, create->cr_linklen);
 
 
 
 
 493		break;
 494	case NF4BLK:
 495	case NF4CHR:
 496		READ_BUF(8);
 497		READ32(create->cr_specdata1);
 498		READ32(create->cr_specdata2);
 
 499		break;
 500	case NF4SOCK:
 501	case NF4FIFO:
 502	case NF4DIR:
 503	default:
 504		break;
 505	}
 506
 507	READ_BUF(4);
 508	READ32(create->cr_namelen);
 509	READ_BUF(create->cr_namelen);
 510	SAVEMEM(create->cr_name, create->cr_namelen);
 511	if ((status = check_filename(create->cr_name, create->cr_namelen, nfserr_inval)))
 512		return status;
 513
 514	status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
 515				    &create->cr_acl);
 
 516	if (status)
 517		goto out;
 518
 519	DECODE_TAIL;
 520}
 521
 522static inline __be32
 523nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
 524{
 525	return nfsd4_decode_stateid(argp, &dr->dr_stateid);
 526}
 527
 528static inline __be32
 529nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
 530{
 531	return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
 
 532}
 533
 534static __be32
 535nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 536{
 537	DECODE_HEAD;
 
 
 
 
 
 
 
 538
 539	READ_BUF(4);
 540	READ32(link->li_namelen);
 541	READ_BUF(link->li_namelen);
 542	SAVEMEM(link->li_name, link->li_namelen);
 543	if ((status = check_filename(link->li_name, link->li_namelen, nfserr_inval)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 544		return status;
 
 
 545
 546	DECODE_TAIL;
 
 
 
 
 
 
 
 
 
 
 547}
 548
 549static __be32
 550nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 551{
 552	DECODE_HEAD;
 553
 554	lock->lk_replay_owner = NULL;
 555	/*
 556	* type, reclaim(boolean), offset, length, new_lock_owner(boolean)
 557	*/
 558	READ_BUF(28);
 559	READ32(lock->lk_type);
 560	if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
 561		goto xdr_error;
 562	READ32(lock->lk_reclaim);
 563	READ64(lock->lk_offset);
 564	READ64(lock->lk_length);
 565	READ32(lock->lk_is_new);
 566
 567	if (lock->lk_is_new) {
 568		READ_BUF(4);
 569		READ32(lock->lk_new_open_seqid);
 570		status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
 571		if (status)
 572			return status;
 573		READ_BUF(8 + sizeof(clientid_t));
 574		READ32(lock->lk_new_lock_seqid);
 575		COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
 576		READ32(lock->lk_new_owner.len);
 577		READ_BUF(lock->lk_new_owner.len);
 578		READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
 579	} else {
 580		status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
 581		if (status)
 582			return status;
 583		READ_BUF(4);
 584		READ32(lock->lk_old_lock_seqid);
 585	}
 586
 587	DECODE_TAIL;
 588}
 589
 590static __be32
 591nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 592{
 593	DECODE_HEAD;
 594		        
 595	READ_BUF(32);
 596	READ32(lockt->lt_type);
 597	if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
 598		goto xdr_error;
 599	READ64(lockt->lt_offset);
 600	READ64(lockt->lt_length);
 601	COPYMEM(&lockt->lt_clientid, 8);
 602	READ32(lockt->lt_owner.len);
 603	READ_BUF(lockt->lt_owner.len);
 604	READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
 605
 606	DECODE_TAIL;
 607}
 608
 609static __be32
 610nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 611{
 612	DECODE_HEAD;
 613
 614	locku->lu_stateowner = NULL;
 615	READ_BUF(8);
 616	READ32(locku->lu_type);
 617	if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
 618		goto xdr_error;
 619	READ32(locku->lu_seqid);
 620	status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
 
 621	if (status)
 622		return status;
 623	READ_BUF(16);
 624	READ64(locku->lu_offset);
 625	READ64(locku->lu_length);
 
 626
 627	DECODE_TAIL;
 628}
 629
 630static __be32
 631nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
 632{
 633	DECODE_HEAD;
 
 
 
 
 
 
 634
 635	READ_BUF(4);
 636	READ32(lookup->lo_len);
 637	READ_BUF(lookup->lo_len);
 638	SAVEMEM(lookup->lo_name, lookup->lo_len);
 639	if ((status = check_filename(lookup->lo_name, lookup->lo_len, nfserr_noent)))
 640		return status;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 641
 642	DECODE_TAIL;
 643}
 644
 645static __be32
 646nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 647{
 648	DECODE_HEAD;
 649
 650	memset(open->op_bmval, 0, sizeof(open->op_bmval));
 651	open->op_iattr.ia_valid = 0;
 652	open->op_stateowner = NULL;
 653
 654	/* seqid, share_access, share_deny, clientid, ownerlen */
 655	READ_BUF(16 + sizeof(clientid_t));
 656	READ32(open->op_seqid);
 657	READ32(open->op_share_access);
 658	READ32(open->op_share_deny);
 659	COPYMEM(&open->op_clientid, sizeof(clientid_t));
 660	READ32(open->op_owner.len);
 661
 662	/* owner, open_flag */
 663	READ_BUF(open->op_owner.len + 4);
 664	SAVEMEM(open->op_owner.data, open->op_owner.len);
 665	READ32(open->op_create);
 666	switch (open->op_create) {
 667	case NFS4_OPEN_NOCREATE:
 668		break;
 669	case NFS4_OPEN_CREATE:
 670		READ_BUF(4);
 671		READ32(open->op_createmode);
 672		switch (open->op_createmode) {
 673		case NFS4_CREATE_UNCHECKED:
 674		case NFS4_CREATE_GUARDED:
 675			status = nfsd4_decode_fattr(argp, open->op_bmval,
 676				&open->op_iattr, &open->op_acl);
 677			if (status)
 678				goto out;
 679			break;
 680		case NFS4_CREATE_EXCLUSIVE:
 681			READ_BUF(8);
 682			COPYMEM(open->op_verf.data, 8);
 683			break;
 684		case NFS4_CREATE_EXCLUSIVE4_1:
 685			if (argp->minorversion < 1)
 686				goto xdr_error;
 687			READ_BUF(8);
 688			COPYMEM(open->op_verf.data, 8);
 689			status = nfsd4_decode_fattr(argp, open->op_bmval,
 690				&open->op_iattr, &open->op_acl);
 691			if (status)
 692				goto out;
 693			break;
 694		default:
 695			goto xdr_error;
 696		}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 697		break;
 698	default:
 699		goto xdr_error;
 700	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 701
 702	/* open_claim */
 703	READ_BUF(4);
 704	READ32(open->op_claim_type);
 
 
 
 
 
 
 
 
 705	switch (open->op_claim_type) {
 706	case NFS4_OPEN_CLAIM_NULL:
 707	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
 708		READ_BUF(4);
 709		READ32(open->op_fname.len);
 710		READ_BUF(open->op_fname.len);
 711		SAVEMEM(open->op_fname.data, open->op_fname.len);
 712		if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
 713			return status;
 714		break;
 715	case NFS4_OPEN_CLAIM_PREVIOUS:
 716		READ_BUF(4);
 717		READ32(open->op_delegate_type);
 718		break;
 719	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
 720		status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
 
 
 
 
 721		if (status)
 722			return status;
 723		READ_BUF(4);
 724		READ32(open->op_fname.len);
 725		READ_BUF(open->op_fname.len);
 726		SAVEMEM(open->op_fname.data, open->op_fname.len);
 727		if ((status = check_filename(open->op_fname.data, open->op_fname.len, nfserr_inval)))
 
 
 
 
 
 
 
 728			return status;
 729		break;
 730	default:
 731		goto xdr_error;
 732	}
 733
 734	DECODE_TAIL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 735}
 736
 737static __be32
 738nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
 739{
 740	DECODE_HEAD;
 741		    
 742	open_conf->oc_stateowner = NULL;
 743	status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
 
 
 744	if (status)
 745		return status;
 746	READ_BUF(4);
 747	READ32(open_conf->oc_seqid);
 748						        
 749	DECODE_TAIL;
 750}
 751
 752static __be32
 753nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
 754{
 755	DECODE_HEAD;
 756		    
 757	open_down->od_stateowner = NULL;
 758	status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
 
 
 
 
 
 
 759	if (status)
 760		return status;
 761	READ_BUF(12);
 762	READ32(open_down->od_seqid);
 763	READ32(open_down->od_share_access);
 764	READ32(open_down->od_share_deny);
 765						        
 766	DECODE_TAIL;
 767}
 768
 769static __be32
 770nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
 771{
 772	DECODE_HEAD;
 773
 774	READ_BUF(4);
 775	READ32(putfh->pf_fhlen);
 776	if (putfh->pf_fhlen > NFS4_FHSIZE)
 777		goto xdr_error;
 778	READ_BUF(putfh->pf_fhlen);
 779	SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
 
 
 
 
 780
 781	DECODE_TAIL;
 
 
 
 
 
 
 
 
 782}
 783
 784static __be32
 785nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
 786{
 787	DECODE_HEAD;
 788
 789	status = nfsd4_decode_stateid(argp, &read->rd_stateid);
 790	if (status)
 791		return status;
 792	READ_BUF(12);
 793	READ64(read->rd_offset);
 794	READ32(read->rd_length);
 
 795
 796	DECODE_TAIL;
 797}
 798
 799static __be32
 800nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
 801{
 802	DECODE_HEAD;
 803
 804	READ_BUF(24);
 805	READ64(readdir->rd_cookie);
 806	COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
 807	READ32(readdir->rd_dircount);    /* just in case you needed a useless field... */
 808	READ32(readdir->rd_maxcount);
 809	if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
 810		goto out;
 
 
 
 
 
 811
 812	DECODE_TAIL;
 813}
 814
 815static __be32
 816nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
 817{
 818	DECODE_HEAD;
 819
 820	READ_BUF(4);
 821	READ32(remove->rm_namelen);
 822	READ_BUF(remove->rm_namelen);
 823	SAVEMEM(remove->rm_name, remove->rm_namelen);
 824	if ((status = check_filename(remove->rm_name, remove->rm_namelen, nfserr_noent)))
 825		return status;
 826
 827	DECODE_TAIL;
 828}
 829
 830static __be32
 831nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
 832{
 833	DECODE_HEAD;
 834
 835	READ_BUF(4);
 836	READ32(rename->rn_snamelen);
 837	READ_BUF(rename->rn_snamelen + 4);
 838	SAVEMEM(rename->rn_sname, rename->rn_snamelen);
 839	READ32(rename->rn_tnamelen);
 840	READ_BUF(rename->rn_tnamelen);
 841	SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
 842	if ((status = check_filename(rename->rn_sname, rename->rn_snamelen, nfserr_noent)))
 843		return status;
 844	if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen, nfserr_inval)))
 845		return status;
 846
 847	DECODE_TAIL;
 848}
 849
 850static __be32
 851nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
 852{
 853	DECODE_HEAD;
 854
 855	READ_BUF(sizeof(clientid_t));
 856	COPYMEM(clientid, sizeof(clientid_t));
 857
 858	DECODE_TAIL;
 859}
 860
 861static __be32
 862nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
 863		     struct nfsd4_secinfo *secinfo)
 864{
 865	DECODE_HEAD;
 866
 867	READ_BUF(4);
 868	READ32(secinfo->si_namelen);
 869	READ_BUF(secinfo->si_namelen);
 870	SAVEMEM(secinfo->si_name, secinfo->si_namelen);
 871	status = check_filename(secinfo->si_name, secinfo->si_namelen,
 872								nfserr_noent);
 873	if (status)
 874		return status;
 875	DECODE_TAIL;
 876}
 877
 878static __be32
 879nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
 880		     struct nfsd4_secinfo_no_name *sin)
 881{
 882	DECODE_HEAD;
 883
 884	READ_BUF(4);
 885	READ32(sin->sin_style);
 886	DECODE_TAIL;
 887}
 888
 889static __be32
 890nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
 891{
 892	__be32 status;
 893
 894	status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
 895	if (status)
 896		return status;
 897	return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
 898				  &setattr->sa_acl);
 
 
 899}
 900
 901static __be32
 902nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
 903{
 904	DECODE_HEAD;
 
 
 
 905
 906	READ_BUF(12);
 907	COPYMEM(setclientid->se_verf.data, 8);
 908	READ32(setclientid->se_namelen);
 909
 910	READ_BUF(setclientid->se_namelen + 8);
 911	SAVEMEM(setclientid->se_name, setclientid->se_namelen);
 912	READ32(setclientid->se_callback_prog);
 913	READ32(setclientid->se_callback_netid_len);
 914
 915	READ_BUF(setclientid->se_callback_netid_len + 4);
 916	SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
 917	READ32(setclientid->se_callback_addr_len);
 918
 919	READ_BUF(setclientid->se_callback_addr_len + 4);
 920	SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
 921	READ32(setclientid->se_callback_ident);
 
 
 
 
 
 
 
 
 
 
 
 
 
 922
 923	DECODE_TAIL;
 924}
 925
 926static __be32
 927nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
 928{
 929	DECODE_HEAD;
 930
 931	READ_BUF(8 + sizeof(nfs4_verifier));
 932	COPYMEM(&scd_c->sc_clientid, 8);
 933	COPYMEM(&scd_c->sc_confirm, sizeof(nfs4_verifier));
 934
 935	DECODE_TAIL;
 
 
 
 936}
 937
 938/* Also used for NVERIFY */
 939static __be32
 940nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
 941{
 942#if 0
 943	struct nfsd4_compoundargs save = {
 944		.p = argp->p,
 945		.end = argp->end,
 946		.rqstp = argp->rqstp,
 947	};
 948	u32             ve_bmval[2];
 949	struct iattr    ve_iattr;           /* request */
 950	struct nfs4_acl *ve_acl;            /* request */
 951#endif
 952	DECODE_HEAD;
 953
 954	if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
 955		goto out;
 
 
 956
 957	/* For convenience's sake, we compare raw xdr'd attributes in
 958	 * nfsd4_proc_verify; however we still decode here just to return
 959	 * correct error in case of bad xdr. */
 960#if 0
 961	status = nfsd4_decode_fattr(ve_bmval, &ve_iattr, &ve_acl);
 962	if (status == nfserr_inval) {
 963		status = nfserrno(status);
 964		goto out;
 965	}
 966#endif
 967	READ_BUF(4);
 968	READ32(verify->ve_attrlen);
 969	READ_BUF(verify->ve_attrlen);
 970	SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
 971
 972	DECODE_TAIL;
 973}
 974
 975static __be32
 976nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
 977{
 978	int avail;
 979	int v;
 980	int len;
 981	DECODE_HEAD;
 982
 983	status = nfsd4_decode_stateid(argp, &write->wr_stateid);
 984	if (status)
 985		return status;
 986	READ_BUF(16);
 987	READ64(write->wr_offset);
 988	READ32(write->wr_stable_how);
 989	if (write->wr_stable_how > 2)
 990		goto xdr_error;
 991	READ32(write->wr_buflen);
 992
 993	/* Sorry .. no magic macros for this.. *
 994	 * READ_BUF(write->wr_buflen);
 995	 * SAVEMEM(write->wr_buf, write->wr_buflen);
 996	 */
 997	avail = (char*)argp->end - (char*)argp->p;
 998	if (avail + argp->pagelen < write->wr_buflen) {
 999		dprintk("NFSD: xdr error (%s:%d)\n",
1000				__FILE__, __LINE__);
1001		goto xdr_error;
1002	}
1003	argp->rqstp->rq_vec[0].iov_base = p;
1004	argp->rqstp->rq_vec[0].iov_len = avail;
1005	v = 0;
1006	len = write->wr_buflen;
1007	while (len > argp->rqstp->rq_vec[v].iov_len) {
1008		len -= argp->rqstp->rq_vec[v].iov_len;
1009		v++;
1010		argp->rqstp->rq_vec[v].iov_base = page_address(argp->pagelist[0]);
1011		argp->pagelist++;
1012		if (argp->pagelen >= PAGE_SIZE) {
1013			argp->rqstp->rq_vec[v].iov_len = PAGE_SIZE;
1014			argp->pagelen -= PAGE_SIZE;
1015		} else {
1016			argp->rqstp->rq_vec[v].iov_len = argp->pagelen;
1017			argp->pagelen -= len;
1018		}
1019	}
1020	argp->end = (__be32*) (argp->rqstp->rq_vec[v].iov_base + argp->rqstp->rq_vec[v].iov_len);
1021	argp->p = (__be32*)  (argp->rqstp->rq_vec[v].iov_base + (XDR_QUADLEN(len) << 2));
1022	argp->rqstp->rq_vec[v].iov_len = len;
1023	write->wr_vlen = v+1;
1024
1025	DECODE_TAIL;
1026}
1027
1028static __be32
1029nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1030{
1031	DECODE_HEAD;
 
 
 
1032
1033	READ_BUF(12);
1034	COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
1035	READ32(rlockowner->rl_owner.len);
1036	READ_BUF(rlockowner->rl_owner.len);
1037	READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
1038
1039	if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
1040		return nfserr_inval;
1041	DECODE_TAIL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1042}
1043
1044static __be32
1045nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1046			 struct nfsd4_exchange_id *exid)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1047{
1048	int dummy, tmp;
1049	DECODE_HEAD;
 
 
 
 
 
1050
1051	READ_BUF(NFS4_VERIFIER_SIZE);
1052	COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1053
1054	READ_BUF(4);
1055	READ32(exid->clname.len);
 
 
1056
1057	READ_BUF(exid->clname.len);
1058	SAVEMEM(exid->clname.data, exid->clname.len);
1059
1060	READ_BUF(4);
1061	READ32(exid->flags);
 
 
 
1062
1063	/* Ignore state_protect4_a */
1064	READ_BUF(4);
1065	READ32(exid->spa_how);
1066	switch (exid->spa_how) {
1067	case SP4_NONE:
1068		break;
1069	case SP4_MACH_CRED:
1070		/* spo_must_enforce */
1071		READ_BUF(4);
1072		READ32(dummy);
1073		READ_BUF(dummy * 4);
1074		p += dummy;
1075
1076		/* spo_must_allow */
1077		READ_BUF(4);
1078		READ32(dummy);
1079		READ_BUF(dummy * 4);
1080		p += dummy;
1081		break;
1082	case SP4_SSV:
1083		/* ssp_ops */
1084		READ_BUF(4);
1085		READ32(dummy);
1086		READ_BUF(dummy * 4);
1087		p += dummy;
1088
1089		READ_BUF(4);
1090		READ32(dummy);
1091		READ_BUF(dummy * 4);
1092		p += dummy;
1093
1094		/* ssp_hash_algs<> */
1095		READ_BUF(4);
1096		READ32(tmp);
1097		while (tmp--) {
1098			READ_BUF(4);
1099			READ32(dummy);
1100			READ_BUF(dummy);
1101			p += XDR_QUADLEN(dummy);
1102		}
1103
1104		/* ssp_encr_algs<> */
1105		READ_BUF(4);
1106		READ32(tmp);
1107		while (tmp--) {
1108			READ_BUF(4);
1109			READ32(dummy);
1110			READ_BUF(dummy);
1111			p += XDR_QUADLEN(dummy);
1112		}
1113
1114		/* ssp_window and ssp_num_gss_handles */
1115		READ_BUF(8);
1116		READ32(dummy);
1117		READ32(dummy);
1118		break;
1119	default:
1120		goto xdr_error;
1121	}
1122
1123	/* Ignore Implementation ID */
1124	READ_BUF(4);    /* nfs_impl_id4 array length */
1125	READ32(dummy);
1126
1127	if (dummy > 1)
1128		goto xdr_error;
1129
1130	if (dummy == 1) {
1131		/* nii_domain */
1132		READ_BUF(4);
1133		READ32(dummy);
1134		READ_BUF(dummy);
1135		p += XDR_QUADLEN(dummy);
1136
1137		/* nii_name */
1138		READ_BUF(4);
1139		READ32(dummy);
1140		READ_BUF(dummy);
1141		p += XDR_QUADLEN(dummy);
1142
1143		/* nii_date */
1144		READ_BUF(12);
1145		p += 3;
 
 
 
 
 
 
 
 
 
 
 
1146	}
1147	DECODE_TAIL;
 
1148}
1149
1150static __be32
1151nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1152			    struct nfsd4_create_session *sess)
1153{
1154	DECODE_HEAD;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1155
1156	u32 dummy;
1157	char *machine_name;
1158	int i;
1159	int nr_secflavs;
 
1160
1161	READ_BUF(16);
1162	COPYMEM(&sess->clientid, 8);
1163	READ32(sess->seqid);
1164	READ32(sess->flags);
1165
1166	/* Fore channel attrs */
1167	READ_BUF(28);
1168	READ32(dummy); /* headerpadsz is always 0 */
1169	READ32(sess->fore_channel.maxreq_sz);
1170	READ32(sess->fore_channel.maxresp_sz);
1171	READ32(sess->fore_channel.maxresp_cached);
1172	READ32(sess->fore_channel.maxops);
1173	READ32(sess->fore_channel.maxreqs);
1174	READ32(sess->fore_channel.nr_rdma_attrs);
1175	if (sess->fore_channel.nr_rdma_attrs == 1) {
1176		READ_BUF(4);
1177		READ32(sess->fore_channel.rdma_attrs);
1178	} else if (sess->fore_channel.nr_rdma_attrs > 1) {
1179		dprintk("Too many fore channel attr bitmaps!\n");
1180		goto xdr_error;
1181	}
1182
1183	/* Back channel attrs */
1184	READ_BUF(28);
1185	READ32(dummy); /* headerpadsz is always 0 */
1186	READ32(sess->back_channel.maxreq_sz);
1187	READ32(sess->back_channel.maxresp_sz);
1188	READ32(sess->back_channel.maxresp_cached);
1189	READ32(sess->back_channel.maxops);
1190	READ32(sess->back_channel.maxreqs);
1191	READ32(sess->back_channel.nr_rdma_attrs);
1192	if (sess->back_channel.nr_rdma_attrs == 1) {
1193		READ_BUF(4);
1194		READ32(sess->back_channel.rdma_attrs);
1195	} else if (sess->back_channel.nr_rdma_attrs > 1) {
1196		dprintk("Too many back channel attr bitmaps!\n");
1197		goto xdr_error;
1198	}
1199
1200	READ_BUF(8);
1201	READ32(sess->callback_prog);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1202
1203	/* callback_sec_params4 */
1204	READ32(nr_secflavs);
1205	for (i = 0; i < nr_secflavs; ++i) {
1206		READ_BUF(4);
1207		READ32(dummy);
1208		switch (dummy) {
1209		case RPC_AUTH_NULL:
1210			/* Nothing to read */
1211			break;
1212		case RPC_AUTH_UNIX:
1213			READ_BUF(8);
1214			/* stamp */
1215			READ32(dummy);
1216
1217			/* machine name */
1218			READ32(dummy);
1219			READ_BUF(dummy);
1220			SAVEMEM(machine_name, dummy);
1221
1222			/* uid, gid */
1223			READ_BUF(8);
1224			READ32(sess->uid);
1225			READ32(sess->gid);
1226
1227			/* more gids */
1228			READ_BUF(4);
1229			READ32(dummy);
1230			READ_BUF(dummy * 4);
1231			break;
1232		case RPC_AUTH_GSS:
1233			dprintk("RPC_AUTH_GSS callback secflavor "
1234				"not supported!\n");
1235			READ_BUF(8);
1236			/* gcbp_service */
1237			READ32(dummy);
1238			/* gcbp_handle_from_server */
1239			READ32(dummy);
1240			READ_BUF(dummy);
1241			p += XDR_QUADLEN(dummy);
1242			/* gcbp_handle_from_client */
1243			READ_BUF(4);
1244			READ32(dummy);
1245			READ_BUF(dummy);
1246			break;
1247		default:
1248			dprintk("Illegal callback secflavor\n");
1249			return nfserr_inval;
1250		}
1251	}
1252	DECODE_TAIL;
1253}
1254
1255static __be32
1256nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
1257			     struct nfsd4_destroy_session *destroy_session)
1258{
1259	DECODE_HEAD;
1260	READ_BUF(NFS4_MAX_SESSIONID_LEN);
1261	COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1262
1263	DECODE_TAIL;
1264}
1265
1266static __be32
1267nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1268			  struct nfsd4_free_stateid *free_stateid)
1269{
1270	DECODE_HEAD;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1271
1272	READ_BUF(sizeof(stateid_t));
1273	READ32(free_stateid->fr_stateid.si_generation);
1274	COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1275
1276	DECODE_TAIL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1277}
1278
1279static __be32
1280nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1281		      struct nfsd4_sequence *seq)
1282{
1283	DECODE_HEAD;
1284
1285	READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
1286	COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1287	READ32(seq->seqid);
1288	READ32(seq->slotid);
1289	READ32(seq->maxslots);
1290	READ32(seq->cachethis);
 
 
 
 
1291
1292	DECODE_TAIL;
1293}
1294
1295static __be32
1296nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1297{
1298	unsigned int nbytes;
1299	stateid_t si;
1300	int i;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1301	__be32 *p;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1302	__be32 status;
1303
1304	READ_BUF(4);
1305	test_stateid->ts_num_ids = ntohl(*p++);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1306
1307	nbytes = test_stateid->ts_num_ids * sizeof(stateid_t);
1308	if (nbytes > (u32)((char *)argp->end - (char *)argp->p))
1309		goto xdr_error;
1310
1311	test_stateid->ts_saved_args = argp;
1312	save_buf(argp, &test_stateid->ts_savedp);
 
 
1313
1314	for (i = 0; i < test_stateid->ts_num_ids; i++) {
1315		status = nfsd4_decode_stateid(argp, &si);
1316		if (status)
1317			return status;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1318	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1319
1320	status = 0;
1321out:
1322	return status;
1323xdr_error:
1324	dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
1325	status = nfserr_bad_xdr;
1326	goto out;
1327}
1328
1329static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
 
 
1330{
1331	DECODE_HEAD;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1332
1333	READ_BUF(4);
1334	READ32(rc->rca_one_fs);
 
 
 
 
 
 
 
 
 
 
 
 
1335
1336	DECODE_TAIL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1337}
1338
1339static __be32
1340nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
1341{
1342	return nfs_ok;
1343}
1344
1345static __be32
1346nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
1347{
1348	return nfserr_notsupp;
1349}
1350
1351typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
1352
1353static nfsd4_dec nfsd4_dec_ops[] = {
1354	[OP_ACCESS]		= (nfsd4_dec)nfsd4_decode_access,
1355	[OP_CLOSE]		= (nfsd4_dec)nfsd4_decode_close,
1356	[OP_COMMIT]		= (nfsd4_dec)nfsd4_decode_commit,
1357	[OP_CREATE]		= (nfsd4_dec)nfsd4_decode_create,
1358	[OP_DELEGPURGE]		= (nfsd4_dec)nfsd4_decode_notsupp,
1359	[OP_DELEGRETURN]	= (nfsd4_dec)nfsd4_decode_delegreturn,
1360	[OP_GETATTR]		= (nfsd4_dec)nfsd4_decode_getattr,
1361	[OP_GETFH]		= (nfsd4_dec)nfsd4_decode_noop,
1362	[OP_LINK]		= (nfsd4_dec)nfsd4_decode_link,
1363	[OP_LOCK]		= (nfsd4_dec)nfsd4_decode_lock,
1364	[OP_LOCKT]		= (nfsd4_dec)nfsd4_decode_lockt,
1365	[OP_LOCKU]		= (nfsd4_dec)nfsd4_decode_locku,
1366	[OP_LOOKUP]		= (nfsd4_dec)nfsd4_decode_lookup,
1367	[OP_LOOKUPP]		= (nfsd4_dec)nfsd4_decode_noop,
1368	[OP_NVERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
1369	[OP_OPEN]		= (nfsd4_dec)nfsd4_decode_open,
1370	[OP_OPENATTR]		= (nfsd4_dec)nfsd4_decode_notsupp,
1371	[OP_OPEN_CONFIRM]	= (nfsd4_dec)nfsd4_decode_open_confirm,
1372	[OP_OPEN_DOWNGRADE]	= (nfsd4_dec)nfsd4_decode_open_downgrade,
1373	[OP_PUTFH]		= (nfsd4_dec)nfsd4_decode_putfh,
1374	[OP_PUTPUBFH]		= (nfsd4_dec)nfsd4_decode_noop,
1375	[OP_PUTROOTFH]		= (nfsd4_dec)nfsd4_decode_noop,
1376	[OP_READ]		= (nfsd4_dec)nfsd4_decode_read,
1377	[OP_READDIR]		= (nfsd4_dec)nfsd4_decode_readdir,
1378	[OP_READLINK]		= (nfsd4_dec)nfsd4_decode_noop,
1379	[OP_REMOVE]		= (nfsd4_dec)nfsd4_decode_remove,
1380	[OP_RENAME]		= (nfsd4_dec)nfsd4_decode_rename,
1381	[OP_RENEW]		= (nfsd4_dec)nfsd4_decode_renew,
1382	[OP_RESTOREFH]		= (nfsd4_dec)nfsd4_decode_noop,
1383	[OP_SAVEFH]		= (nfsd4_dec)nfsd4_decode_noop,
1384	[OP_SECINFO]		= (nfsd4_dec)nfsd4_decode_secinfo,
1385	[OP_SETATTR]		= (nfsd4_dec)nfsd4_decode_setattr,
1386	[OP_SETCLIENTID]	= (nfsd4_dec)nfsd4_decode_setclientid,
1387	[OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
1388	[OP_VERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
1389	[OP_WRITE]		= (nfsd4_dec)nfsd4_decode_write,
1390	[OP_RELEASE_LOCKOWNER]	= (nfsd4_dec)nfsd4_decode_release_lockowner,
1391};
1392
1393static nfsd4_dec nfsd41_dec_ops[] = {
1394	[OP_ACCESS]		= (nfsd4_dec)nfsd4_decode_access,
1395	[OP_CLOSE]		= (nfsd4_dec)nfsd4_decode_close,
1396	[OP_COMMIT]		= (nfsd4_dec)nfsd4_decode_commit,
1397	[OP_CREATE]		= (nfsd4_dec)nfsd4_decode_create,
1398	[OP_DELEGPURGE]		= (nfsd4_dec)nfsd4_decode_notsupp,
1399	[OP_DELEGRETURN]	= (nfsd4_dec)nfsd4_decode_delegreturn,
1400	[OP_GETATTR]		= (nfsd4_dec)nfsd4_decode_getattr,
1401	[OP_GETFH]		= (nfsd4_dec)nfsd4_decode_noop,
1402	[OP_LINK]		= (nfsd4_dec)nfsd4_decode_link,
1403	[OP_LOCK]		= (nfsd4_dec)nfsd4_decode_lock,
1404	[OP_LOCKT]		= (nfsd4_dec)nfsd4_decode_lockt,
1405	[OP_LOCKU]		= (nfsd4_dec)nfsd4_decode_locku,
1406	[OP_LOOKUP]		= (nfsd4_dec)nfsd4_decode_lookup,
1407	[OP_LOOKUPP]		= (nfsd4_dec)nfsd4_decode_noop,
1408	[OP_NVERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
1409	[OP_OPEN]		= (nfsd4_dec)nfsd4_decode_open,
1410	[OP_OPENATTR]		= (nfsd4_dec)nfsd4_decode_notsupp,
1411	[OP_OPEN_CONFIRM]	= (nfsd4_dec)nfsd4_decode_notsupp,
1412	[OP_OPEN_DOWNGRADE]	= (nfsd4_dec)nfsd4_decode_open_downgrade,
1413	[OP_PUTFH]		= (nfsd4_dec)nfsd4_decode_putfh,
1414	[OP_PUTPUBFH]		= (nfsd4_dec)nfsd4_decode_notsupp,
1415	[OP_PUTROOTFH]		= (nfsd4_dec)nfsd4_decode_noop,
1416	[OP_READ]		= (nfsd4_dec)nfsd4_decode_read,
1417	[OP_READDIR]		= (nfsd4_dec)nfsd4_decode_readdir,
1418	[OP_READLINK]		= (nfsd4_dec)nfsd4_decode_noop,
1419	[OP_REMOVE]		= (nfsd4_dec)nfsd4_decode_remove,
1420	[OP_RENAME]		= (nfsd4_dec)nfsd4_decode_rename,
1421	[OP_RENEW]		= (nfsd4_dec)nfsd4_decode_notsupp,
1422	[OP_RESTOREFH]		= (nfsd4_dec)nfsd4_decode_noop,
1423	[OP_SAVEFH]		= (nfsd4_dec)nfsd4_decode_noop,
1424	[OP_SECINFO]		= (nfsd4_dec)nfsd4_decode_secinfo,
1425	[OP_SETATTR]		= (nfsd4_dec)nfsd4_decode_setattr,
1426	[OP_SETCLIENTID]	= (nfsd4_dec)nfsd4_decode_notsupp,
1427	[OP_SETCLIENTID_CONFIRM]= (nfsd4_dec)nfsd4_decode_notsupp,
1428	[OP_VERIFY]		= (nfsd4_dec)nfsd4_decode_verify,
1429	[OP_WRITE]		= (nfsd4_dec)nfsd4_decode_write,
1430	[OP_RELEASE_LOCKOWNER]	= (nfsd4_dec)nfsd4_decode_notsupp,
1431
1432	/* new operations for NFSv4.1 */
1433	[OP_BACKCHANNEL_CTL]	= (nfsd4_dec)nfsd4_decode_notsupp,
1434	[OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1435	[OP_EXCHANGE_ID]	= (nfsd4_dec)nfsd4_decode_exchange_id,
1436	[OP_CREATE_SESSION]	= (nfsd4_dec)nfsd4_decode_create_session,
1437	[OP_DESTROY_SESSION]	= (nfsd4_dec)nfsd4_decode_destroy_session,
1438	[OP_FREE_STATEID]	= (nfsd4_dec)nfsd4_decode_free_stateid,
1439	[OP_GET_DIR_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
 
 
 
 
 
 
 
1440	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_notsupp,
1441	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
1442	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_notsupp,
1443	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_notsupp,
1444	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_notsupp,
 
1445	[OP_SECINFO_NO_NAME]	= (nfsd4_dec)nfsd4_decode_secinfo_no_name,
1446	[OP_SEQUENCE]		= (nfsd4_dec)nfsd4_decode_sequence,
1447	[OP_SET_SSV]		= (nfsd4_dec)nfsd4_decode_notsupp,
1448	[OP_TEST_STATEID]	= (nfsd4_dec)nfsd4_decode_test_stateid,
1449	[OP_WANT_DELEGATION]	= (nfsd4_dec)nfsd4_decode_notsupp,
1450	[OP_DESTROY_CLIENTID]	= (nfsd4_dec)nfsd4_decode_notsupp,
1451	[OP_RECLAIM_COMPLETE]	= (nfsd4_dec)nfsd4_decode_reclaim_complete,
1452};
1453
1454struct nfsd4_minorversion_ops {
1455	nfsd4_dec *decoders;
1456	int nops;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1457};
1458
1459static struct nfsd4_minorversion_ops nfsd4_minorversion[] = {
1460	[0] = { nfsd4_dec_ops, ARRAY_SIZE(nfsd4_dec_ops) },
1461	[1] = { nfsd41_dec_ops, ARRAY_SIZE(nfsd41_dec_ops) },
1462};
 
 
 
 
 
 
 
 
 
1463
1464static __be32
1465nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1466{
1467	DECODE_HEAD;
1468	struct nfsd4_op *op;
1469	struct nfsd4_minorversion_ops *ops;
1470	bool cachethis = false;
 
 
 
 
 
1471	int i;
1472
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1473	/*
1474	 * XXX: According to spec, we should check the tag
1475	 * for UTF-8 compliance.  I'm postponing this for
1476	 * now because it seems that some clients do use
1477	 * binary tags.
1478	 */
1479	READ_BUF(4);
1480	READ32(argp->taglen);
1481	READ_BUF(argp->taglen + 8);
1482	SAVEMEM(argp->tag, argp->taglen);
1483	READ32(argp->minorversion);
1484	READ32(argp->opcnt);
1485
1486	if (argp->taglen > NFSD4_MAX_TAGLEN)
1487		goto xdr_error;
1488	if (argp->opcnt > 100)
1489		goto xdr_error;
1490
1491	if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
1492		argp->ops = kmalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
1493		if (!argp->ops) {
1494			argp->ops = argp->iops;
1495			dprintk("nfsd: couldn't allocate room for COMPOUND\n");
1496			goto xdr_error;
1497		}
1498	}
1499
1500	if (argp->minorversion >= ARRAY_SIZE(nfsd4_minorversion))
1501		argp->opcnt = 0;
1502
1503	ops = &nfsd4_minorversion[argp->minorversion];
1504	for (i = 0; i < argp->opcnt; i++) {
1505		op = &argp->ops[i];
1506		op->replay = NULL;
1507
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1508		/*
1509		 * We can't use READ_BUF() here because we need to handle
1510		 * a missing opcode as an OP_WRITE + 1. So we need to check
1511		 * to see if we're truly at the end of our buffer or if there
1512		 * is another page we need to flip to.
1513		 */
 
1514
1515		if (argp->p == argp->end) {
1516			if (argp->pagelen < 4) {
1517				/* There isn't an opcode still on the wire */
1518				op->opnum = OP_WRITE + 1;
1519				op->status = nfserr_bad_xdr;
1520				argp->opcnt = i+1;
1521				break;
1522			}
1523
1524			/*
1525			 * False alarm. We just hit a page boundary, but there
1526			 * is still data available.  Move pointer across page
1527			 * boundary.  *snip from READ_BUF*
1528			 */
1529			argp->p = page_address(argp->pagelist[0]);
1530			argp->pagelist++;
1531			if (argp->pagelen < PAGE_SIZE) {
1532				argp->end = argp->p + (argp->pagelen>>2);
1533				argp->pagelen = 0;
1534			} else {
1535				argp->end = argp->p + (PAGE_SIZE>>2);
1536				argp->pagelen -= PAGE_SIZE;
1537			}
1538		}
1539		op->opnum = ntohl(*argp->p++);
1540
1541		if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
1542			op->status = ops->decoders[op->opnum](argp, &op->u);
1543		else {
1544			op->opnum = OP_ILLEGAL;
1545			op->status = nfserr_op_illegal;
1546		}
1547
1548		if (op->status) {
1549			argp->opcnt = i+1;
1550			break;
1551		}
1552		/*
1553		 * We'll try to cache the result in the DRC if any one
1554		 * op in the compound wants to be cached:
1555		 */
1556		cachethis |= nfsd4_cache_this_op(op);
1557	}
1558	/* Sessions make the DRC unnecessary: */
1559	if (argp->minorversion)
1560		cachethis = false;
 
1561	argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
1562
1563	DECODE_TAIL;
 
 
 
1564}
1565
1566#define WRITE32(n)               *p++ = htonl(n)
1567#define WRITE64(n)               do {				\
1568	*p++ = htonl((u32)((n) >> 32));				\
1569	*p++ = htonl((u32)(n));					\
1570} while (0)
1571#define WRITEMEM(ptr,nbytes)     do { if (nbytes > 0) {		\
1572	*(p + XDR_QUADLEN(nbytes) -1) = 0;                      \
1573	memcpy(p, ptr, nbytes);					\
1574	p += XDR_QUADLEN(nbytes);				\
1575}} while (0)
1576
1577static void write32(__be32 **p, u32 n)
1578{
1579	*(*p)++ = n;
 
 
 
 
 
1580}
1581
1582static void write64(__be32 **p, u64 n)
 
 
 
 
 
 
 
 
 
 
 
1583{
1584	write32(p, (u32)(n >> 32));
1585	write32(p, (u32)n);
1586}
 
 
 
 
 
1587
1588static void write_change(__be32 **p, struct kstat *stat, struct inode *inode)
1589{
1590	if (IS_I_VERSION(inode)) {
1591		write64(p, inode->i_version);
1592	} else {
1593		write32(p, stat->ctime.tv_sec);
1594		write32(p, stat->ctime.tv_nsec);
1595	}
1596}
1597
1598static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
1599{
1600	write32(p, c->atomic);
1601	if (c->change_supported) {
1602		write64(p, c->before_change);
1603		write64(p, c->after_change);
1604	} else {
1605		write32(p, c->before_ctime_sec);
1606		write32(p, c->before_ctime_nsec);
1607		write32(p, c->after_ctime_sec);
1608		write32(p, c->after_ctime_nsec);
1609	}
1610}
1611
1612#define RESERVE_SPACE(nbytes)	do {				\
1613	p = resp->p;						\
1614	BUG_ON(p + XDR_QUADLEN(nbytes) > resp->end);		\
1615} while (0)
1616#define ADJUST_ARGS()		resp->p = p
1617
1618/*
1619 * Header routine to setup seqid operation replay cache
1620 */
1621#define ENCODE_SEQID_OP_HEAD					\
1622	__be32 *save;						\
1623								\
1624	save = resp->p;
1625
1626/*
1627 * Routine for encoding the result of a "seqid-mutating" NFSv4 operation.  This
1628 * is where sequence id's are incremented, and the replay cache is filled.
1629 * Note that we increment sequence id's here, at the last moment, so we're sure
1630 * we know whether the error to be returned is a sequence id mutating error.
1631 */
1632
1633#define ENCODE_SEQID_OP_TAIL(stateowner) do {			\
1634	if (seqid_mutating_err(nfserr) && stateowner) { 	\
1635		stateowner->so_seqid++;				\
1636		stateowner->so_replay.rp_status = nfserr;   	\
1637		stateowner->so_replay.rp_buflen = 		\
1638			  (((char *)(resp)->p - (char *)save)); \
1639		memcpy(stateowner->so_replay.rp_buf, save,      \
1640 			stateowner->so_replay.rp_buflen); 	\
1641	} } while (0);
1642
1643/* Encode as an array of strings the string given with components
1644 * separated @sep.
1645 */
1646static __be32 nfsd4_encode_components(char sep, char *components,
1647				   __be32 **pp, int *buflen)
 
1648{
1649	__be32 *p = *pp;
1650	__be32 *countp = p;
 
1651	int strlen, count=0;
1652	char *str, *end;
1653
1654	dprintk("nfsd4_encode_components(%s)\n", components);
1655	if ((*buflen -= 4) < 0)
 
 
 
1656		return nfserr_resource;
1657	WRITE32(0); /* We will fill this in with @count later */
 
1658	end = str = components;
1659	while (*end) {
1660		for (; *end && (*end != sep); end++)
1661			; /* Point to end of component */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1662		strlen = end - str;
1663		if (strlen) {
1664			if ((*buflen -= ((XDR_QUADLEN(strlen) << 2) + 4)) < 0)
 
1665				return nfserr_resource;
1666			WRITE32(strlen);
1667			WRITEMEM(str, strlen);
1668			count++;
1669		}
1670		else
1671			end++;
 
 
 
1672		str = end;
1673	}
1674	*pp = p;
1675	p = countp;
1676	WRITE32(count);
1677	return 0;
1678}
1679
 
 
 
 
 
 
 
 
 
1680/*
1681 * encode a location element of a fs_locations structure
1682 */
1683static __be32 nfsd4_encode_fs_location4(struct nfsd4_fs_location *location,
1684				    __be32 **pp, int *buflen)
1685{
1686	__be32 status;
1687	__be32 *p = *pp;
1688
1689	status = nfsd4_encode_components(':', location->hosts, &p, buflen);
 
1690	if (status)
1691		return status;
1692	status = nfsd4_encode_components('/', location->path, &p, buflen);
1693	if (status)
1694		return status;
1695	*pp = p;
1696	return 0;
1697}
1698
1699/*
1700 * Return the path to an export point in the pseudo filesystem namespace
1701 * Returned string is safe to use as long as the caller holds a reference
1702 * to @exp.
1703 */
1704static char *nfsd4_path(struct svc_rqst *rqstp, struct svc_export *exp, __be32 *stat)
 
 
1705{
1706	struct svc_fh tmp_fh;
1707	char *path = NULL, *rootpath;
1708	size_t rootlen;
1709
1710	fh_init(&tmp_fh, NFS4_FHSIZE);
1711	*stat = exp_pseudoroot(rqstp, &tmp_fh);
1712	if (*stat)
1713		return NULL;
1714	rootpath = tmp_fh.fh_export->ex_pathname;
1715
1716	path = exp->ex_pathname;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1717
1718	rootlen = strlen(rootpath);
1719	if (strncmp(path, rootpath, rootlen)) {
1720		dprintk("nfsd: fs_locations failed;"
1721			"%s is not contained in %s\n", path, rootpath);
1722		*stat = nfserr_notsupp;
1723		path = NULL;
1724		goto out;
1725	}
1726	path += rootlen;
1727out:
1728	fh_put(&tmp_fh);
1729	return path;
 
 
 
 
 
 
 
 
 
 
1730}
1731
1732/*
1733 *  encode a fs_locations structure
1734 */
1735static __be32 nfsd4_encode_fs_locations(struct svc_rqst *rqstp,
1736				     struct svc_export *exp,
1737				     __be32 **pp, int *buflen)
1738{
1739	__be32 status;
1740	int i;
1741	__be32 *p = *pp;
1742	struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
1743	char *root = nfsd4_path(rqstp, exp, &status);
1744
 
1745	if (status)
1746		return status;
1747	status = nfsd4_encode_components('/', root, &p, buflen);
1748	if (status)
1749		return status;
1750	if ((*buflen -= 4) < 0)
1751		return nfserr_resource;
1752	WRITE32(fslocs->locations_count);
1753	for (i=0; i<fslocs->locations_count; i++) {
1754		status = nfsd4_encode_fs_location4(&fslocs->locations[i],
1755						   &p, buflen);
1756		if (status)
1757			return status;
1758	}
1759	*pp = p;
1760	return 0;
1761}
1762
1763static u32 nfs4_ftypes[16] = {
1764        NF4BAD,  NF4FIFO, NF4CHR, NF4BAD,
1765        NF4DIR,  NF4BAD,  NF4BLK, NF4BAD,
1766        NF4REG,  NF4BAD,  NF4LNK, NF4BAD,
1767        NF4SOCK, NF4BAD,  NF4LNK, NF4BAD,
1768};
1769
1770static __be32
1771nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1772			__be32 **p, int *buflen)
1773{
1774	int status;
1775
1776	if (*buflen < (XDR_QUADLEN(IDMAP_NAMESZ) << 2) + 4)
1777		return nfserr_resource;
1778	if (whotype != NFS4_ACL_WHO_NAMED)
1779		status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
1780	else if (group)
1781		status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1));
1782	else
1783		status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1));
1784	if (status < 0)
1785		return nfserrno(status);
1786	*p = xdr_encode_opaque(*p, NULL, status);
1787	*buflen -= (XDR_QUADLEN(status) << 2) + 4;
1788	BUG_ON(*buflen < 0);
1789	return 0;
1790}
1791
1792static inline __be32
1793nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen)
 
1794{
1795	return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen);
 
 
 
 
 
1796}
1797
1798static inline __be32
1799nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen)
1800{
1801	return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen);
1802}
 
 
 
 
 
 
 
 
 
 
1803
1804static inline __be32
1805nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1806		__be32 **p, int *buflen)
1807{
1808	return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen);
1809}
1810
1811#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
1812			      FATTR4_WORD0_RDATTR_ERROR)
1813#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1814
1815static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *rdattr_err)
1816{
1817	/* As per referral draft:  */
1818	if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
1819	    *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
1820		if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
1821	            *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
1822			*rdattr_err = NFSERR_MOVED;
1823		else
1824			return nfserr_moved;
1825	}
1826	*bmval0 &= WORD0_ABSENT_FS_ATTRS;
1827	*bmval1 &= WORD1_ABSENT_FS_ATTRS;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1828	return 0;
 
 
1829}
1830
1831/*
1832 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
1833 * ourselves.
1834 *
1835 * @countp is the buffer size in _words_; upon successful return this becomes
1836 * replaced with the number of words written.
1837 */
1838__be32
1839nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1840		struct dentry *dentry, __be32 *buffer, int *countp, u32 *bmval,
 
1841		struct svc_rqst *rqstp, int ignore_crossmnt)
1842{
1843	u32 bmval0 = bmval[0];
1844	u32 bmval1 = bmval[1];
1845	u32 bmval2 = bmval[2];
1846	struct kstat stat;
1847	struct svc_fh tempfh;
1848	struct kstatfs statfs;
1849	int buflen = *countp << 2;
1850	__be32 *attrlenp;
 
 
1851	u32 dummy;
1852	u64 dummy64;
1853	u32 rdattr_err = 0;
1854	__be32 *p = buffer;
1855	__be32 status;
1856	int err;
1857	int aclsupport = 0;
1858	struct nfs4_acl *acl = NULL;
 
 
 
 
 
1859	struct nfsd4_compoundres *resp = rqstp->rq_resp;
1860	u32 minorversion = resp->cstate.minorversion;
1861	struct path path = {
1862		.mnt	= exp->ex_path.mnt,
1863		.dentry	= dentry,
1864	};
 
1865
1866	BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
1867	BUG_ON(bmval0 & ~nfsd_suppattrs0(minorversion));
1868	BUG_ON(bmval1 & ~nfsd_suppattrs1(minorversion));
1869	BUG_ON(bmval2 & ~nfsd_suppattrs2(minorversion));
1870
1871	if (exp->ex_fslocs.migrated) {
1872		BUG_ON(bmval[2]);
1873		status = fattr_handle_absent_fs(&bmval0, &bmval1, &rdattr_err);
1874		if (status)
1875			goto out;
1876	}
1877
1878	err = vfs_getattr(exp->ex_path.mnt, dentry, &stat);
1879	if (err)
1880		goto out_nfserr;
1881	if ((bmval0 & (FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL |
1882			FATTR4_WORD0_MAXNAME)) ||
1883	    (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
1884		       FATTR4_WORD1_SPACE_TOTAL))) {
1885		err = vfs_statfs(&path, &statfs);
1886		if (err)
1887			goto out_nfserr;
1888	}
1889	if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
1890		fh_init(&tempfh, NFS4_FHSIZE);
1891		status = fh_compose(&tempfh, exp, dentry, NULL);
 
 
 
 
1892		if (status)
1893			goto out;
1894		fhp = &tempfh;
1895	}
1896	if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
1897			| FATTR4_WORD0_SUPPORTED_ATTRS)) {
1898		err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
1899		aclsupport = (err == 0);
1900		if (bmval0 & FATTR4_WORD0_ACL) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1901			if (err == -EOPNOTSUPP)
1902				bmval0 &= ~FATTR4_WORD0_ACL;
1903			else if (err == -EINVAL) {
1904				status = nfserr_attrnotsupp;
1905				goto out;
1906			} else if (err != 0)
1907				goto out_nfserr;
1908		}
1909	}
 
1910
1911	if (bmval2) {
1912		if ((buflen -= 16) < 0)
1913			goto out_resource;
1914		WRITE32(3);
1915		WRITE32(bmval0);
1916		WRITE32(bmval1);
1917		WRITE32(bmval2);
1918	} else if (bmval1) {
1919		if ((buflen -= 12) < 0)
1920			goto out_resource;
1921		WRITE32(2);
1922		WRITE32(bmval0);
1923		WRITE32(bmval1);
1924	} else {
1925		if ((buflen -= 8) < 0)
1926			goto out_resource;
1927		WRITE32(1);
1928		WRITE32(bmval0);
1929	}
1930	attrlenp = p++;                /* to be backfilled later */
1931
1932	if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
1933		u32 word0 = nfsd_suppattrs0(minorversion);
1934		u32 word1 = nfsd_suppattrs1(minorversion);
1935		u32 word2 = nfsd_suppattrs2(minorversion);
1936
1937		if (!aclsupport)
1938			word0 &= ~FATTR4_WORD0_ACL;
1939		if (!word2) {
1940			if ((buflen -= 12) < 0)
 
 
 
1941				goto out_resource;
1942			WRITE32(2);
1943			WRITE32(word0);
1944			WRITE32(word1);
1945		} else {
1946			if ((buflen -= 16) < 0)
 
1947				goto out_resource;
1948			WRITE32(3);
1949			WRITE32(word0);
1950			WRITE32(word1);
1951			WRITE32(word2);
1952		}
1953	}
1954	if (bmval0 & FATTR4_WORD0_TYPE) {
1955		if ((buflen -= 4) < 0)
 
1956			goto out_resource;
1957		dummy = nfs4_ftypes[(stat.mode & S_IFMT) >> 12];
1958		if (dummy == NF4BAD)
1959			goto out_serverfault;
1960		WRITE32(dummy);
 
 
1961	}
1962	if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
1963		if ((buflen -= 4) < 0)
 
1964			goto out_resource;
1965		if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
1966			WRITE32(NFS4_FH_PERSISTENT);
1967		else
1968			WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
 
1969	}
1970	if (bmval0 & FATTR4_WORD0_CHANGE) {
1971		if ((buflen -= 8) < 0)
 
1972			goto out_resource;
1973		write_change(&p, &stat, dentry->d_inode);
1974	}
1975	if (bmval0 & FATTR4_WORD0_SIZE) {
1976		if ((buflen -= 8) < 0)
 
1977			goto out_resource;
1978		WRITE64(stat.size);
1979	}
1980	if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
1981		if ((buflen -= 4) < 0)
 
1982			goto out_resource;
1983		WRITE32(1);
1984	}
1985	if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
1986		if ((buflen -= 4) < 0)
 
1987			goto out_resource;
1988		WRITE32(1);
1989	}
1990	if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
1991		if ((buflen -= 4) < 0)
 
1992			goto out_resource;
1993		WRITE32(0);
1994	}
1995	if (bmval0 & FATTR4_WORD0_FSID) {
1996		if ((buflen -= 16) < 0)
 
1997			goto out_resource;
1998		if (exp->ex_fslocs.migrated) {
1999			WRITE64(NFS4_REFERRAL_FSID_MAJOR);
2000			WRITE64(NFS4_REFERRAL_FSID_MINOR);
2001		} else switch(fsid_source(fhp)) {
2002		case FSIDSOURCE_FSID:
2003			WRITE64((u64)exp->ex_fsid);
2004			WRITE64((u64)0);
2005			break;
2006		case FSIDSOURCE_DEV:
2007			WRITE32(0);
2008			WRITE32(MAJOR(stat.dev));
2009			WRITE32(0);
2010			WRITE32(MINOR(stat.dev));
2011			break;
2012		case FSIDSOURCE_UUID:
2013			WRITEMEM(exp->ex_uuid, 16);
 
2014			break;
2015		}
2016	}
2017	if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
2018		if ((buflen -= 4) < 0)
 
2019			goto out_resource;
2020		WRITE32(0);
2021	}
2022	if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2023		if ((buflen -= 4) < 0)
 
2024			goto out_resource;
2025		WRITE32(nfsd4_lease);
2026	}
2027	if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2028		if ((buflen -= 4) < 0)
 
2029			goto out_resource;
2030		WRITE32(rdattr_err);
2031	}
2032	if (bmval0 & FATTR4_WORD0_ACL) {
2033		struct nfs4_ace *ace;
2034
2035		if (acl == NULL) {
2036			if ((buflen -= 4) < 0)
 
2037				goto out_resource;
2038
2039			WRITE32(0);
2040			goto out_acl;
2041		}
2042		if ((buflen -= 4) < 0)
 
2043			goto out_resource;
2044		WRITE32(acl->naces);
2045
2046		for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
2047			if ((buflen -= 4*3) < 0)
2048				goto out_resource;
2049			WRITE32(ace->type);
2050			WRITE32(ace->flag);
2051			WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
2052			status = nfsd4_encode_aclname(rqstp, ace->whotype,
2053				ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP,
2054				&p, &buflen);
2055			if (status == nfserr_resource)
2056				goto out_resource;
 
 
 
 
 
2057			if (status)
2058				goto out;
2059		}
2060	}
2061out_acl:
2062	if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
2063		if ((buflen -= 4) < 0)
 
2064			goto out_resource;
2065		WRITE32(aclsupport ?
2066			ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
2067	}
2068	if (bmval0 & FATTR4_WORD0_CANSETTIME) {
2069		if ((buflen -= 4) < 0)
 
2070			goto out_resource;
2071		WRITE32(1);
2072	}
2073	if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2074		if ((buflen -= 4) < 0)
 
2075			goto out_resource;
2076		WRITE32(1);
2077	}
2078	if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2079		if ((buflen -= 4) < 0)
 
2080			goto out_resource;
2081		WRITE32(1);
2082	}
2083	if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
2084		if ((buflen -= 4) < 0)
 
2085			goto out_resource;
2086		WRITE32(1);
2087	}
2088	if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
2089		buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4;
2090		if (buflen < 0)
2091			goto out_resource;
2092		WRITE32(fhp->fh_handle.fh_size);
2093		WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size);
2094	}
2095	if (bmval0 & FATTR4_WORD0_FILEID) {
2096		if ((buflen -= 8) < 0)
 
2097			goto out_resource;
2098		WRITE64(stat.ino);
2099	}
2100	if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
2101		if ((buflen -= 8) < 0)
 
2102			goto out_resource;
2103		WRITE64((u64) statfs.f_ffree);
2104	}
2105	if (bmval0 & FATTR4_WORD0_FILES_FREE) {
2106		if ((buflen -= 8) < 0)
 
2107			goto out_resource;
2108		WRITE64((u64) statfs.f_ffree);
2109	}
2110	if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
2111		if ((buflen -= 8) < 0)
 
2112			goto out_resource;
2113		WRITE64((u64) statfs.f_files);
2114	}
2115	if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2116		status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);
2117		if (status == nfserr_resource)
2118			goto out_resource;
2119		if (status)
2120			goto out;
2121	}
2122	if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
2123		if ((buflen -= 4) < 0)
 
2124			goto out_resource;
2125		WRITE32(1);
2126	}
2127	if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
2128		if ((buflen -= 8) < 0)
 
2129			goto out_resource;
2130		WRITE64(~(u64)0);
2131	}
2132	if (bmval0 & FATTR4_WORD0_MAXLINK) {
2133		if ((buflen -= 4) < 0)
 
2134			goto out_resource;
2135		WRITE32(255);
2136	}
2137	if (bmval0 & FATTR4_WORD0_MAXNAME) {
2138		if ((buflen -= 4) < 0)
 
2139			goto out_resource;
2140		WRITE32(statfs.f_namelen);
2141	}
2142	if (bmval0 & FATTR4_WORD0_MAXREAD) {
2143		if ((buflen -= 8) < 0)
 
2144			goto out_resource;
2145		WRITE64((u64) svc_max_payload(rqstp));
2146	}
2147	if (bmval0 & FATTR4_WORD0_MAXWRITE) {
2148		if ((buflen -= 8) < 0)
 
2149			goto out_resource;
2150		WRITE64((u64) svc_max_payload(rqstp));
2151	}
2152	if (bmval1 & FATTR4_WORD1_MODE) {
2153		if ((buflen -= 4) < 0)
 
2154			goto out_resource;
2155		WRITE32(stat.mode & S_IALLUGO);
2156	}
2157	if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
2158		if ((buflen -= 4) < 0)
 
2159			goto out_resource;
2160		WRITE32(1);
2161	}
2162	if (bmval1 & FATTR4_WORD1_NUMLINKS) {
2163		if ((buflen -= 4) < 0)
 
2164			goto out_resource;
2165		WRITE32(stat.nlink);
2166	}
2167	if (bmval1 & FATTR4_WORD1_OWNER) {
2168		status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);
2169		if (status == nfserr_resource)
2170			goto out_resource;
2171		if (status)
2172			goto out;
2173	}
2174	if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2175		status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);
2176		if (status == nfserr_resource)
2177			goto out_resource;
2178		if (status)
2179			goto out;
2180	}
2181	if (bmval1 & FATTR4_WORD1_RAWDEV) {
2182		if ((buflen -= 8) < 0)
 
2183			goto out_resource;
2184		WRITE32((u32) MAJOR(stat.rdev));
2185		WRITE32((u32) MINOR(stat.rdev));
2186	}
2187	if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
2188		if ((buflen -= 8) < 0)
 
2189			goto out_resource;
2190		dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
2191		WRITE64(dummy64);
2192	}
2193	if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
2194		if ((buflen -= 8) < 0)
 
2195			goto out_resource;
2196		dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
2197		WRITE64(dummy64);
2198	}
2199	if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
2200		if ((buflen -= 8) < 0)
 
2201			goto out_resource;
2202		dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
2203		WRITE64(dummy64);
2204	}
2205	if (bmval1 & FATTR4_WORD1_SPACE_USED) {
2206		if ((buflen -= 8) < 0)
 
2207			goto out_resource;
2208		dummy64 = (u64)stat.blocks << 9;
2209		WRITE64(dummy64);
2210	}
2211	if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2212		if ((buflen -= 12) < 0)
 
2213			goto out_resource;
2214		WRITE32(0);
2215		WRITE32(stat.atime.tv_sec);
2216		WRITE32(stat.atime.tv_nsec);
2217	}
2218	if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
2219		if ((buflen -= 12) < 0)
 
2220			goto out_resource;
2221		WRITE32(0);
2222		WRITE32(1);
2223		WRITE32(0);
2224	}
2225	if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2226		if ((buflen -= 12) < 0)
 
2227			goto out_resource;
2228		WRITE32(0);
2229		WRITE32(stat.ctime.tv_sec);
2230		WRITE32(stat.ctime.tv_nsec);
2231	}
2232	if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2233		if ((buflen -= 12) < 0)
 
2234			goto out_resource;
2235		WRITE32(0);
2236		WRITE32(stat.mtime.tv_sec);
2237		WRITE32(stat.mtime.tv_nsec);
2238	}
2239	if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
2240		if ((buflen -= 8) < 0)
 
 
 
 
2241                	goto out_resource;
2242		/*
2243		 * Get parent's attributes if not ignoring crossmount
2244		 * and this is the root of a cross-mounted filesystem.
2245		 */
2246		if (ignore_crossmnt == 0 &&
2247		    dentry == exp->ex_path.mnt->mnt_root) {
2248			struct path path = exp->ex_path;
2249			path_get(&path);
2250			while (follow_up(&path)) {
2251				if (path.dentry != path.mnt->mnt_root)
2252					break;
2253			}
2254			err = vfs_getattr(path.mnt, path.dentry, &stat);
2255			path_put(&path);
2256			if (err)
2257				goto out_nfserr;
 
2258		}
2259		WRITE64(stat.ino);
 
 
 
 
 
 
2260	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2261	if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2262		WRITE32(3);
2263		WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD0);
2264		WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD1);
2265		WRITE32(NFSD_SUPPATTR_EXCLCREAT_WORD2);
 
 
 
 
 
 
2266	}
2267
2268	*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2269	*countp = p - buffer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2270	status = nfs_ok;
2271
2272out:
 
 
 
 
2273	kfree(acl);
2274	if (fhp == &tempfh)
2275		fh_put(&tempfh);
 
 
 
 
2276	return status;
2277out_nfserr:
2278	status = nfserrno(err);
2279	goto out;
2280out_resource:
2281	*countp = 0;
2282	status = nfserr_resource;
2283	goto out;
2284out_serverfault:
2285	status = nfserr_serverfault;
2286	goto out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2287}
2288
2289static inline int attributes_need_mount(u32 *bmval)
2290{
2291	if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
2292		return 1;
2293	if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
2294		return 1;
2295	return 0;
2296}
2297
2298static __be32
2299nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2300		const char *name, int namlen, __be32 *p, int *buflen)
2301{
2302	struct svc_export *exp = cd->rd_fhp->fh_export;
2303	struct dentry *dentry;
2304	__be32 nfserr;
2305	int ignore_crossmnt = 0;
2306
2307	dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
2308	if (IS_ERR(dentry))
2309		return nfserrno(PTR_ERR(dentry));
2310	if (!dentry->d_inode) {
2311		/*
2312		 * nfsd_buffered_readdir drops the i_mutex between
2313		 * readdir and calling this callback, leaving a window
2314		 * where this directory entry could have gone away.
2315		 */
2316		dput(dentry);
2317		return nfserr_noent;
2318	}
2319
2320	exp_get(exp);
2321	/*
2322	 * In the case of a mountpoint, the client may be asking for
2323	 * attributes that are only properties of the underlying filesystem
2324	 * as opposed to the cross-mounted file system. In such a case,
2325	 * we will not follow the cross mount and will fill the attribtutes
2326	 * directly from the mountpoint dentry.
2327	 */
2328	if (nfsd_mountpoint(dentry, exp)) {
2329		int err;
2330
2331		if (!(exp->ex_flags & NFSEXP_V4ROOT)
2332				&& !attributes_need_mount(cd->rd_bmval)) {
2333			ignore_crossmnt = 1;
2334			goto out_encode;
2335		}
2336		/*
2337		 * Why the heck aren't we just using nfsd_lookup??
2338		 * Different "."/".." handling?  Something else?
2339		 * At least, add a comment here to explain....
2340		 */
2341		err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
2342		if (err) {
2343			nfserr = nfserrno(err);
2344			goto out_put;
2345		}
2346		nfserr = check_nfsd_access(exp, cd->rd_rqstp);
2347		if (nfserr)
2348			goto out_put;
2349
2350	}
2351out_encode:
2352	nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
2353					cd->rd_rqstp, ignore_crossmnt);
2354out_put:
2355	dput(dentry);
2356	exp_put(exp);
2357	return nfserr;
2358}
2359
2360static __be32 *
2361nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
2362{
2363	__be32 *attrlenp;
2364
2365	if (buflen < 6)
 
2366		return NULL;
2367	*p++ = htonl(2);
2368	*p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
2369	*p++ = htonl(0);			 /* bmval1 */
2370
2371	attrlenp = p++;
2372	*p++ = nfserr;       /* no htonl */
2373	*attrlenp = htonl((char *)p - (char *)attrlenp - 4);
2374	return p;
2375}
2376
2377static int
2378nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
2379		    loff_t offset, u64 ino, unsigned int d_type)
2380{
2381	struct readdir_cd *ccd = ccdv;
2382	struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
2383	int buflen;
2384	__be32 *p = cd->buffer;
2385	__be32 *cookiep;
 
 
2386	__be32 nfserr = nfserr_toosmall;
 
 
2387
2388	/* In nfsv4, "." and ".." never make it onto the wire.. */
2389	if (name && isdotent(name, namlen)) {
2390		cd->common.err = nfs_ok;
2391		return 0;
2392	}
2393
2394	if (cd->offset)
2395		xdr_encode_hyper(cd->offset, (u64) offset);
 
 
 
2396
2397	buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);
2398	if (buflen < 0)
2399		goto fail;
2400
2401	*p++ = xdr_one;                             /* mark entry present */
2402	cookiep = p;
 
 
 
2403	p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
2404	p = xdr_encode_array(p, name, namlen);      /* name length & name */
2405
2406	nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen);
2407	switch (nfserr) {
2408	case nfs_ok:
2409		p += buflen;
2410		break;
2411	case nfserr_resource:
2412		nfserr = nfserr_toosmall;
2413		goto fail;
2414	case nfserr_noent:
 
2415		goto skip_entry;
2416	default:
2417		/*
2418		 * If the client requested the RDATTR_ERROR attribute,
2419		 * we stuff the error code into this attribute
2420		 * and continue.  If this attribute was not requested,
2421		 * then in accordance with the spec, we fail the
2422		 * entire READDIR operation(!)
2423		 */
2424		if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
2425			goto fail;
2426		p = nfsd4_encode_rdattr_error(p, buflen, nfserr);
2427		if (p == NULL) {
2428			nfserr = nfserr_toosmall;
2429			goto fail;
2430		}
2431	}
2432	cd->buflen -= (p - cd->buffer);
2433	cd->buffer = p;
2434	cd->offset = cookiep;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2435skip_entry:
2436	cd->common.err = nfs_ok;
2437	return 0;
2438fail:
 
2439	cd->common.err = nfserr;
2440	return -EINVAL;
2441}
2442
2443static void
2444nfsd4_encode_stateid(struct nfsd4_compoundres *resp, stateid_t *sid)
2445{
2446	__be32 *p;
2447
2448	RESERVE_SPACE(sizeof(stateid_t));
2449	WRITE32(sid->si_generation);
2450	WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
2451	ADJUST_ARGS();
 
 
 
2452}
2453
2454static __be32
2455nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
2456{
 
2457	__be32 *p;
2458
2459	if (!nfserr) {
2460		RESERVE_SPACE(8);
2461		WRITE32(access->ac_supported);
2462		WRITE32(access->ac_resp_access);
2463		ADJUST_ARGS();
2464	}
2465	return nfserr;
2466}
2467
2468static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
2469{
 
2470	__be32 *p;
2471
2472	if (!nfserr) {
2473		RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
2474		WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
2475		WRITE32(bcts->dir);
2476		/* XXX: ? */
2477		WRITE32(0);
2478		ADJUST_ARGS();
2479	}
2480	return nfserr;
2481}
2482
2483static __be32
2484nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
2485{
2486	ENCODE_SEQID_OP_HEAD;
2487
2488	if (!nfserr)
2489		nfsd4_encode_stateid(resp, &close->cl_stateid);
2490
2491	ENCODE_SEQID_OP_TAIL(close->cl_stateowner);
2492	return nfserr;
2493}
2494
2495
2496static __be32
2497nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
2498{
 
2499	__be32 *p;
2500
2501	if (!nfserr) {
2502		RESERVE_SPACE(8);
2503		WRITEMEM(commit->co_verf.data, 8);
2504		ADJUST_ARGS();
2505	}
2506	return nfserr;
2507}
2508
2509static __be32
2510nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
2511{
 
2512	__be32 *p;
2513
2514	if (!nfserr) {
2515		RESERVE_SPACE(32);
2516		write_cinfo(&p, &create->cr_cinfo);
2517		WRITE32(2);
2518		WRITE32(create->cr_bmval[0]);
2519		WRITE32(create->cr_bmval[1]);
2520		ADJUST_ARGS();
2521	}
2522	return nfserr;
2523}
2524
2525static __be32
2526nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
2527{
2528	struct svc_fh *fhp = getattr->ga_fhp;
2529	int buflen;
2530
2531	if (nfserr)
2532		return nfserr;
2533
2534	buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);
2535	nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,
2536				    resp->p, &buflen, getattr->ga_bmval,
2537				    resp->rqstp, 0);
2538	if (!nfserr)
2539		resp->p += buflen;
2540	return nfserr;
2541}
2542
2543static __be32
2544nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
2545{
 
2546	struct svc_fh *fhp = *fhpp;
2547	unsigned int len;
2548	__be32 *p;
2549
2550	if (!nfserr) {
2551		len = fhp->fh_handle.fh_size;
2552		RESERVE_SPACE(len + 4);
2553		WRITE32(len);
2554		WRITEMEM(&fhp->fh_handle.fh_base, len);
2555		ADJUST_ARGS();
2556	}
2557	return nfserr;
2558}
2559
2560/*
2561* Including all fields other than the name, a LOCK4denied structure requires
2562*   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
2563*/
2564static void
2565nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld)
2566{
 
2567	__be32 *p;
2568
2569	RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0));
2570	WRITE64(ld->ld_start);
2571	WRITE64(ld->ld_length);
2572	WRITE32(ld->ld_type);
2573	if (ld->ld_sop) {
2574		WRITEMEM(&ld->ld_clientid, 8);
2575		WRITE32(ld->ld_sop->so_owner.len);
2576		WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len);
2577		kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner);
 
 
 
 
 
 
 
 
 
 
 
 
 
2578	}  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
2579		WRITE64((u64)0); /* clientid */
2580		WRITE32(0); /* length of owner name */
2581	}
2582	ADJUST_ARGS();
2583}
2584
2585static __be32
2586nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
2587{
2588	ENCODE_SEQID_OP_HEAD;
2589
2590	if (!nfserr)
2591		nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
2592	else if (nfserr == nfserr_denied)
2593		nfsd4_encode_lock_denied(resp, &lock->lk_denied);
2594
2595	ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);
2596	return nfserr;
2597}
2598
2599static __be32
2600nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
2601{
 
 
2602	if (nfserr == nfserr_denied)
2603		nfsd4_encode_lock_denied(resp, &lockt->lt_denied);
2604	return nfserr;
2605}
2606
2607static __be32
2608nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
2609{
2610	ENCODE_SEQID_OP_HEAD;
2611
2612	if (!nfserr)
2613		nfsd4_encode_stateid(resp, &locku->lu_stateid);
2614
2615	ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);
2616	return nfserr;
2617}
2618
2619
2620static __be32
2621nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
2622{
 
2623	__be32 *p;
2624
2625	if (!nfserr) {
2626		RESERVE_SPACE(20);
2627		write_cinfo(&p, &link->li_cinfo);
2628		ADJUST_ARGS();
2629	}
2630	return nfserr;
2631}
2632
2633
2634static __be32
2635nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
2636{
 
2637	__be32 *p;
2638	ENCODE_SEQID_OP_HEAD;
2639
 
2640	if (nfserr)
2641		goto out;
 
 
 
 
 
 
 
 
 
 
2642
2643	nfsd4_encode_stateid(resp, &open->op_stateid);
2644	RESERVE_SPACE(40);
2645	write_cinfo(&p, &open->op_cinfo);
2646	WRITE32(open->op_rflags);
2647	WRITE32(2);
2648	WRITE32(open->op_bmval[0]);
2649	WRITE32(open->op_bmval[1]);
2650	WRITE32(open->op_delegate_type);
2651	ADJUST_ARGS();
2652
 
2653	switch (open->op_delegate_type) {
2654	case NFS4_OPEN_DELEGATE_NONE:
2655		break;
2656	case NFS4_OPEN_DELEGATE_READ:
2657		nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2658		RESERVE_SPACE(20);
2659		WRITE32(open->op_recall);
 
 
 
 
2660
2661		/*
2662		 * TODO: ACE's in delegations
2663		 */
2664		WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2665		WRITE32(0);
2666		WRITE32(0);
2667		WRITE32(0);   /* XXX: is NULL principal ok? */
2668		ADJUST_ARGS();
2669		break;
2670	case NFS4_OPEN_DELEGATE_WRITE:
2671		nfsd4_encode_stateid(resp, &open->op_delegate_stateid);
2672		RESERVE_SPACE(32);
2673		WRITE32(0);
 
 
 
 
2674
2675		/*
2676		 * TODO: space_limit's in delegations
2677		 */
2678		WRITE32(NFS4_LIMIT_SIZE);
2679		WRITE32(~(u32)0);
2680		WRITE32(~(u32)0);
2681
2682		/*
2683		 * TODO: ACE's in delegations
2684		 */
2685		WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
2686		WRITE32(0);
2687		WRITE32(0);
2688		WRITE32(0);   /* XXX: is NULL principal ok? */
2689		ADJUST_ARGS();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2690		break;
2691	default:
2692		BUG();
2693	}
2694	/* XXX save filehandle here */
2695out:
2696	ENCODE_SEQID_OP_TAIL(open->op_stateowner);
2697	return nfserr;
2698}
2699
2700static __be32
2701nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
2702{
2703	ENCODE_SEQID_OP_HEAD;
2704
2705	if (!nfserr)
2706		nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
2707
2708	ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);
2709	return nfserr;
2710}
2711
2712static __be32
2713nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
2714{
2715	ENCODE_SEQID_OP_HEAD;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2716
2717	if (!nfserr)
2718		nfsd4_encode_stateid(resp, &od->od_stateid);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2719
2720	ENCODE_SEQID_OP_TAIL(od->od_stateowner);
 
 
 
 
 
 
2721	return nfserr;
2722}
2723
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2724static __be32
2725nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2726		  struct nfsd4_read *read)
2727{
2728	u32 eof;
2729	int v, pn;
2730	unsigned long maxcount; 
2731	long len;
2732	__be32 *p;
2733
2734	if (nfserr)
2735		return nfserr;
2736	if (resp->xbuf->page_len)
 
 
 
 
 
 
 
 
 
2737		return nfserr_resource;
2738
2739	RESERVE_SPACE(8); /* eof flag and byte count */
2740
2741	maxcount = svc_max_payload(resp->rqstp);
2742	if (maxcount > read->rd_length)
2743		maxcount = read->rd_length;
 
 
 
 
 
 
 
2744
2745	len = maxcount;
2746	v = 0;
2747	while (len > 0) {
2748		pn = resp->rqstp->rq_resused++;
2749		resp->rqstp->rq_vec[v].iov_base =
2750			page_address(resp->rqstp->rq_respages[pn]);
2751		resp->rqstp->rq_vec[v].iov_len =
2752			len < PAGE_SIZE ? len : PAGE_SIZE;
2753		v++;
2754		len -= PAGE_SIZE;
2755	}
2756	read->rd_vlen = v;
2757
2758	nfserr = nfsd_read_file(read->rd_rqstp, read->rd_fhp, read->rd_filp,
2759			read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,
2760			&maxcount);
2761
2762	if (nfserr == nfserr_symlink)
2763		nfserr = nfserr_inval;
2764	if (nfserr)
2765		return nfserr;
2766	eof = (read->rd_offset + maxcount >=
2767	       read->rd_fhp->fh_dentry->d_inode->i_size);
2768
2769	WRITE32(eof);
2770	WRITE32(maxcount);
2771	ADJUST_ARGS();
2772	resp->xbuf->head[0].iov_len = (char*)p
2773					- (char*)resp->xbuf->head[0].iov_base;
2774	resp->xbuf->page_len = maxcount;
2775
2776	/* Use rest of head for padding and remaining ops: */
2777	resp->xbuf->tail[0].iov_base = p;
2778	resp->xbuf->tail[0].iov_len = 0;
2779	if (maxcount&3) {
2780		RESERVE_SPACE(4);
2781		WRITE32(0);
2782		resp->xbuf->tail[0].iov_base += maxcount&3;
2783		resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2784		ADJUST_ARGS();
2785	}
2786	return 0;
2787}
2788
2789static __be32
2790nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
2791{
2792	int maxcount;
2793	char *page;
 
 
 
 
2794	__be32 *p;
2795
2796	if (nfserr)
2797		return nfserr;
2798	if (resp->xbuf->page_len)
2799		return nfserr_resource;
2800
2801	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
2802
2803	maxcount = PAGE_SIZE;
2804	RESERVE_SPACE(4);
2805
 
 
 
2806	/*
2807	 * XXX: By default, the ->readlink() VFS op will truncate symlinks
2808	 * if they would overflow the buffer.  Is this kosher in NFSv4?  If
2809	 * not, one easy fix is: if ->readlink() precisely fills the buffer,
2810	 * assume that truncation occurred, and return NFS4ERR_RESOURCE.
2811	 */
2812	nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);
 
2813	if (nfserr == nfserr_isdir)
2814		return nfserr_inval;
2815	if (nfserr)
2816		return nfserr;
 
 
 
 
 
 
2817
2818	WRITE32(maxcount);
2819	ADJUST_ARGS();
2820	resp->xbuf->head[0].iov_len = (char*)p
2821				- (char*)resp->xbuf->head[0].iov_base;
2822	resp->xbuf->page_len = maxcount;
 
 
2823
2824	/* Use rest of head for padding and remaining ops: */
2825	resp->xbuf->tail[0].iov_base = p;
2826	resp->xbuf->tail[0].iov_len = 0;
2827	if (maxcount&3) {
2828		RESERVE_SPACE(4);
2829		WRITE32(0);
2830		resp->xbuf->tail[0].iov_base += maxcount&3;
2831		resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);
2832		ADJUST_ARGS();
2833	}
2834	return 0;
2835}
2836
2837static __be32
2838nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
2839{
2840	int maxcount;
 
2841	loff_t offset;
2842	__be32 *page, *savep, *tailbase;
 
 
2843	__be32 *p;
2844
2845	if (nfserr)
2846		return nfserr;
2847	if (resp->xbuf->page_len)
2848		return nfserr_resource;
2849
2850	RESERVE_SPACE(8);  /* verifier */
2851	savep = p;
2852
2853	/* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
2854	WRITE32(0);
2855	WRITE32(0);
2856	ADJUST_ARGS();
2857	resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;
2858	tailbase = p;
2859
2860	maxcount = PAGE_SIZE;
2861	if (maxcount > readdir->rd_maxcount)
2862		maxcount = readdir->rd_maxcount;
2863
2864	/*
2865	 * Convert from bytes to words, account for the two words already
2866	 * written, make sure to leave two words at the end for the next
2867	 * pointer and eof field.
 
 
 
 
 
 
 
 
 
 
 
 
2868	 */
2869	maxcount = (maxcount >> 2) - 4;
2870	if (maxcount < 0) {
2871		nfserr =  nfserr_toosmall;
2872		goto err_no_verf;
2873	}
 
2874
2875	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);
 
 
 
 
 
2876	readdir->common.err = 0;
2877	readdir->buflen = maxcount;
2878	readdir->buffer = page;
2879	readdir->offset = NULL;
2880
2881	offset = readdir->rd_cookie;
2882	nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
2883			      &offset,
2884			      &readdir->common, nfsd4_encode_dirent);
2885	if (nfserr == nfs_ok &&
2886	    readdir->common.err == nfserr_toosmall &&
2887	    readdir->buffer == page) 
2888		nfserr = nfserr_toosmall;
2889	if (nfserr == nfserr_symlink)
2890		nfserr = nfserr_notdir;
 
 
 
 
 
2891	if (nfserr)
2892		goto err_no_verf;
2893
2894	if (readdir->offset)
2895		xdr_encode_hyper(readdir->offset, offset);
 
 
 
2896
2897	p = readdir->buffer;
 
 
 
 
2898	*p++ = 0;	/* no more entries */
2899	*p++ = htonl(readdir->common.err == nfserr_eof);
2900	resp->xbuf->page_len = ((char*)p) - (char*)page_address(
2901		resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
2902
2903	/* Use rest of head for padding and remaining ops: */
2904	resp->xbuf->tail[0].iov_base = tailbase;
2905	resp->xbuf->tail[0].iov_len = 0;
2906	resp->p = resp->xbuf->tail[0].iov_base;
2907	resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;
2908
2909	return 0;
2910err_no_verf:
2911	p = savep;
2912	ADJUST_ARGS();
2913	return nfserr;
2914}
2915
2916static __be32
2917nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
2918{
 
2919	__be32 *p;
2920
2921	if (!nfserr) {
2922		RESERVE_SPACE(20);
2923		write_cinfo(&p, &remove->rm_cinfo);
2924		ADJUST_ARGS();
2925	}
2926	return nfserr;
2927}
2928
2929static __be32
2930nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
2931{
 
2932	__be32 *p;
2933
2934	if (!nfserr) {
2935		RESERVE_SPACE(40);
2936		write_cinfo(&p, &rename->rn_sinfo);
2937		write_cinfo(&p, &rename->rn_tinfo);
2938		ADJUST_ARGS();
2939	}
2940	return nfserr;
2941}
2942
2943static __be32
2944nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
2945			 __be32 nfserr,struct svc_export *exp)
2946{
2947	int i = 0;
2948	u32 nflavs;
2949	struct exp_flavor_info *flavs;
2950	struct exp_flavor_info def_flavs[2];
2951	__be32 *p;
 
2952
2953	if (nfserr)
2954		goto out;
2955	if (exp->ex_nflavors) {
2956		flavs = exp->ex_flavors;
2957		nflavs = exp->ex_nflavors;
2958	} else { /* Handling of some defaults in absence of real secinfo: */
2959		flavs = def_flavs;
2960		if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
2961			nflavs = 2;
2962			flavs[0].pseudoflavor = RPC_AUTH_UNIX;
2963			flavs[1].pseudoflavor = RPC_AUTH_NULL;
2964		} else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
2965			nflavs = 1;
2966			flavs[0].pseudoflavor
2967					= svcauth_gss_flavor(exp->ex_client);
2968		} else {
2969			nflavs = 1;
2970			flavs[0].pseudoflavor
2971					= exp->ex_client->flavour->flavour;
2972		}
2973	}
2974
2975	RESERVE_SPACE(4);
2976	WRITE32(nflavs);
2977	ADJUST_ARGS();
 
 
 
2978	for (i = 0; i < nflavs; i++) {
2979		u32 flav = flavs[i].pseudoflavor;
2980		struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
2981
2982		if (gm) {
2983			RESERVE_SPACE(4);
2984			WRITE32(RPC_AUTH_GSS);
2985			ADJUST_ARGS();
2986			RESERVE_SPACE(4 + gm->gm_oid.len);
2987			WRITE32(gm->gm_oid.len);
2988			WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
2989			ADJUST_ARGS();
2990			RESERVE_SPACE(4);
2991			WRITE32(0); /* qop */
2992			ADJUST_ARGS();
2993			RESERVE_SPACE(4);
2994			WRITE32(gss_pseudoflavor_to_service(gm, flav));
2995			ADJUST_ARGS();
2996			gss_mech_put(gm);
 
2997		} else {
2998			RESERVE_SPACE(4);
2999			WRITE32(flav);
3000			ADJUST_ARGS();
3001		}
3002	}
3003out:
3004	if (exp)
3005		exp_put(exp);
3006	return nfserr;
 
3007}
3008
3009static __be32
3010nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
3011		     struct nfsd4_secinfo *secinfo)
3012{
3013	return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
 
 
3014}
3015
3016static __be32
3017nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3018		     struct nfsd4_secinfo_no_name *secinfo)
3019{
3020	return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
 
 
3021}
3022
3023/*
3024 * The SETATTR encode routine is special -- it always encodes a bitmap,
3025 * regardless of the error status.
3026 */
3027static __be32
3028nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
3029{
 
3030	__be32 *p;
3031
3032	RESERVE_SPACE(12);
 
 
3033	if (nfserr) {
3034		WRITE32(2);
3035		WRITE32(0);
3036		WRITE32(0);
 
3037	}
3038	else {
3039		WRITE32(2);
3040		WRITE32(setattr->sa_bmval[0]);
3041		WRITE32(setattr->sa_bmval[1]);
 
3042	}
3043	ADJUST_ARGS();
3044	return nfserr;
3045}
3046
3047static __be32
3048nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
3049{
 
3050	__be32 *p;
3051
3052	if (!nfserr) {
3053		RESERVE_SPACE(8 + sizeof(nfs4_verifier));
3054		WRITEMEM(&scd->se_clientid, 8);
3055		WRITEMEM(&scd->se_confirm, sizeof(nfs4_verifier));
3056		ADJUST_ARGS();
 
 
3057	}
3058	else if (nfserr == nfserr_clid_inuse) {
3059		RESERVE_SPACE(8);
3060		WRITE32(0);
3061		WRITE32(0);
3062		ADJUST_ARGS();
 
3063	}
3064	return nfserr;
3065}
3066
3067static __be32
3068nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
3069{
 
3070	__be32 *p;
3071
3072	if (!nfserr) {
3073		RESERVE_SPACE(16);
3074		WRITE32(write->wr_bytes_written);
3075		WRITE32(write->wr_how_written);
3076		WRITEMEM(write->wr_verifier.data, 8);
3077		ADJUST_ARGS();
3078	}
3079	return nfserr;
3080}
3081
3082static __be32
3083nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, int nfserr,
3084			 struct nfsd4_exchange_id *exid)
3085{
 
3086	__be32 *p;
3087	char *major_id;
3088	char *server_scope;
3089	int major_id_sz;
3090	int server_scope_sz;
3091	uint64_t minor_id = 0;
 
3092
3093	if (nfserr)
3094		return nfserr;
3095
3096	major_id = utsname()->nodename;
3097	major_id_sz = strlen(major_id);
3098	server_scope = utsname()->nodename;
3099	server_scope_sz = strlen(server_scope);
3100
3101	RESERVE_SPACE(
3102		8 /* eir_clientid */ +
3103		4 /* eir_sequenceid */ +
3104		4 /* eir_flags */ +
3105		4 /* spr_how (SP4_NONE) */ +
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3106		8 /* so_minor_id */ +
3107		4 /* so_major_id.len */ +
3108		(XDR_QUADLEN(major_id_sz) * 4) +
3109		4 /* eir_server_scope.len */ +
3110		(XDR_QUADLEN(server_scope_sz) * 4) +
3111		4 /* eir_server_impl_id.count (0) */);
3112
3113	WRITEMEM(&exid->clientid, 8);
3114	WRITE32(exid->seqid);
3115	WRITE32(exid->flags);
3116
3117	/* state_protect4_r. Currently only support SP4_NONE */
3118	BUG_ON(exid->spa_how != SP4_NONE);
3119	WRITE32(exid->spa_how);
3120
3121	/* The server_owner struct */
3122	WRITE64(minor_id);      /* Minor id */
3123	/* major id */
3124	WRITE32(major_id_sz);
3125	WRITEMEM(major_id, major_id_sz);
3126
3127	/* Server scope */
3128	WRITE32(server_scope_sz);
3129	WRITEMEM(server_scope, server_scope_sz);
3130
3131	/* Implementation id */
3132	WRITE32(0);	/* zero length nfs_impl_id4 array */
3133	ADJUST_ARGS();
3134	return 0;
3135}
3136
3137static __be32
3138nfsd4_encode_create_session(struct nfsd4_compoundres *resp, int nfserr,
3139			    struct nfsd4_create_session *sess)
3140{
 
3141	__be32 *p;
3142
3143	if (nfserr)
3144		return nfserr;
 
 
 
 
 
3145
3146	RESERVE_SPACE(24);
3147	WRITEMEM(sess->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3148	WRITE32(sess->seqid);
3149	WRITE32(sess->flags);
3150	ADJUST_ARGS();
3151
3152	RESERVE_SPACE(28);
3153	WRITE32(0); /* headerpadsz */
3154	WRITE32(sess->fore_channel.maxreq_sz);
3155	WRITE32(sess->fore_channel.maxresp_sz);
3156	WRITE32(sess->fore_channel.maxresp_cached);
3157	WRITE32(sess->fore_channel.maxops);
3158	WRITE32(sess->fore_channel.maxreqs);
3159	WRITE32(sess->fore_channel.nr_rdma_attrs);
3160	ADJUST_ARGS();
3161
3162	if (sess->fore_channel.nr_rdma_attrs) {
3163		RESERVE_SPACE(4);
3164		WRITE32(sess->fore_channel.rdma_attrs);
3165		ADJUST_ARGS();
 
3166	}
3167
3168	RESERVE_SPACE(28);
3169	WRITE32(0); /* headerpadsz */
3170	WRITE32(sess->back_channel.maxreq_sz);
3171	WRITE32(sess->back_channel.maxresp_sz);
3172	WRITE32(sess->back_channel.maxresp_cached);
3173	WRITE32(sess->back_channel.maxops);
3174	WRITE32(sess->back_channel.maxreqs);
3175	WRITE32(sess->back_channel.nr_rdma_attrs);
3176	ADJUST_ARGS();
 
3177
3178	if (sess->back_channel.nr_rdma_attrs) {
3179		RESERVE_SPACE(4);
3180		WRITE32(sess->back_channel.rdma_attrs);
3181		ADJUST_ARGS();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3182	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3183	return 0;
3184}
3185
3186static __be32
3187nfsd4_encode_destroy_session(struct nfsd4_compoundres *resp, int nfserr,
3188			     struct nfsd4_destroy_session *destroy_session)
3189{
 
 
 
 
 
 
 
 
3190	return nfserr;
3191}
3192
3193static __be32
3194nfsd4_encode_free_stateid(struct nfsd4_compoundres *resp, int nfserr,
3195			  struct nfsd4_free_stateid *free_stateid)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3196{
3197	__be32 *p;
 
 
 
 
 
 
 
 
 
3198
3199	if (nfserr)
3200		return nfserr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3201
3202	RESERVE_SPACE(4);
3203	WRITE32(nfserr);
3204	ADJUST_ARGS();
3205	return nfserr;
3206}
3207
3208static __be32
3209nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
3210		      struct nfsd4_sequence *seq)
3211{
 
3212	__be32 *p;
3213
3214	if (nfserr)
3215		return nfserr;
3216
3217	RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 20);
3218	WRITEMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
3219	WRITE32(seq->seqid);
3220	WRITE32(seq->slotid);
3221	WRITE32(seq->maxslots);
3222	/* For now: target_maxslots = maxslots */
3223	WRITE32(seq->maxslots);
3224	WRITE32(seq->status_flags);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3225
3226	ADJUST_ARGS();
3227	resp->cstate.datap = p; /* DRC cache data pointer */
3228	return 0;
3229}
3230
3231__be32
3232nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr,
3233			  struct nfsd4_test_stateid *test_stateid)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3234{
3235	struct nfsd4_compoundargs *argp;
3236	stateid_t si;
 
 
 
 
 
3237	__be32 *p;
3238	int i;
3239	int valid;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3240
3241	restore_buf(test_stateid->ts_saved_args, &test_stateid->ts_savedp);
3242	argp = test_stateid->ts_saved_args;
3243
3244	RESERVE_SPACE(4);
3245	*p++ = htonl(test_stateid->ts_num_ids);
3246	resp->p = p;
 
 
 
 
 
 
 
 
 
 
 
 
3247
3248	nfs4_lock_state();
3249	for (i = 0; i < test_stateid->ts_num_ids; i++) {
3250		nfsd4_decode_stateid(argp, &si);
3251		valid = nfs4_validate_stateid(&si, test_stateid->ts_has_session);
3252		RESERVE_SPACE(4);
3253		*p++ = htonl(valid);
3254		resp->p = p;
3255	}
3256	nfs4_unlock_state();
 
 
3257
3258	return nfserr;
 
 
 
 
 
 
3259}
3260
3261static __be32
3262nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
 
3263{
3264	return nfserr;
 
 
 
 
 
 
 
 
3265}
3266
3267typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
3268
3269/*
3270 * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
3271 * since we don't need to filter out obsolete ops as this is
3272 * done in the decoding phase.
3273 */
3274static nfsd4_enc nfsd4_enc_ops[] = {
3275	[OP_ACCESS]		= (nfsd4_enc)nfsd4_encode_access,
3276	[OP_CLOSE]		= (nfsd4_enc)nfsd4_encode_close,
3277	[OP_COMMIT]		= (nfsd4_enc)nfsd4_encode_commit,
3278	[OP_CREATE]		= (nfsd4_enc)nfsd4_encode_create,
3279	[OP_DELEGPURGE]		= (nfsd4_enc)nfsd4_encode_noop,
3280	[OP_DELEGRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
3281	[OP_GETATTR]		= (nfsd4_enc)nfsd4_encode_getattr,
3282	[OP_GETFH]		= (nfsd4_enc)nfsd4_encode_getfh,
3283	[OP_LINK]		= (nfsd4_enc)nfsd4_encode_link,
3284	[OP_LOCK]		= (nfsd4_enc)nfsd4_encode_lock,
3285	[OP_LOCKT]		= (nfsd4_enc)nfsd4_encode_lockt,
3286	[OP_LOCKU]		= (nfsd4_enc)nfsd4_encode_locku,
3287	[OP_LOOKUP]		= (nfsd4_enc)nfsd4_encode_noop,
3288	[OP_LOOKUPP]		= (nfsd4_enc)nfsd4_encode_noop,
3289	[OP_NVERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
3290	[OP_OPEN]		= (nfsd4_enc)nfsd4_encode_open,
3291	[OP_OPENATTR]		= (nfsd4_enc)nfsd4_encode_noop,
3292	[OP_OPEN_CONFIRM]	= (nfsd4_enc)nfsd4_encode_open_confirm,
3293	[OP_OPEN_DOWNGRADE]	= (nfsd4_enc)nfsd4_encode_open_downgrade,
3294	[OP_PUTFH]		= (nfsd4_enc)nfsd4_encode_noop,
3295	[OP_PUTPUBFH]		= (nfsd4_enc)nfsd4_encode_noop,
3296	[OP_PUTROOTFH]		= (nfsd4_enc)nfsd4_encode_noop,
3297	[OP_READ]		= (nfsd4_enc)nfsd4_encode_read,
3298	[OP_READDIR]		= (nfsd4_enc)nfsd4_encode_readdir,
3299	[OP_READLINK]		= (nfsd4_enc)nfsd4_encode_readlink,
3300	[OP_REMOVE]		= (nfsd4_enc)nfsd4_encode_remove,
3301	[OP_RENAME]		= (nfsd4_enc)nfsd4_encode_rename,
3302	[OP_RENEW]		= (nfsd4_enc)nfsd4_encode_noop,
3303	[OP_RESTOREFH]		= (nfsd4_enc)nfsd4_encode_noop,
3304	[OP_SAVEFH]		= (nfsd4_enc)nfsd4_encode_noop,
3305	[OP_SECINFO]		= (nfsd4_enc)nfsd4_encode_secinfo,
3306	[OP_SETATTR]		= (nfsd4_enc)nfsd4_encode_setattr,
3307	[OP_SETCLIENTID]	= (nfsd4_enc)nfsd4_encode_setclientid,
3308	[OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
3309	[OP_VERIFY]		= (nfsd4_enc)nfsd4_encode_noop,
3310	[OP_WRITE]		= (nfsd4_enc)nfsd4_encode_write,
3311	[OP_RELEASE_LOCKOWNER]	= (nfsd4_enc)nfsd4_encode_noop,
3312
3313	/* NFSv4.1 operations */
3314	[OP_BACKCHANNEL_CTL]	= (nfsd4_enc)nfsd4_encode_noop,
3315	[OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
3316	[OP_EXCHANGE_ID]	= (nfsd4_enc)nfsd4_encode_exchange_id,
3317	[OP_CREATE_SESSION]	= (nfsd4_enc)nfsd4_encode_create_session,
3318	[OP_DESTROY_SESSION]	= (nfsd4_enc)nfsd4_encode_destroy_session,
3319	[OP_FREE_STATEID]	= (nfsd4_enc)nfsd4_encode_free_stateid,
3320	[OP_GET_DIR_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
 
 
 
 
 
 
 
3321	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_noop,
3322	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
3323	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_noop,
3324	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_noop,
3325	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
 
3326	[OP_SECINFO_NO_NAME]	= (nfsd4_enc)nfsd4_encode_secinfo_no_name,
3327	[OP_SEQUENCE]		= (nfsd4_enc)nfsd4_encode_sequence,
3328	[OP_SET_SSV]		= (nfsd4_enc)nfsd4_encode_noop,
3329	[OP_TEST_STATEID]	= (nfsd4_enc)nfsd4_encode_test_stateid,
3330	[OP_WANT_DELEGATION]	= (nfsd4_enc)nfsd4_encode_noop,
3331	[OP_DESTROY_CLIENTID]	= (nfsd4_enc)nfsd4_encode_noop,
3332	[OP_RECLAIM_COMPLETE]	= (nfsd4_enc)nfsd4_encode_noop,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3333};
3334
3335/*
3336 * Calculate the total amount of memory that the compound response has taken
3337 * after encoding the current operation.
 
 
 
 
3338 *
3339 * pad: add on 8 bytes for the next operation's op_code and status so that
3340 * there is room to cache a failure on the next operation.
3341 *
3342 * Compare this length to the session se_fmaxresp_cached.
3343 *
3344 * Our se_fmaxresp_cached will always be a multiple of PAGE_SIZE, and so
3345 * will be at least a page and will therefore hold the xdr_buf head.
3346 */
3347static int nfsd4_check_drc_limit(struct nfsd4_compoundres *resp)
3348{
3349	int status = 0;
3350	struct xdr_buf *xb = &resp->rqstp->rq_res;
3351	struct nfsd4_compoundargs *args = resp->rqstp->rq_argp;
3352	struct nfsd4_session *session = NULL;
3353	struct nfsd4_slot *slot = resp->cstate.slot;
3354	u32 length, tlen = 0, pad = 8;
3355
 
 
3356	if (!nfsd4_has_session(&resp->cstate))
3357		return status;
3358
3359	session = resp->cstate.session;
3360	if (session == NULL || slot->sl_cachethis == 0)
3361		return status;
3362
3363	if (resp->opcnt >= args->opcnt)
3364		pad = 0; /* this is the last operation */
3365
3366	if (xb->page_len == 0) {
3367		length = (char *)resp->p - (char *)xb->head[0].iov_base + pad;
3368	} else {
3369		if (xb->tail[0].iov_base && xb->tail[0].iov_len > 0)
3370			tlen = (char *)resp->p - (char *)xb->tail[0].iov_base;
3371
3372		length = xb->head[0].iov_len + xb->page_len + tlen + pad;
3373	}
3374	dprintk("%s length %u, xb->page_len %u tlen %u pad %u\n", __func__,
3375		length, xb->page_len, tlen, pad);
3376
3377	if (length <= session->se_fchannel.maxresp_cached)
3378		return status;
3379	else
3380		return nfserr_rep_too_big_to_cache;
3381}
3382
3383void
3384nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3385{
3386	__be32 *statp;
 
 
 
 
 
3387	__be32 *p;
3388
3389	RESERVE_SPACE(8);
3390	WRITE32(op->opnum);
3391	statp = p++;	/* to be backfilled at the end */
3392	ADJUST_ARGS();
 
 
 
3393
3394	if (op->opnum == OP_ILLEGAL)
3395		goto status;
3396	BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
 
 
 
3397	       !nfsd4_enc_ops[op->opnum]);
3398	op->status = nfsd4_enc_ops[op->opnum](resp, op->status, &op->u);
3399	/* nfsd4_check_drc_limit guarantees enough room for error status */
3400	if (!op->status && nfsd4_check_drc_limit(resp))
3401		op->status = nfserr_rep_too_big_to_cache;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3402status:
3403	/*
3404	 * Note: We write the status directly, instead of using WRITE32(),
3405	 * since it is already in network byte order.
3406	 */
3407	*statp = op->status;
3408}
3409
3410/* 
3411 * Encode the reply stored in the stateowner reply cache 
3412 * 
3413 * XDR note: do not encode rp->rp_buflen: the buffer contains the
3414 * previously sent already encoded operation.
3415 *
3416 * called with nfs4_lock_state() held
3417 */
3418void
3419nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
3420{
3421	__be32 *p;
3422	struct nfs4_replay *rp = op->replay;
3423
3424	BUG_ON(!rp);
3425
3426	RESERVE_SPACE(8);
3427	WRITE32(op->opnum);
 
 
3428	*p++ = rp->rp_status;  /* already xdr'ed */
3429	ADJUST_ARGS();
3430
3431	RESERVE_SPACE(rp->rp_buflen);
3432	WRITEMEM(rp->rp_buf, rp->rp_buflen);
3433	ADJUST_ARGS();
3434}
3435
3436int
3437nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy)
3438{
3439        return xdr_ressize_check(rqstp, p);
3440}
3441
3442int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp)
3443{
3444	struct svc_rqst *rqstp = rq;
3445	struct nfsd4_compoundargs *args = rqstp->rq_argp;
3446
3447	if (args->ops != args->iops) {
3448		kfree(args->ops);
3449		args->ops = args->iops;
3450	}
3451	kfree(args->tmpp);
3452	args->tmpp = NULL;
3453	while (args->to_free) {
3454		struct tmpbuf *tb = args->to_free;
3455		args->to_free = tb->next;
3456		tb->release(tb->buf);
3457		kfree(tb);
3458	}
3459	return 1;
3460}
3461
3462int
3463nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args)
3464{
3465	args->p = p;
3466	args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
3467	args->pagelist = rqstp->rq_arg.pages;
3468	args->pagelen = rqstp->rq_arg.page_len;
3469	args->tmpp = NULL;
3470	args->to_free = NULL;
 
 
3471	args->ops = args->iops;
3472	args->rqstp = rqstp;
3473
3474	return !nfsd4_decode_compound(args);
3475}
3476
3477int
3478nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp)
3479{
3480	/*
3481	 * All that remains is to write the tag and operation count...
3482	 */
3483	struct nfsd4_compound_state *cs = &resp->cstate;
3484	struct kvec *iov;
 
 
 
 
 
3485	p = resp->tagp;
3486	*p++ = htonl(resp->taglen);
3487	memcpy(p, resp->tag, resp->taglen);
3488	p += XDR_QUADLEN(resp->taglen);
3489	*p++ = htonl(resp->opcnt);
3490
3491	if (rqstp->rq_res.page_len) 
3492		iov = &rqstp->rq_res.tail[0];
3493	else
3494		iov = &rqstp->rq_res.head[0];
3495	iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
3496	BUG_ON(iov->iov_len > PAGE_SIZE);
3497	if (nfsd4_has_session(cs)) {
3498		if (cs->status != nfserr_replay_cache) {
3499			nfsd4_store_cache_entry(resp);
3500			dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
3501			cs->slot->sl_inuse = false;
3502		}
3503		/* Renew the clientid on success and on replay */
3504		release_session_client(cs->session);
3505		nfsd4_put_session(cs->session);
3506	}
3507	return 1;
3508}
3509
3510/*
3511 * Local variables:
3512 *  c-basic-offset: 8
3513 * End:
3514 */