/* SPDX-License-Identifier: unknown license... */
/*
 * The content of this file is a mix of rpcgen-generated
 * and hand-edited program text.  It is not automatically
 * generated by, e.g., build processes.
 *
 * This file is under version control.
 */
#include "config.h"
#include "gsh_rpc.h"
#include "nfs23.h"
#include "nfs_fh.h"
#include "fsal_convert.h"

static struct nfs_request_lookahead dummy_lookahead = {
	.flags = 0,
	.read = 0,
	.write = 0
};

bool xdr_nfspath2(XDR *xdrs, nfspath2 *objp)
{
	if (!xdr_string(xdrs, objp, NFS2_MAXPATHLEN))
		return (false);
	return (true);
}

bool xdr_filename2(XDR *xdrs, filename2 *objp)
{
	if (!xdr_string(xdrs, objp, NFS2_MAXNAMLEN))
		return (false);
	return (true);
}

bool xdr_fhandle2(XDR *xdrs, fhandle2 objp)
{
	if (!xdr_opaque(xdrs, objp, NFS2_FHSIZE))
		return (false);
	return (true);
}

bool xdr_nfsdata2(XDR *xdrs, nfsdata2 *objp)
{
	if (!xdr_bytes
	    (xdrs, (char **)&objp->nfsdata2_val, (u_int *) & objp->nfsdata2_len,
	     NFS2_MAXDATA))
		return (false);
	return (true);
}

bool xdr_nfscookie2(XDR *xdrs, nfscookie2 objp)
{
	if (!xdr_opaque(xdrs, objp, NFS2_COOKIESIZE))
		return (false);
	return (true);
}

