xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs_log_xdr.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <sys/systm.h>
30 #include <sys/cmn_err.h>
31 #include <sys/kmem.h>
32 #include <sys/cred.h>
33 #include <sys/dirent.h>
34 #include <rpc/types.h>
35 #include <nfs/nfs.h>
36 #include <nfs/export.h>
37 #include <rpc/svc.h>
38 #include <rpc/xdr.h>
39 #include <rpc/rpcb_prot.h>
40 #include <rpc/clnt.h>
41 #include <nfs/nfs_log.h>
42 
43 /*
44  * nfsl_principal_name_get - extracts principal from transport struct.
45  * Based on "uts/common/rpc/sec/sec_svc.c" function sec_svc_getcred.
46  */
47 static char *
48 nfsl_principal_name_get(struct svc_req *req)
49 {
50 	char				*principal_name = NULL;
51 	struct authdes_cred		*adc;
52 	rpc_gss_rawcred_t		*rcred;
53 	rpc_gss_ucred_t			*ucred;
54 	void				*cookie;
55 
56 	switch (req->rq_cred.oa_flavor) {
57 	case AUTH_UNIX:
58 	case AUTH_NONE:
59 		/* no principal name provided */
60 		break;
61 
62 	case AUTH_DES:
63 		adc = (struct authdes_cred *)req->rq_clntcred;
64 		principal_name = adc->adc_fullname.name;
65 		break;
66 
67 	case RPCSEC_GSS:
68 		(void) rpc_gss_getcred(req, &rcred, &ucred, &cookie);
69 		principal_name = (caddr_t)rcred->client_principal;
70 		break;
71 
72 	default:
73 		break;
74 	}
75 	return (principal_name);
76 }
77 
78 bool_t
79 xdr_timestruc32_t(XDR *xdrs, timestruc32_t *objp)
80 {
81 	if (!xdr_int(xdrs, &objp->tv_sec))
82 		return (FALSE);
83 	return (xdr_int(xdrs, &objp->tv_nsec));
84 }
85 
86 bool_t
87 xdr_nfsstat(XDR *xdrs, nfsstat *objp)
88 {
89 	return (xdr_enum(xdrs, (enum_t *)objp));
90 }
91 
92 bool_t
93 xdr_nfslog_sharefsres(XDR *xdrs, nfslog_sharefsres *objp)
94 {
95 	return (xdr_nfsstat(xdrs, objp));
96 }
97 
98 bool_t
99 xdr_nfsreadargs(XDR *xdrs, struct nfsreadargs *ra)
100 {
101 	if (xdr_fhandle(xdrs, &ra->ra_fhandle) &&
102 	    xdr_u_int(xdrs, &ra->ra_offset) &&
103 	    xdr_u_int(xdrs, &ra->ra_count) &&
104 	    xdr_u_int(xdrs, &ra->ra_totcount)) {
105 		return (TRUE);
106 	}
107 	return (FALSE);
108 }
109 
110 bool_t
111 xdr_nfslog_nfsreadargs(xdrs, objp)
112 	register XDR *xdrs;
113 	nfslog_nfsreadargs *objp;
114 {
115 	return (xdr_nfsreadargs(xdrs, objp));
116 }
117 
118 /*
119  * Current version (2 and up) xdr function for buffer header
120  * uses 64-bit offset (relocated to an 8 byte boundary), version 1 uses 32.
121  */
122 bool_t
123 xdr_nfslog_buffer_header(xdrs, objp)
124 	register XDR *xdrs;
125 	nfslog_buffer_header *objp;
126 {
127 	if (!xdr_u_int(xdrs, &objp->bh_length))
128 		return (FALSE);
129 	if (!xdr_rpcvers(xdrs, &objp->bh_version))
130 		return (FALSE);
131 	ASSERT(objp->bh_version > 1);
132 	if (!xdr_u_longlong_t(xdrs, &objp->bh_offset))
133 		return (FALSE);
134 	if (!xdr_u_int(xdrs, &objp->bh_flags))
135 		return (FALSE);
136 	return (xdr_timestruc32_t(xdrs, &objp->bh_timestamp));
137 }
138 
139 /*
140  * Hand coded xdr functions for the kernel ENCODE path
141  */
142 
143 bool_t
144 xdr_nfslog_request_record(
145 	XDR *xdrs,
146 	struct exportinfo *exi,
147 	struct svc_req *req,
148 	cred_t *cr,
149 	struct netbuf *pnb,
150 	unsigned int	reclen,
151 	unsigned int	record_id)
152 {
153 	char *netid = NULL;
154 	char *prin = NULL;
155 	unsigned int flavor;
156 	timestruc32_t ts;
157 	timestruc_t now;
158 	uid_t ruid;
159 	gid_t rgid;
160 
161 	if (xdrs->x_op != XDR_ENCODE)
162 		return (FALSE);
163 
164 	/*
165 	 * First we do the encoding of the record header
166 	 */
167 	if (!xdr_u_int(xdrs, &reclen))
168 		return (FALSE);
169 	if (!xdr_u_int(xdrs, &record_id))
170 		return (FALSE);
171 	if (!xdr_rpcprog(xdrs, &req->rq_prog))
172 		return (FALSE);
173 	if (!xdr_rpcproc(xdrs, &req->rq_proc))
174 		return (FALSE);
175 	if (!xdr_rpcvers(xdrs, &req->rq_vers))
176 		return (FALSE);
177 	flavor = req->rq_cred.oa_flavor;
178 	if (!xdr_u_int(xdrs, &flavor))
179 		return (FALSE);
180 
181 	gethrestime(&now);
182 	TIMESPEC_TO_TIMESPEC32(&ts, &now);
183 	if (!xdr_timestruc32_t(xdrs, &ts))
184 		return (FALSE);
185 
186 	/* This code depends on us doing XDR_ENCODE ops only */
187 	ruid = crgetruid(cr);
188 	if (!xdr_uid_t(xdrs, &ruid))
189 		return (FALSE);
190 	rgid = crgetrgid(cr);
191 	if (!xdr_gid_t(xdrs, &rgid))
192 		return (FALSE);
193 
194 	/*
195 	 * Now encode the rest of the request record (but not args/res)
196 	 */
197 	prin = nfsl_principal_name_get(req);
198 	if (!xdr_string(xdrs, &prin, ~0))
199 		return (FALSE);
200 	if (req->rq_xprt)
201 		netid = svc_getnetid(req->rq_xprt);
202 	if (!xdr_string(xdrs, &netid, ~0))
203 		return (FALSE);
204 	if (!xdr_string(xdrs, &exi->exi_export.ex_tag, ~0))
205 		return (FALSE);
206 	return (xdr_netbuf(xdrs, pnb));
207 }
208 
209 bool_t
210 xdr_nfslog_sharefsargs(XDR *xdrs, struct exportinfo *objp)
211 {
212 
213 	if (xdrs->x_op != XDR_ENCODE)
214 		return (FALSE);
215 
216 	if (!xdr_int(xdrs, &objp->exi_export.ex_flags))
217 		return (FALSE);
218 	if (!xdr_u_int(xdrs, &objp->exi_export.ex_anon))
219 		return (FALSE);
220 	if (!xdr_string(xdrs, &objp->exi_export.ex_path, ~0))
221 		return (FALSE);
222 	return (xdr_fhandle(xdrs, &objp->exi_fh));
223 }
224 
225 bool_t
226 xdr_nfslog_getfhargs(XDR *xdrs, nfslog_getfhargs *objp)
227 {
228 	if (!xdr_fhandle(xdrs, &objp->gfh_fh_buf))
229 		return (FALSE);
230 	return (xdr_string(xdrs, &objp->gfh_path, ~0));
231 }
232 
233 bool_t
234 xdr_nfslog_drok(XDR *xdrs, struct nfsdrok *objp)
235 {
236 	return (xdr_fhandle(xdrs, &objp->drok_fhandle));
237 }
238 
239 bool_t
240 xdr_nfslog_diropres(XDR *xdrs, struct nfsdiropres *objp)
241 {
242 	if (!xdr_nfsstat(xdrs, &objp->dr_status))
243 		return (FALSE);
244 	switch (objp->dr_status) {
245 	case NFS_OK:
246 		if (!xdr_nfslog_drok(xdrs, &objp->dr_drok))
247 			return (FALSE);
248 		break;
249 	}
250 	return (TRUE);
251 }
252 
253 bool_t
254 xdr_nfslog_getattrres(XDR *xdrs, struct nfsattrstat *objp)
255 {
256 	return (xdr_nfsstat(xdrs, &objp->ns_status));
257 }
258 
259 bool_t
260 xdr_nfslog_rrok(XDR *xdrs, struct nfsrrok *objp)
261 {
262 	if (!xdr_u_int(xdrs, &objp->rrok_attr.na_size))
263 		return (FALSE);
264 	return (xdr_u_int(xdrs, &objp->rrok_count));
265 }
266 
267 bool_t
268 xdr_nfslog_rdresult(XDR *xdrs, struct nfsrdresult *objp)
269 {
270 	if (!xdr_nfsstat(xdrs, &objp->rr_status))
271 		return (FALSE);
272 	switch (objp->rr_status) {
273 	case NFS_OK:
274 		if (!xdr_nfslog_rrok(xdrs, &objp->rr_u.rr_ok_u))
275 			return (FALSE);
276 		break;
277 	}
278 	return (TRUE);
279 }
280 
281 bool_t
282 xdr_nfslog_writeargs(XDR *xdrs, struct nfswriteargs *objp)
283 {
284 	if (!xdr_fhandle(xdrs, &objp->wa_args->otw_wa_fhandle))
285 		return (FALSE);
286 	if (!xdr_u_int(xdrs, &objp->wa_args->otw_wa_begoff))
287 		return (FALSE);
288 	if (!xdr_u_int(xdrs, &objp->wa_args->otw_wa_offset))
289 		return (FALSE);
290 	if (!xdr_u_int(xdrs, &objp->wa_args->otw_wa_totcount))
291 		return (FALSE);
292 	return (xdr_u_int(xdrs, &objp->wa_count));
293 }
294 
295 bool_t
296 xdr_nfslog_writeresult(XDR *xdrs, struct nfsattrstat *objp)
297 {
298 	if (!xdr_nfsstat(xdrs, &objp->ns_status))
299 		return (FALSE);
300 	switch (objp->ns_status) {
301 	case NFS_OK:
302 		if (!xdr_u_int(xdrs, &objp->ns_u.ns_attr_u.na_size))
303 			return (FALSE);
304 		break;
305 	}
306 	return (TRUE);
307 }
308 
309 bool_t
310 xdr_nfslog_diropargs(XDR *xdrs, struct nfsdiropargs *objp)
311 {
312 	if (!xdr_fhandle(xdrs, objp->da_fhandle))
313 		return (FALSE);
314 	return (xdr_string(xdrs, &objp->da_name, ~0));
315 }
316 
317 bool_t
318 xdr_nfslog_sattr(XDR *xdrs, struct nfssattr *objp)
319 {
320 	if (!xdr_u_int(xdrs, &objp->sa_mode))
321 		return (FALSE);
322 	if (!xdr_u_int(xdrs, &objp->sa_uid))
323 		return (FALSE);
324 	if (!xdr_u_int(xdrs, &objp->sa_gid))
325 		return (FALSE);
326 	if (!xdr_u_int(xdrs, &objp->sa_size))
327 		return (FALSE);
328 	if (!xdr_nfs2_timeval(xdrs, (nfs2_timeval *)&objp->sa_atime))
329 		return (FALSE);
330 	return (xdr_nfs2_timeval(xdrs, (nfs2_timeval *)&objp->sa_mtime));
331 }
332 
333 bool_t
334 xdr_nfslog_createargs(XDR *xdrs, struct nfscreatargs *objp)
335 {
336 	if (!xdr_nfslog_sattr(xdrs, objp->ca_sa))
337 		return (FALSE);
338 	return (xdr_nfslog_diropargs(xdrs, &objp->ca_da));
339 }
340 
341 bool_t
342 xdr_nfslog_setattrargs(XDR *xdrs, struct nfssaargs *objp)
343 {
344 	if (!xdr_fhandle(xdrs, &objp->saa_fh))
345 		return (FALSE);
346 	return (xdr_nfslog_sattr(xdrs, &objp->saa_sa));
347 }
348 
349 bool_t
350 xdr_nfslog_rdlnres(XDR *xdrs, struct nfsrdlnres *objp)
351 {
352 	caddr_t	lnres = NULL;
353 	int count;
354 
355 	if (!xdr_nfsstat(xdrs, &objp->rl_status))
356 		return (FALSE);
357 	switch (objp->rl_status) {
358 	case NFS_OK:
359 		if ((count = objp->rl_u.rl_srok_u.srok_count) != 0) {
360 			/*
361 			 * allocate extra element for terminating NULL
362 			 */
363 			lnres = kmem_alloc(count + 1, KM_SLEEP);
364 			bcopy(objp->rl_u.rl_srok_u.srok_data, lnres, count);
365 			lnres[count] = '\0';
366 		}
367 		if (!xdr_string(xdrs, &lnres, ~0)) {
368 			if (lnres != NULL)
369 				kmem_free(lnres, count + 1);
370 			return (FALSE);
371 		}
372 		if (lnres != NULL)
373 			kmem_free(lnres, count + 1);
374 		break;
375 	}
376 	return (TRUE);
377 }
378 
379 bool_t
380 xdr_nfslog_rnmargs(XDR *xdrs, struct nfsrnmargs *objp)
381 {
382 	if (!xdr_nfslog_diropargs(xdrs, &objp->rna_from))
383 		return (FALSE);
384 	return (xdr_nfslog_diropargs(xdrs, &objp->rna_to));
385 }
386 
387 bool_t
388 xdr_nfslog_linkargs(XDR *xdrs, struct nfslinkargs *objp)
389 {
390 	if (!xdr_fhandle(xdrs, objp->la_from))
391 		return (FALSE);
392 	return (xdr_nfslog_diropargs(xdrs, &objp->la_to));
393 }
394 
395 bool_t
396 xdr_nfslog_symlinkargs(XDR *xdrs, struct nfsslargs *objp)
397 {
398 	if (!xdr_nfslog_diropargs(xdrs, &objp->sla_from))
399 		return (FALSE);
400 	if (!xdr_string(xdrs, &objp->sla_tnm, ~0))
401 		return (FALSE);
402 	return (xdr_nfslog_sattr(xdrs, objp->sla_sa));
403 }
404 
405 bool_t
406 xdr_nfslog_statfs(XDR *xdrs, struct nfsstatfs *objp)
407 {
408 	return (xdr_nfsstat(xdrs, &objp->fs_status));
409 }
410 
411 bool_t
412 xdr_nfslog_rddirargs(XDR *xdrs, struct nfsrddirargs *objp)
413 {
414 	if (!xdr_fhandle(xdrs, &objp->rda_fh))
415 		return (FALSE);
416 	if (!xdr_u_int(xdrs, &objp->rda_offset))
417 		return (FALSE);
418 	return (xdr_u_int(xdrs, &objp->rda_count));
419 }
420 
421 bool_t
422 xdr_nfslog_rdok(XDR *xdrs, struct nfsrdok *objp)
423 {
424 	if (!xdr_u_int(xdrs, &objp->rdok_offset))
425 		return (FALSE);
426 	if (!xdr_u_int(xdrs, &objp->rdok_size))
427 		return (FALSE);
428 	return (xdr_bool(xdrs, &objp->rdok_eof));
429 }
430 
431 bool_t
432 xdr_nfslog_rddirres(XDR *xdrs, struct nfsrddirres *objp)
433 {
434 	if (!xdr_nfsstat(xdrs, &objp->rd_status))
435 		return (FALSE);
436 	switch (objp->rd_status) {
437 	case NFS_OK:
438 		if (!xdr_nfslog_rdok(xdrs, &objp->rd_u.rd_rdok_u))
439 			return (FALSE);
440 		break;
441 	}
442 	return (TRUE);
443 }
444 
445 bool_t
446 xdr_nfslog_diropargs3(XDR *xdrs, diropargs3 *objp)
447 {
448 	char *name;
449 
450 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->dir))
451 		return (FALSE);
452 	if (objp->name != nfs3nametoolong)
453 		name = objp->name;
454 	else {
455 		/*
456 		 * The name is not defined, set it to the
457 		 * zero length string.
458 		 */
459 		name = NULL;
460 	}
461 	return (xdr_string(xdrs, &name, ~0));
462 }
463 
464 bool_t
465 xdr_nfslog_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
466 {
467 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
468 		return (FALSE);
469 	switch (objp->status) {
470 	case NFS3_OK:
471 		if (!xdr_nfslog_nfs_fh3(xdrs, &objp->res_u.ok.object))
472 			return (FALSE);
473 		break;
474 	}
475 	return (TRUE);
476 }
477 
478 bool_t
479 xdr_set_size3(XDR *xdrs, set_size3 *objp)
480 {
481 	if (!xdr_bool(xdrs, &objp->set_it))
482 		return (FALSE);
483 	switch (objp->set_it) {
484 	case TRUE:
485 		if (!xdr_uint64(xdrs, &objp->size))
486 			return (FALSE);
487 		break;
488 	}
489 	return (TRUE);
490 }
491 
492 bool_t
493 xdr_nfslog_createhow3(XDR *xdrs, createhow3 *objp)
494 {
495 	if (!xdr_enum(xdrs, (enum_t *)&objp->mode))
496 		return (FALSE);
497 	switch (objp->mode) {
498 	case UNCHECKED:
499 	case GUARDED:
500 		if (!xdr_set_size3(xdrs,
501 			&objp->createhow3_u.obj_attributes.size))
502 			return (FALSE);
503 		break;
504 	case EXCLUSIVE:
505 		break;
506 	default:
507 		return (FALSE);
508 	}
509 	return (TRUE);
510 }
511 
512 bool_t
513 xdr_nfslog_CREATE3args(XDR *xdrs, CREATE3args *objp)
514 {
515 	if (!xdr_nfslog_diropargs3(xdrs, &objp->where))
516 		return (FALSE);
517 	return (xdr_nfslog_createhow3(xdrs, &objp->how));
518 }
519 
520 bool_t
521 xdr_nfslog_CREATE3resok(XDR *xdrs, CREATE3resok *objp)
522 {
523 	return (xdr_post_op_fh3(xdrs, &objp->obj));
524 }
525 
526 bool_t
527 xdr_nfslog_CREATE3res(XDR *xdrs, CREATE3res *objp)
528 {
529 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
530 		return (FALSE);
531 	switch (objp->status) {
532 	case NFS3_OK:
533 		if (!xdr_nfslog_CREATE3resok(xdrs, &objp->res_u.ok))
534 			return (FALSE);
535 		break;
536 	}
537 	return (TRUE);
538 }
539 
540 bool_t
541 xdr_nfslog_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
542 {
543 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
544 }
545 
546 bool_t
547 xdr_nfslog_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
548 {
549 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->object));
550 }
551 
552 bool_t
553 xdr_nfslog_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
554 {
555 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
556 }
557 
558 bool_t
559 xdr_nfslog_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
560 {
561 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->object))
562 		return (FALSE);
563 	return (xdr_set_size3(xdrs, &objp->new_attributes.size));
564 }
565 
566 bool_t
567 xdr_nfslog_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
568 {
569 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
570 }
571 
572 bool_t
573 xdr_nfslog_READLINK3res(XDR *xdrs, READLINK3res *objp)
574 {
575 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
576 		return (FALSE);
577 	switch (objp->status) {
578 	case NFS3_OK:
579 		if (!xdr_string(xdrs, &objp->res_u.ok.data, ~0))
580 			return (FALSE);
581 		break;
582 	}
583 	return (TRUE);
584 }
585 
586 bool_t
587 xdr_nfslog_READ3args(XDR *xdrs, READ3args *objp)
588 {
589 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
590 		return (FALSE);
591 	if (!xdr_uint64(xdrs, &objp->offset))
592 		return (FALSE);
593 	return (xdr_uint32(xdrs, &objp->count));
594 }
595 
596 bool_t
597 xdr_nfslog_READ3resok(XDR *xdrs, READ3resok *objp)
598 {
599 	if (!xdr_uint64(xdrs, &objp->file_attributes.attr.size))
600 		return (FALSE);
601 	if (!xdr_uint32(xdrs, &objp->count))
602 		return (FALSE);
603 	if (!xdr_bool(xdrs, &objp->eof))
604 		return (FALSE);
605 	return (xdr_u_int(xdrs, &objp->size));
606 }
607 
608 bool_t
609 xdr_nfslog_READ3res(XDR *xdrs, READ3res *objp)
610 {
611 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
612 		return (FALSE);
613 	switch (objp->status) {
614 	case NFS3_OK:
615 		if (!xdr_nfslog_READ3resok(xdrs, &objp->res_u.ok))
616 			return (FALSE);
617 		break;
618 	}
619 	return (TRUE);
620 }
621 
622 bool_t
623 xdr_nfslog_WRITE3args(XDR *xdrs, WRITE3args *objp)
624 {
625 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
626 		return (FALSE);
627 	if (!xdr_uint64(xdrs, &objp->offset))
628 		return (FALSE);
629 	if (!xdr_uint32(xdrs, &objp->count))
630 		return (FALSE);
631 	return (xdr_enum(xdrs, (enum_t *)&objp->stable));
632 }
633 
634 bool_t
635 xdr_nfslog_WRITE3resok(XDR *xdrs, WRITE3resok *objp)
636 {
637 	if (!xdr_uint64(xdrs, &objp->file_wcc.after.attr.size))
638 		return (FALSE);
639 	if (!xdr_uint32(xdrs, &objp->count))
640 		return (FALSE);
641 	return (xdr_enum(xdrs, (enum_t *)&objp->committed));
642 }
643 
644 bool_t
645 xdr_nfslog_WRITE3res(XDR *xdrs, WRITE3res *objp)
646 {
647 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
648 		return (FALSE);
649 	switch (objp->status) {
650 	case NFS3_OK:
651 		if (!xdr_nfslog_WRITE3resok(xdrs, &objp->res_u.ok))
652 			return (FALSE);
653 		break;
654 	}
655 	return (TRUE);
656 }
657 
658 bool_t
659 xdr_nfslog_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
660 {
661 	return (xdr_nfslog_diropargs3(xdrs, &objp->where));
662 }
663 
664 bool_t
665 xdr_nfslog_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
666 {
667 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
668 		return (FALSE);
669 	switch (objp->status) {
670 	case NFS3_OK:
671 		if (!xdr_post_op_fh3(xdrs, &objp->res_u.ok.obj))
672 			return (FALSE);
673 		break;
674 	}
675 	return (TRUE);
676 }
677 
678 bool_t
679 xdr_nfslog_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
680 {
681 	if (!xdr_nfslog_diropargs3(xdrs, &objp->where))
682 		return (FALSE);
683 	return (xdr_string(xdrs, &objp->symlink.symlink_data, ~0));
684 }
685 
686 bool_t
687 xdr_nfslog_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
688 {
689 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
690 		return (FALSE);
691 	switch (objp->status) {
692 	case NFS3_OK:
693 		if (!xdr_post_op_fh3(xdrs, &objp->res_u.ok.obj))
694 			return (FALSE);
695 		break;
696 	}
697 	return (TRUE);
698 }
699 
700 bool_t
701 xdr_nfslog_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
702 {
703 	if (!xdr_nfslog_diropargs3(xdrs, &objp->where))
704 		return (FALSE);
705 	return (xdr_enum(xdrs, (enum_t *)&objp->what.type));
706 }
707 
708 bool_t
709 xdr_nfslog_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
710 {
711 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
712 		return (FALSE);
713 	switch (objp->status) {
714 	case NFS3_OK:
715 		if (!xdr_post_op_fh3(xdrs, &objp->res_u.ok.obj))
716 			return (FALSE);
717 		break;
718 	}
719 	return (TRUE);
720 }
721 
722 bool_t
723 xdr_nfslog_REMOVE3args(XDR *xdrs, REMOVE3args *objp)
724 {
725 	return (xdr_nfslog_diropargs3(xdrs, &objp->object));
726 }
727 
728 bool_t
729 xdr_nfslog_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
730 {
731 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
732 }
733 
734 bool_t
735 xdr_nfslog_RMDIR3args(XDR *xdrs, RMDIR3args *objp)
736 {
737 	return (xdr_nfslog_diropargs3(xdrs, &objp->object));
738 }
739 
740 bool_t
741 xdr_nfslog_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
742 {
743 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
744 }
745 
746 bool_t
747 xdr_nfslog_RENAME3args(XDR *xdrs, RENAME3args *objp)
748 {
749 	if (!xdr_nfslog_diropargs3(xdrs, &objp->from))
750 		return (FALSE);
751 	return (xdr_nfslog_diropargs3(xdrs, &objp->to));
752 }
753 
754 bool_t
755 xdr_nfslog_RENAME3res(XDR *xdrs, RENAME3res *objp)
756 {
757 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
758 }
759 
760 bool_t
761 xdr_nfslog_LINK3args(XDR *xdrs, LINK3args *objp)
762 {
763 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
764 		return (FALSE);
765 	return (xdr_nfslog_diropargs3(xdrs, &objp->link));
766 }
767 
768 bool_t
769 xdr_nfslog_LINK3res(XDR *xdrs, LINK3res *objp)
770 {
771 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
772 }
773 
774 bool_t
775 xdr_nfslog_READDIR3args(XDR *xdrs, READDIR3args *objp)
776 {
777 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->dir));
778 }
779 
780 bool_t
781 xdr_nfslog_READDIR3res(XDR *xdrs, READDIR3res *objp)
782 {
783 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
784 }
785 
786 bool_t
787 xdr_nfslog_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
788 {
789 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->dir))
790 		return (FALSE);
791 	if (!xdr_uint32(xdrs, &objp->dircount))
792 		return (FALSE);
793 	return (xdr_uint32(xdrs, &objp->maxcount));
794 }
795 
796 #ifdef	nextdp
797 #undef	nextdp
798 #endif
799 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
800 
801 bool_t
802 xdr_nfslog_READDIRPLUS3resok(XDR *xdrs, READDIRPLUS3resok *objp)
803 {
804 	struct dirent64 *dp;
805 	bool_t true = TRUE;
806 	bool_t false = FALSE;
807 	int nents;
808 	char *name;
809 	entryplus3_info *infop;
810 
811 	dp = (struct dirent64 *)objp->reply.entries;
812 	nents = objp->size;
813 	infop = objp->infop;
814 	while (nents > 0) {
815 		if (dp->d_reclen == 0)
816 			return (FALSE);
817 		if (dp->d_ino == 0) {
818 			dp = nextdp(dp);
819 			infop++;
820 			nents--;
821 			continue;
822 		}
823 		name = dp->d_name;
824 
825 		if (!xdr_bool(xdrs, &true) ||
826 		    !xdr_post_op_fh3(xdrs, &infop->fh) ||
827 		    !xdr_string(xdrs, &name, ~0)) {
828 			return (FALSE);
829 		}
830 		dp = nextdp(dp);
831 		infop++;
832 		nents--;
833 	}
834 	if (!xdr_bool(xdrs, &false))
835 		return (FALSE);
836 
837 	return (xdr_bool(xdrs, &objp->reply.eof));
838 }
839 
840 bool_t
841 xdr_nfslog_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
842 {
843 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
844 		return (FALSE);
845 	switch (objp->status) {
846 	case NFS3_OK:
847 		if (!xdr_nfslog_READDIRPLUS3resok(xdrs, &objp->res_u.ok))
848 			return (FALSE);
849 		break;
850 	}
851 	return (TRUE);
852 }
853 
854 bool_t
855 xdr_nfslog_FSSTAT3args(XDR *xdrs, FSSTAT3args *objp)
856 {
857 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->fsroot));
858 }
859 
860 bool_t
861 xdr_nfslog_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
862 {
863 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
864 }
865 
866 bool_t
867 xdr_nfslog_FSINFO3args(XDR *xdrs, FSINFO3args *objp)
868 {
869 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->fsroot));
870 }
871 
872 bool_t
873 xdr_nfslog_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
874 {
875 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
876 }
877 
878 bool_t
879 xdr_nfslog_PATHCONF3args(XDR *xdrs, PATHCONF3args *objp)
880 {
881 	return (xdr_nfslog_nfs_fh3(xdrs, &objp->object));
882 }
883 
884 bool_t
885 xdr_nfslog_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
886 {
887 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
888 }
889 
890 bool_t
891 xdr_nfslog_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
892 {
893 	if (!xdr_nfslog_nfs_fh3(xdrs, &objp->file))
894 		return (FALSE);
895 	if (!xdr_uint64(xdrs, &objp->offset))
896 		return (FALSE);
897 	return (xdr_uint32(xdrs, &objp->count));
898 }
899 
900 bool_t
901 xdr_nfslog_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
902 {
903 	return (xdr_enum(xdrs, (enum_t *)&objp->status));
904 }
905 
906 bool_t
907 xdr_nfslog_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
908 {
909 	nfs_fh3 fh;
910 
911 	if (objp->fh3_len > NFS_FHMAXDATA || objp->fh3_xlen > NFS_FHMAXDATA) {
912 		fh = *objp;
913 		fh.fh3_len = NFS_FHMAXDATA;
914 		fh.fh3_xlen = NFS_FHMAXDATA;
915 		fh.fh3_length = NFS3_OLDFHSIZE;
916 		return (xdr_nfs_fh3_server(xdrs, &fh));
917 	}
918 	return (xdr_nfs_fh3_server(xdrs, objp));
919 }
920