bool xdr_fhstatus2(XDR *xdrs, fhstatus2 *objp)
{
	if (!xdr_u_int(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case 0:
		if (!xdr_fhandle2(xdrs, objp->fhstatus2_u.directory))
			return (false);
		break;
	}
	return (true);
}

bool xdr_nfs3_uint64(XDR *xdrs, nfs3_uint64 *objp)
{
	if (!xdr_u_longlong_t(xdrs, (quad_t *) objp))
		return (false);
	return (true);
}

bool xdr_nfs3_int64(XDR *xdrs, nfs3_int64 *objp)
{
	if (!xdr_longlong_t(xdrs, (quad_t *) objp))
		return (false);
	return (true);
}

bool xdr_nfs3_uint32(XDR *xdrs, nfs3_uint32 *objp)
{
	if (!xdr_u_int(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_nfs3_int32(XDR *xdrs, nfs3_int32 *objp)
{
	if (!xdr_int(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_filename3(XDR *xdrs, filename3 *objp)
{
	if (!xdr_string(xdrs, objp, XDR_STRING_MAXLEN))
		return (false);
	return (true);
}

bool xdr_nfspath3(XDR *xdrs, nfspath3 *objp)
{
	if (!xdr_string(xdrs, objp, XDR_STRING_MAXLEN))
		return (false);
	return (true);
}

bool xdr_fileid3(XDR *xdrs, fileid3 *objp)
{
	if (!xdr_nfs3_uint64(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_cookie3(XDR *xdrs, cookie3 *objp)
{
	if (!xdr_nfs3_uint64(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_cookieverf3(XDR *xdrs, cookieverf3 objp)
{
	if (!xdr_opaque(xdrs, objp, 8))
		return (false);
	return (true);
}

bool xdr_createverf3(XDR *xdrs, createverf3 objp)
{
	if (!xdr_opaque(xdrs, objp, 8))
		return (false);
	return (true);
}

bool xdr_writeverf3(XDR *xdrs, writeverf3 objp)
{
	if (!xdr_opaque(xdrs, objp, 8))
		return (false);
	return (true);
}

bool xdr_uid3(XDR *xdrs, uid3 *objp)
{
	if (!xdr_nfs3_uint32(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_gid3(XDR *xdrs, gid3 *objp)
{
	if (!xdr_nfs3_uint32(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_size3(XDR *xdrs, size3 *objp)
{
	if (!xdr_nfs3_uint64(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_offset3(XDR *xdrs, offset3 *objp)
{
	if (!xdr_nfs3_uint64(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_mode3(XDR *xdrs, mode3 *objp)
{
	if (!xdr_nfs3_uint32(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_count3(XDR *xdrs, count3 *objp)
{
	if (!xdr_nfs3_uint32(xdrs, objp))
		return (false);
	return (true);
}

bool xdr_nfsstat3(XDR *xdrs, nfsstat3 *objp)
{
	if (!xdr_enum(xdrs, (enum_t *) objp))
		return (false);
	return (true);
}

bool xdr_ftype3(XDR *xdrs, ftype3 *objp)
{
	if (!xdr_enum(xdrs, (enum_t *) objp))
		return (false);
	return (true);
}

bool xdr_specdata3(XDR *xdrs, specdata3 *objp)
{
	if (!xdr_nfs3_uint32(xdrs, &objp->specdata1))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->specdata2))
		return (false);
	return (true);
}

bool xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
{
	if (!xdr_bytes
	    (xdrs, (char **)&objp->data.data_val,
	     (u_int *) & objp->data.data_len, 64))
		return (false);

	return (true);
}

bool xdr_nfstime3(XDR *xdrs, nfstime3 *objp)
{
	if (!xdr_nfs3_uint32(xdrs, &objp->tv_sec))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->tv_nsec))
		return (false);
	return (true);
}

bool xdr_fattr3(XDR *xdrs, fattr3 *objp)
{
	ftype3 ft;
	specdata3 rdev;
	uid3 uid;
	gid3 gid;
	nfstime3 atime, mtime, ctime;
	mode3 mode;

	if (xdrs->x_op == XDR_ENCODE) {
		/* Convert object_file_type_t to ftype3 */
		switch (objp->type) {
		case FIFO_FILE:
			ft = NF3FIFO;
			break;

		case CHARACTER_FILE:
			ft = NF3CHR;
			break;

		case DIRECTORY:
			ft = NF3DIR;
			break;

		case BLOCK_FILE:
			ft = NF3BLK;
			break;

		case REGULAR_FILE:
		case EXTENDED_ATTR:
			ft = NF3REG;
			break;

		case SYMBOLIC_LINK:
			ft = NF3LNK;
			break;

		case SOCKET_FILE:
			ft = NF3SOCK;
			break;

		default:
			LogEvent(COMPONENT_NFSPROTO,
				 "xdr_fattr3: Bogus type = %d",
				 objp->type);
		}

		mode = fsal2unix_mode(objp->mode);
		rdev.specdata1 = objp->rawdev.major;
		rdev.specdata2 = objp->rawdev.minor;
		uid = objp->owner;
		gid = objp->group;
		atime.tv_sec = objp->atime.tv_sec;
		atime.tv_nsec = objp->atime.tv_nsec;
		mtime.tv_sec = objp->mtime.tv_sec;
		mtime.tv_nsec = objp->mtime.tv_nsec;
		ctime.tv_sec = objp->ctime.tv_sec;
		ctime.tv_nsec = objp->ctime.tv_nsec;
	}

	if (!xdr_ftype3(xdrs, &ft))
		return (false);
	if (!xdr_mode3(xdrs, &mode))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->numlinks))
		return (false);
	if (!xdr_uid3(xdrs, &uid))
		return (false);
	if (!xdr_gid3(xdrs, &gid))
		return (false);
	if (!xdr_size3(xdrs, &objp->filesize))
		return (false);
	if (!xdr_size3(xdrs, &objp->spaceused))
		return (false);
	if (!xdr_specdata3(xdrs, &rdev))
		return (false);
	if (!xdr_nfs3_uint64(xdrs, &objp->fsid3))
		return (false);
	if (!xdr_fileid3(xdrs, &objp->fileid))
		return (false);
	if (!xdr_nfstime3(xdrs, &atime))
		return (false);
	if (!xdr_nfstime3(xdrs, &mtime))
		return (false);
	if (!xdr_nfstime3(xdrs, &ctime))
		return (false);


	if (xdrs->x_op == XDR_DECODE) {
		/* Convert ftype3 to object_file_type_t */
		switch (ft) {
		case NF3FIFO:
			objp->type = FIFO_FILE;
			break;

		case NF3CHR:
			objp->type = CHARACTER_FILE;
			break;

		case NF3DIR:
			objp->type = DIRECTORY;
			break;

		case NF3BLK:
			objp->type = BLOCK_FILE;
			break;

		case NF3REG:
			objp->type = REGULAR_FILE;
			break;

		case NF3LNK:
			objp->type = SYMBOLIC_LINK;
			break;

		case NF3SOCK:
			objp->type = SOCKET_FILE;
			break;

		default:
			LogEvent(COMPONENT_NFSPROTO,
				 "xdr_fattr3: Bogus type = %d",
				 ft);
		}

		objp->mode = unix2fsal_mode(mode);
		objp->rawdev.major = rdev.specdata1;
		objp->rawdev.minor = rdev.specdata2;
		objp->fsid.major = objp->fsid3;
		objp->fsid.minor = 0;
		objp->owner = uid;
		objp->group = gid;
		objp->atime.tv_sec = atime.tv_sec;
		objp->atime.tv_nsec = atime.tv_nsec;
		objp->mtime.tv_sec = mtime.tv_sec;
		objp->mtime.tv_nsec = mtime.tv_nsec;
		objp->ctime.tv_sec = ctime.tv_sec;
		objp->ctime.tv_nsec = ctime.tv_nsec;
	}

	return (true);
}

bool xdr_post_op_attr(XDR *xdrs, post_op_attr *objp)
{
	if (!xdr_bool(xdrs, &objp->attributes_follow))
		return (false);
	switch (objp->attributes_follow) {
	case TRUE:
		if (!xdr_fattr3(xdrs, &objp->post_op_attr_u.attributes))
			return (false);
		break;
	case FALSE:
		break;
	default:
		return (false);
	}
	return (true);
}

bool xdr_wcc_attr(XDR *xdrs, wcc_attr *objp)
{
	if (!xdr_size3(xdrs, &objp->size))
		return (false);
	if (!xdr_nfstime3(xdrs, &objp->mtime))
		return (false);
	if (!xdr_nfstime3(xdrs, &objp->ctime))
		return (false);
	return (true);
}

bool xdr_pre_op_attr(XDR *xdrs, pre_op_attr *objp)
{
	if (!xdr_bool(xdrs, &objp->attributes_follow))
		return (false);
	switch (objp->attributes_follow) {
	case TRUE:
		if (!xdr_wcc_attr(xdrs, &objp->pre_op_attr_u.attributes))
			return (false);
		break;
	case FALSE:
		break;
	default:
		return (false);
	}
	return (true);
}

bool xdr_wcc_data(XDR *xdrs, wcc_data *objp)
{
	if (!xdr_pre_op_attr(xdrs, &objp->before))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->after))
		return (false);
	return (true);
}

bool xdr_post_op_fh3(XDR *xdrs, post_op_fh3 *objp)
{
	if (!xdr_bool(xdrs, &objp->handle_follows))
		return (false);
	switch (objp->handle_follows) {
	case TRUE:
		if (!xdr_nfs_fh3(xdrs, &objp->post_op_fh3_u.handle))
			return (false);
		break;
	case FALSE:
		break;
	default:
		return (false);
	}
	return (true);
}

bool xdr_time_how(XDR *xdrs, time_how *objp)
{
	if (!xdr_enum(xdrs, (enum_t *) objp))
		return (false);
	return (true);
}

bool xdr_set_mode3(XDR *xdrs, set_mode3 *objp)
{
	if (!xdr_bool(xdrs, &objp->set_it))
		return (false);
	switch (objp->set_it) {
	case TRUE:
		if (!xdr_mode3(xdrs, &objp->set_mode3_u.mode))
			return (false);
		break;
	}
	return (true);
}

bool xdr_set_uid3(XDR *xdrs, set_uid3 *objp)
{
	if (!xdr_bool(xdrs, &objp->set_it))
		return (false);
	switch (objp->set_it) {
	case TRUE:
		if (!xdr_uid3(xdrs, &objp->set_uid3_u.uid))
			return (false);
		break;
	}
	return (true);
}

bool xdr_set_gid3(XDR *xdrs, set_gid3 *objp)
{
	if (!xdr_bool(xdrs, &objp->set_it))
		return (false);
	switch (objp->set_it) {
	case TRUE:
		if (!xdr_gid3(xdrs, &objp->set_gid3_u.gid))
			return (false);
		break;
	}
	return (true);
}

bool xdr_set_size3(XDR *xdrs, set_size3 *objp)
{
	if (!xdr_bool(xdrs, &objp->set_it))
		return (false);
	switch (objp->set_it) {
	case TRUE:
		if (!xdr_size3(xdrs, &objp->set_size3_u.size))
			return (false);
		break;
	}
	return (true);
}

bool xdr_set_atime(XDR *xdrs, set_atime *objp)
{
	if (!xdr_time_how(xdrs, &objp->set_it))
		return (false);
	switch (objp->set_it) {
	case SET_TO_CLIENT_TIME:
		if (!xdr_nfstime3(xdrs, &objp->set_atime_u.atime))
			return (false);
		break;
	default:
		return (true);
		break;
	}
	return (true);
}

bool xdr_set_mtime(XDR *xdrs, set_mtime *objp)
{
	if (!xdr_time_how(xdrs, &objp->set_it))
		return (false);
	switch (objp->set_it) {
	case SET_TO_CLIENT_TIME:
		if (!xdr_nfstime3(xdrs, &objp->set_mtime_u.mtime))
			return (false);
		break;
	default:
		return (true);
		break;
	}
	return (true);
}

bool xdr_sattr3(XDR *xdrs, sattr3 *objp)
{
	if (!xdr_set_mode3(xdrs, &objp->mode))
		return (false);
	if (!xdr_set_uid3(xdrs, &objp->uid))
		return (false);
	if (!xdr_set_gid3(xdrs, &objp->gid))
		return (false);
	if (!xdr_set_size3(xdrs, &objp->size))
		return (false);
	if (!xdr_set_atime(xdrs, &objp->atime))
		return (false);
	if (!xdr_set_mtime(xdrs, &objp->mtime))
		return (false);
	return (true);
}

bool xdr_diropargs3(XDR *xdrs, diropargs3 *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->dir))
		return (false);
	if (!xdr_filename3(xdrs, &objp->name))
		return (false);
	return (true);
}

bool xdr_GETATTR3args(XDR *xdrs, GETATTR3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->object))
		return (false);
	return (true);
}

bool xdr_GETATTR3resok(XDR *xdrs, GETATTR3resok *objp)
{
	if (!xdr_fattr3(xdrs, &objp->obj_attributes))
		return (false);
	return (true);
}

bool xdr_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_GETATTR3resok(xdrs, &objp->GETATTR3res_u.resok))
			return (false);
		break;
	default:
		return (true);
		break;
	}
	return (true);
}

bool xdr_sattrguard3(XDR *xdrs, sattrguard3 *objp)
{
	if (!xdr_bool(xdrs, &objp->check))
		return (false);
	switch (objp->check) {
	case TRUE:
		if (!xdr_nfstime3(xdrs, &objp->sattrguard3_u.obj_ctime))
			return (false);
		break;
	case FALSE:
		break;
	default:
		return (false);
	}
	return (true);
}

bool xdr_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->object))
		return (false);
	if (!xdr_sattr3(xdrs, &objp->new_attributes))
		return (false);
	if (!xdr_sattrguard3(xdrs, &objp->guard))
		return (false);
	return (true);
}

bool xdr_SETATTR3resok(XDR *xdrs, SETATTR3resok *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->obj_wcc))
		return (false);
	return (true);
}

bool xdr_SETATTR3resfail(XDR *xdrs, SETATTR3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->obj_wcc))
		return (false);
	return (true);
}

bool xdr_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_SETATTR3resok(xdrs, &objp->SETATTR3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_SETATTR3resfail(xdrs, &objp->SETATTR3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_LOOKUP3args(XDR *xdrs, LOOKUP3args *objp)
{
	if (!xdr_diropargs3(xdrs, &objp->what))
		return (false);
	return (true);
}

bool xdr_LOOKUP3resok(XDR *xdrs, LOOKUP3resok *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->object))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
		return (false);
	return (true);
}

bool xdr_LOOKUP3resfail(XDR *xdrs, LOOKUP3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
		return (false);
	return (true);
}

bool xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_LOOKUP3resok(xdrs, &objp->LOOKUP3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_LOOKUP3resfail(xdrs, &objp->LOOKUP3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->object))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->access))
		return (false);
	return (true);
}

bool xdr_ACCESS3resok(XDR *xdrs, ACCESS3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->access))
		return (false);
	return (true);
}

bool xdr_ACCESS3resfail(XDR *xdrs, ACCESS3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	return (true);
}

bool xdr_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_ACCESS3resok(xdrs, &objp->ACCESS3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_ACCESS3resfail(xdrs, &objp->ACCESS3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_READLINK3args(XDR *xdrs, READLINK3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->symlink))
		return (false);
	return (true);
}

bool xdr_READLINK3resok(XDR *xdrs, READLINK3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->symlink_attributes))
		return (false);
	if (!xdr_nfspath3(xdrs, &objp->data))
		return (false);
	return (true);
}

bool xdr_READLINK3resfail(XDR *xdrs, READLINK3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->symlink_attributes))
		return (false);
	return (true);
}

bool xdr_READLINK3res(XDR *xdrs, READLINK3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_READLINK3resok(xdrs, &objp->READLINK3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_READLINK3resfail(xdrs, &objp->READLINK3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_READ3args(XDR *xdrs, READ3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_nfs_fh3(xdrs, &objp->file))
		return (false);
	if (!xdr_offset3(xdrs, &objp->offset))
		return (false);
	if (!xdr_count3(xdrs, &objp->count))
		return (false);
	lkhd->flags = NFS_LOOKAHEAD_READ;
	(lkhd->read)++;
	return (true);
}

void xdr_READ3res_uio_release(struct xdr_uio *uio, u_int flags)
{
	int ix;

	LogFullDebug(COMPONENT_NFS_V4,
		     "Releasing %p, references %"PRIi32", count %d",
		     uio, uio->uio_references, (int) uio->uio_count);

	if (!(--uio->uio_references)) {
		for (ix = 0; ix < uio->uio_count; ix++) {
			gsh_free(uio->uio_vio[ix].vio_base);
		}
		gsh_free(uio);
	}
}

struct xdr_uio *xdr_READ3res_uio_setup(struct READ3resok *objp)
{
	struct xdr_uio *uio;
	u_int size = objp->data.data_len;
	/* The size to actually be written must be a multiple of
	 * BYTES_PER_XDR_UNIT
	 */
	u_int size2 = RNDUP(size);
	int i;

	if (size2 != size) {
		/* Must zero out extra bytes */
		for (i = size; i < size2; i++)
			objp->data.data_val[i] = 0;
	}

	uio = gsh_calloc(1, sizeof(struct xdr_uio) + sizeof(struct xdr_vio));
	uio->uio_release = xdr_READ3res_uio_release;
	uio->uio_count = 1;
	uio->uio_vio[0].vio_base = objp->data.data_val;
	uio->uio_vio[0].vio_head = objp->data.data_val;
	uio->uio_vio[0].vio_tail = objp->data.data_val + size2;
	uio->uio_vio[0].vio_wrap = objp->data.data_val + size2;
	uio->uio_vio[0].vio_length = size2;
	uio->uio_vio[0].vio_type = VIO_DATA;

	/* Take over read data buffer */
	objp->data.data_val = NULL;
	objp->data.data_len = 0;

	LogFullDebug(COMPONENT_NFS_V4,
		     "Allocated %p, references %"PRIi32", count %d",
		     uio, uio->uio_references, (int) uio->uio_count);

	return uio;
}

static inline bool xdr_READ3resok_encode(XDR *xdrs, READ3resok *objp)
{
	struct xdr_uio *uio;
	uint32_t size = objp->data.data_len;

	if (!inline_xdr_u_int32_t(xdrs, &size))
		return false;

	uio = xdr_READ3res_uio_setup(objp);

	if (!xdr_putbufs(xdrs, uio, UIO_FLAG_NONE)) {
		uio->uio_release(uio, UIO_FLAG_NONE);
		return false;
	}
	return true;
}

bool xdr_READ3resok(XDR *xdrs, READ3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
		return (false);
	if (!xdr_count3(xdrs, &objp->count))
		return (false);
	if (!xdr_bool(xdrs, &objp->eof))
		return (false);

	if (xdrs->x_op == XDR_ENCODE)
		return xdr_READ3resok_encode(xdrs, objp);

	if (!xdr_bytes
	    (xdrs, (char **)&objp->data.data_val,
	     &objp->data.data_len, XDR_BYTES_MAXLEN_IO))
		return (false);
	return (true);
}

bool xdr_READ3resfail(XDR *xdrs, READ3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
		return (false);
	return (true);
}

bool xdr_READ3res(XDR *xdrs, READ3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_READ3resok(xdrs, &objp->READ3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_READ3resfail(xdrs, &objp->READ3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_stable_how(XDR *xdrs, stable_how *objp)
{
	if (!xdr_enum(xdrs, (enum_t *) objp))
		return (false);
	return (true);
}

bool xdr_WRITE3args(XDR *xdrs, WRITE3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_nfs_fh3(xdrs, &objp->file))
		return (false);
	if (!xdr_offset3(xdrs, &objp->offset))
		return (false);
	if (!xdr_count3(xdrs, &objp->count))
		return (false);
	if (!xdr_stable_how(xdrs, &objp->stable))
		return (false);
	if (!xdr_bytes
	    (xdrs, (char **)&objp->data.data_val,
	     &objp->data.data_len, XDR_BYTES_MAXLEN_IO))
		return (false);
	lkhd->flags |= NFS_LOOKAHEAD_WRITE;
	(lkhd->write)++;
	return (true);
}

bool xdr_WRITE3resok(XDR *xdrs, WRITE3resok *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
		return (false);
	if (!xdr_count3(xdrs, &objp->count))
		return (false);
	if (!xdr_stable_how(xdrs, &objp->committed))
		return (false);
	if (!xdr_writeverf3(xdrs, objp->verf))
		return (false);
	return (true);
}

bool xdr_WRITE3resfail(XDR *xdrs, WRITE3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
		return (false);
	return (true);
}

bool xdr_WRITE3res(XDR *xdrs, WRITE3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_WRITE3resok(xdrs, &objp->WRITE3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_WRITE3resfail(xdrs, &objp->WRITE3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_createmode3(XDR *xdrs, createmode3 *objp)
{
	if (!xdr_enum(xdrs, (enum_t *) objp))
		return (false);
	return (true);
}

bool xdr_createhow3(XDR *xdrs, createhow3 *objp)
{
	if (!xdr_createmode3(xdrs, &objp->mode))
		return (false);
	switch (objp->mode) {
	case UNCHECKED:
	case GUARDED:
		if (!xdr_sattr3(xdrs, &objp->createhow3_u.obj_attributes))
			return (false);
		break;
	case EXCLUSIVE:
		if (!xdr_createverf3(xdrs, objp->createhow3_u.verf))
			return (false);
		break;
	default:
		return (false);
	}
	return (true);
}

bool xdr_CREATE3args(XDR *xdrs, CREATE3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_diropargs3(xdrs, &objp->where))
		return (false);
	if (!xdr_createhow3(xdrs, &objp->how))
		return (false);
	lkhd->flags |= NFS_LOOKAHEAD_CREATE;
	return (true);
}

bool xdr_CREATE3resok(XDR *xdrs, CREATE3resok *objp)
{
	if (!xdr_post_op_fh3(xdrs, &objp->obj))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_CREATE3resfail(XDR *xdrs, CREATE3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_CREATE3res(XDR *xdrs, CREATE3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_CREATE3resok(xdrs, &objp->CREATE3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_CREATE3resfail(xdrs, &objp->CREATE3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
{
	if (!xdr_diropargs3(xdrs, &objp->where))
		return (false);
	if (!xdr_sattr3(xdrs, &objp->attributes))
		return (false);
	return (true);
}

bool xdr_MKDIR3resok(XDR *xdrs, MKDIR3resok *objp)
{
	if (!xdr_post_op_fh3(xdrs, &objp->obj))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_MKDIR3resfail(XDR *xdrs, MKDIR3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_MKDIR3resok(xdrs, &objp->MKDIR3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_MKDIR3resfail(xdrs, &objp->MKDIR3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_symlinkdata3(XDR *xdrs, symlinkdata3 *objp)
{
	if (!xdr_sattr3(xdrs, &objp->symlink_attributes))
		return (false);
	if (!xdr_nfspath3(xdrs, &objp->symlink_data))
		return (false);
	return (true);
}

bool xdr_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
{
	if (!xdr_diropargs3(xdrs, &objp->where))
		return (false);
	if (!xdr_symlinkdata3(xdrs, &objp->symlink))
		return (false);
	return (true);
}

bool xdr_SYMLINK3resok(XDR *xdrs, SYMLINK3resok *objp)
{
	if (!xdr_post_op_fh3(xdrs, &objp->obj))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_SYMLINK3resfail(XDR *xdrs, SYMLINK3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_SYMLINK3resok(xdrs, &objp->SYMLINK3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_SYMLINK3resfail(xdrs, &objp->SYMLINK3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_devicedata3(XDR *xdrs, devicedata3 *objp)
{
	if (!xdr_sattr3(xdrs, &objp->dev_attributes))
		return (false);
	if (!xdr_specdata3(xdrs, &objp->spec))
		return (false);
	return (true);
}

bool xdr_mknoddata3(XDR *xdrs, mknoddata3 *objp)
{
	if (!xdr_ftype3(xdrs, &objp->type))
		return (false);
	switch (objp->type) {
	case NF3CHR:
	case NF3BLK:
		if (!xdr_devicedata3(xdrs, &objp->mknoddata3_u.device))
			return (false);
		break;
	case NF3SOCK:
	case NF3FIFO:
		if (!xdr_sattr3(xdrs, &objp->mknoddata3_u.pipe_attributes))
			return (false);
		break;
	default:
		return (true);
		break;
	}
	return (true);
}

bool xdr_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
{
	if (!xdr_diropargs3(xdrs, &objp->where))
		return (false);
	if (!xdr_mknoddata3(xdrs, &objp->what))
		return (false);
	return (true);
}

bool xdr_MKNOD3resok(XDR *xdrs, MKNOD3resok *objp)
{
	if (!xdr_post_op_fh3(xdrs, &objp->obj))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_MKNOD3resfail(XDR *xdrs, MKNOD3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_MKNOD3resok(xdrs, &objp->MKNOD3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_MKNOD3resfail(xdrs, &objp->MKNOD3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_REMOVE3args(XDR *xdrs, REMOVE3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_diropargs3(xdrs, &objp->object))
		return (false);
	lkhd->flags |= NFS_LOOKAHEAD_REMOVE;
	return (true);
}

bool xdr_REMOVE3resok(XDR *xdrs, REMOVE3resok *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_REMOVE3resfail(XDR *xdrs, REMOVE3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_REMOVE3resok(xdrs, &objp->REMOVE3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_REMOVE3resfail(xdrs, &objp->REMOVE3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_RMDIR3args(XDR *xdrs, RMDIR3args *objp)
{
	if (!xdr_diropargs3(xdrs, &objp->object))
		return (false);
	return (true);
}

bool xdr_RMDIR3resok(XDR *xdrs, RMDIR3resok *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_RMDIR3resfail(XDR *xdrs, RMDIR3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->dir_wcc))
		return (false);
	return (true);
}

bool xdr_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_RMDIR3resok(xdrs, &objp->RMDIR3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_RMDIR3resfail(xdrs, &objp->RMDIR3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_RENAME3args(XDR *xdrs, RENAME3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_diropargs3(xdrs, &objp->from))
		return (false);
	if (!xdr_diropargs3(xdrs, &objp->to))
		return (false);
	lkhd->flags |= NFS_LOOKAHEAD_RENAME;
	return (true);
}

bool xdr_RENAME3resok(XDR *xdrs, RENAME3resok *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->fromdir_wcc))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->todir_wcc))
		return (false);
	return (true);
}

bool xdr_RENAME3resfail(XDR *xdrs, RENAME3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->fromdir_wcc))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->todir_wcc))
		return (false);
	return (true);
}

bool xdr_RENAME3res(XDR *xdrs, RENAME3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_RENAME3resok(xdrs, &objp->RENAME3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_RENAME3resfail(xdrs, &objp->RENAME3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_LINK3args(XDR *xdrs, LINK3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->file))
		return (false);
	if (!xdr_diropargs3(xdrs, &objp->link))
		return (false);
	return (true);
}

bool xdr_LINK3resok(XDR *xdrs, LINK3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->linkdir_wcc))
		return (false);
	return (true);
}

bool xdr_LINK3resfail(XDR *xdrs, LINK3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->file_attributes))
		return (false);
	if (!xdr_wcc_data(xdrs, &objp->linkdir_wcc))
		return (false);
	return (true);
}

bool xdr_LINK3res(XDR *xdrs, LINK3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_LINK3resok(xdrs, &objp->LINK3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_LINK3resfail(xdrs, &objp->LINK3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_READDIR3args(XDR *xdrs, READDIR3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_nfs_fh3(xdrs, &objp->dir))
		return (false);
	if (!xdr_cookie3(xdrs, &objp->cookie))
		return (false);
	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
		return (false);
	if (!xdr_count3(xdrs, &objp->count))
		return (false);
	lkhd->flags |= NFS_LOOKAHEAD_READDIR;
	return (true);
}

bool xdr_entry3(XDR *xdrs, entry3 *objp)
{
	if (!xdr_fileid3(xdrs, &objp->fileid))
		return (false);
	if (!xdr_filename3(xdrs, &objp->name))
		return (false);
	if (!xdr_cookie3(xdrs, &objp->cookie))
		return (false);
	if (!xdr_pointer(xdrs, (void **)&objp->nextentry, sizeof(entry3),
			 (xdrproc_t) xdr_entry3))
		return (false);
	return (true);
}

bool xdr_encode_entry3(XDR *xdrs, entry3 *objp)
{
	bool_t next = objp != NULL;

	if (!xdr_bool(xdrs, &next))
		return false;
	if (!next)
		return true;

	if (!xdr_fileid3(xdrs, &objp->fileid))
		return false;
	if (!xdr_filename3(xdrs, &objp->name))
		return false;
	if (!xdr_cookie3(xdrs, &objp->cookie))
		return false;

	return true;
}

void xdr_dirlist3_uio_release(struct xdr_uio *uio, u_int flags)
{
	int ix;

	LogFullDebug(COMPONENT_NFS_READDIR,
		     "Releasing %p, references %"PRIi32", count %d",
		     uio, uio->uio_references, (int) uio->uio_count);

	if (!(--uio->uio_references)) {
		for (ix = 0; ix < uio->uio_count; ix++) {
			gsh_free(uio->uio_vio[ix].vio_base);
		}
		gsh_free(uio);
	}
}

static inline bool xdr_dirlist3_encode(XDR *xdrs, dirlist3 *objp)
{
	if (!xdr_putbufs(xdrs, objp->uio, UIO_FLAG_NONE)) {
		objp->uio->uio_release(objp->uio, UIO_FLAG_NONE);
		return false;
	}
	return true;
}

bool xdr_dirlist3(XDR *xdrs, dirlist3 *objp)
{
	if (objp->uio != NULL)
		return xdr_dirlist3_encode(xdrs, objp);

	if (!xdr_pointer(xdrs, (void **)&objp->entries, sizeof(entry3),
			 (xdrproc_t) xdr_entry3))
		return (false);
	if (!xdr_bool(xdrs, &objp->eof))
		return (false);
	return (true);
}

bool xdr_READDIR3resok(XDR *xdrs, READDIR3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
		return (false);
	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
		return (false);
	if (!xdr_dirlist3(xdrs, &objp->reply))
		return (false);
	return (true);
}

bool xdr_READDIR3resfail(XDR *xdrs, READDIR3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
		return (false);
	return (true);
}

bool xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_READDIR3resok(xdrs, &objp->READDIR3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_READDIR3resfail(xdrs, &objp->READDIR3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_nfs_fh3(xdrs, &objp->dir))
		return (false);
	if (!xdr_cookie3(xdrs, &objp->cookie))
		return (false);
	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
		return (false);
	if (!xdr_count3(xdrs, &objp->dircount))
		return (false);
	if (!xdr_count3(xdrs, &objp->maxcount))
		return (false);
	lkhd->flags |= NFS_LOOKAHEAD_READDIR;
	return (true);
}

bool xdr_entryplus3(XDR *xdrs, entryplus3 *objp)
{
	if (!xdr_fileid3(xdrs, &objp->fileid))
		return (false);
	if (!xdr_filename3(xdrs, &objp->name))
		return (false);
	if (!xdr_cookie3(xdrs, &objp->cookie))
		return (false);
	if (!xdr_post_op_attr(xdrs, &objp->name_attributes))
		return (false);
	if (!xdr_post_op_fh3(xdrs, &objp->name_handle))
		return (false);
	if (!xdr_pointer(xdrs, (void **)&objp->nextentry, sizeof(entryplus3),
			 (xdrproc_t) xdr_entryplus3))
		return (false);
	return (true);
}

bool xdr_encode_entryplus3(XDR *xdrs, entryplus3 *objp, const fattr3 *attrs)
{
	bool_t next = objp != NULL;

	if (!xdr_bool(xdrs, &next))
		return false;
	if (!next)
		return true;

	if (!xdr_fileid3(xdrs, &objp->fileid))
		return false;
	if (!xdr_filename3(xdrs, &objp->name))
		return false;
	if (!xdr_cookie3(xdrs, &objp->cookie))
		return false;
	if (!xdr_bool(xdrs, &objp->name_attributes.attributes_follow))
		return false;
	if (objp->name_attributes.attributes_follow) {
		if (!xdr_fattr3(xdrs, (fattr3 *) attrs))
			return false;
	}
	if (!xdr_post_op_fh3(xdrs, &objp->name_handle))
		return false;
	return true;
}

void xdr_dirlistplus3_uio_release(struct xdr_uio *uio, u_int flags)
{
	int ix;

	LogFullDebug(COMPONENT_NFS_READDIR,
		     "Releasing %p, references %"PRIi32", count %d",
		     uio, uio->uio_references, (int) uio->uio_count);

	if (!(--uio->uio_references)) {
		for (ix = 0; ix < uio->uio_count; ix++) {
			gsh_free(uio->uio_vio[ix].vio_base);
		}
		gsh_free(uio);
	}
}

static inline bool xdr_dirlistplus3_encode(XDR *xdrs, dirlistplus3 *objp)
{
	if (!xdr_putbufs(xdrs, objp->uio, UIO_FLAG_NONE)) {
		objp->uio->uio_release(objp->uio, UIO_FLAG_NONE);
		return false;
	}
	return true;
}

bool xdr_dirlistplus3(XDR *xdrs, dirlistplus3 *objp)
{
	if (objp->uio != NULL)
		return xdr_dirlistplus3_encode(xdrs, objp);

	if (!xdr_pointer(xdrs, (void **)&objp->entries, sizeof(entryplus3),
			 (xdrproc_t) xdr_entryplus3))
		return (false);
	if (!xdr_bool(xdrs, &objp->eof))
		return (false);
	return (true);
}

bool xdr_READDIRPLUS3resok(XDR *xdrs, READDIRPLUS3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
		return (false);
	if (!xdr_cookieverf3(xdrs, objp->cookieverf))
		return (false);
	if (!xdr_dirlistplus3(xdrs, &objp->reply))
		return (false);
	return (true);
}

bool xdr_READDIRPLUS3resfail(XDR *xdrs, READDIRPLUS3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
		return (false);
	return (true);
}

bool xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_READDIRPLUS3resok
		    (xdrs, &objp->READDIRPLUS3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_READDIRPLUS3resfail
		    (xdrs, &objp->READDIRPLUS3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_FSSTAT3args(XDR *xdrs, FSSTAT3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->fsroot))
		return (false);
	return (true);
}

bool xdr_FSSTAT3resok(XDR *xdrs, FSSTAT3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_size3(xdrs, &objp->tbytes))
		return (false);
	if (!xdr_size3(xdrs, &objp->fbytes))
		return (false);
	if (!xdr_size3(xdrs, &objp->abytes))
		return (false);
	if (!xdr_size3(xdrs, &objp->tfiles))
		return (false);
	if (!xdr_size3(xdrs, &objp->ffiles))
		return (false);
	if (!xdr_size3(xdrs, &objp->afiles))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->invarsec))
		return (false);
	return (true);
}

bool xdr_FSSTAT3resfail(XDR *xdrs, FSSTAT3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	return (true);
}

bool xdr_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_FSSTAT3resok(xdrs, &objp->FSSTAT3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_FSSTAT3resfail(xdrs, &objp->FSSTAT3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_FSINFO3args(XDR *xdrs, FSINFO3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->fsroot))
		return (false);
	return (true);
}

bool xdr_FSINFO3resok(XDR *xdrs, FSINFO3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->rtmax))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->rtpref))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->rtmult))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->wtmax))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->wtpref))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->wtmult))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->dtpref))
		return (false);
	if (!xdr_size3(xdrs, &objp->maxfilesize))
		return (false);
	if (!xdr_nfstime3(xdrs, &objp->time_delta))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->properties))
		return (false);
	return (true);
}

bool xdr_FSINFO3resfail(XDR *xdrs, FSINFO3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	return (true);
}

bool xdr_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_FSINFO3resok(xdrs, &objp->FSINFO3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_FSINFO3resfail(xdrs, &objp->FSINFO3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_PATHCONF3args(XDR *xdrs, PATHCONF3args *objp)
{
	if (!xdr_nfs_fh3(xdrs, &objp->object))
		return (false);
	return (true);
}

bool xdr_PATHCONF3resok(XDR *xdrs, PATHCONF3resok *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->linkmax))
		return (false);
	if (!xdr_nfs3_uint32(xdrs, &objp->name_max))
		return (false);
	if (!xdr_bool(xdrs, &objp->no_trunc))
		return (false);
	if (!xdr_bool(xdrs, &objp->chown_restricted))
		return (false);
	if (!xdr_bool(xdrs, &objp->case_insensitive))
		return (false);
	if (!xdr_bool(xdrs, &objp->case_preserving))
		return (false);
	return (true);
}

bool xdr_PATHCONF3resfail(XDR *xdrs, PATHCONF3resfail *objp)
{
	if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
		return (false);
	return (true);
}

bool xdr_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_PATHCONF3resok(xdrs, &objp->PATHCONF3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_PATHCONF3resfail(xdrs, &objp->PATHCONF3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}

bool xdr_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
{
	struct nfs_request_lookahead *lkhd =
	    xdrs->x_public ? (struct nfs_request_lookahead *)xdrs->
	    x_public : &dummy_lookahead;

	if (!xdr_nfs_fh3(xdrs, &objp->file))
		return (false);
	if (!xdr_offset3(xdrs, &objp->offset))
		return (false);
	if (!xdr_count3(xdrs, &objp->count))
		return (false);
	lkhd->flags |= NFS_LOOKAHEAD_COMMIT;
	return (true);
}

bool xdr_COMMIT3resok(XDR *xdrs, COMMIT3resok *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
		return (false);
	if (!xdr_writeverf3(xdrs, objp->verf))
		return (false);
	return (true);
}

bool xdr_COMMIT3resfail(XDR *xdrs, COMMIT3resfail *objp)
{
	if (!xdr_wcc_data(xdrs, &objp->file_wcc))
		return (false);
	return (true);
}

bool xdr_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
{
	if (!xdr_nfsstat3(xdrs, &objp->status))
		return (false);
	switch (objp->status) {
	case NFS3_OK:
		if (!xdr_COMMIT3resok(xdrs, &objp->COMMIT3res_u.resok))
			return (false);
		break;
	default:
		if (!xdr_COMMIT3resfail(xdrs, &objp->COMMIT3res_u.resfail))
			return (false);
		break;
	}
	return (true);
}
