xref: /onnv-gate/usr/src/uts/common/fs/cachefs/cachefs_log.c (revision 5331:3047ad28a67b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
54321Scasper  * Common Development and Distribution License (the "License").
64321Scasper  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
224321Scasper  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include <sys/errno.h>
290Sstevel@tonic-gate #include <sys/param.h>
300Sstevel@tonic-gate #include <sys/types.h>
310Sstevel@tonic-gate #include <sys/systm.h>
320Sstevel@tonic-gate #include <sys/user.h>
330Sstevel@tonic-gate #include <sys/stat.h>
340Sstevel@tonic-gate #include <sys/kstat.h>
350Sstevel@tonic-gate #include <sys/time.h>
360Sstevel@tonic-gate #include <sys/vfs.h>
370Sstevel@tonic-gate #include <sys/vnode.h>
380Sstevel@tonic-gate #include <sys/file.h>
390Sstevel@tonic-gate #include <rpc/types.h>
400Sstevel@tonic-gate #include <rpc/xdr.h>
410Sstevel@tonic-gate #include <sys/mode.h>
420Sstevel@tonic-gate #include <sys/pathname.h>
430Sstevel@tonic-gate #include <sys/cmn_err.h>
440Sstevel@tonic-gate #include <sys/debug.h>
450Sstevel@tonic-gate #include <sys/fs/cachefs_fs.h>
460Sstevel@tonic-gate #include <sys/fs/cachefs_log.h>
470Sstevel@tonic-gate #include <vm/seg.h>
480Sstevel@tonic-gate #include <vm/seg_map.h>
490Sstevel@tonic-gate #include <sys/sysmacros.h>
500Sstevel@tonic-gate 
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate  * ino64_t is a unsigned long on LP64 and unsigned long long on ILP32,
530Sstevel@tonic-gate  * the compiler emits many warnings when calling xdr_u_longlong_t with an
540Sstevel@tonic-gate  * unsigned long pointer on LP64 even though it's safe.
550Sstevel@tonic-gate  */
560Sstevel@tonic-gate #define	xdr_ino64(xdrs, p)	xdr_u_longlong_t((xdrs), (u_longlong_t *)(p))
570Sstevel@tonic-gate 
580Sstevel@tonic-gate /*
590Sstevel@tonic-gate  * cfs_time_t is an int in both LP64 and ILP32. To avoid compiler warnings
60*5331Samw  * define its xdr here explicitly
610Sstevel@tonic-gate  */
620Sstevel@tonic-gate #define	xdr_cfs_time_t(xdrs, p)	xdr_int((xdrs), (int *)(p))
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #define	CACHEFS_LOG_MAX_BUFFERED	65536
650Sstevel@tonic-gate #define	CACHEFS_LOG_LOWATER		 8192
660Sstevel@tonic-gate #define	CACHEFS_LOG_ENCODE_SIZE		 4096
670Sstevel@tonic-gate 
680Sstevel@tonic-gate #if (defined(_SYSCALL32_IMPL) || defined(_LP64))
690Sstevel@tonic-gate 
700Sstevel@tonic-gate #define	OUT_IF_TIME_OVERFLOW(cachep, time)				\
710Sstevel@tonic-gate 	if (TIME_OVERFLOW(time)) {					\
720Sstevel@tonic-gate 		cachefs_log_error(cachep, EOVERFLOW, 1);		\
730Sstevel@tonic-gate 		goto out;						\
740Sstevel@tonic-gate 	}
750Sstevel@tonic-gate 
760Sstevel@tonic-gate #define	RET_IF_TIME_OVERFLOW(cachep, time)				\
770Sstevel@tonic-gate 	if (TIME_OVERFLOW(time)) {					\
780Sstevel@tonic-gate 		cachefs_log_error(cachep, EOVERFLOW, 1);		\
790Sstevel@tonic-gate 		return;							\
800Sstevel@tonic-gate 	}
810Sstevel@tonic-gate 
820Sstevel@tonic-gate #else /* not (_SYSCALL32_IMPL || _LP64) */
830Sstevel@tonic-gate 
840Sstevel@tonic-gate #define	OUT_IF_TIME_OVERFLOW(cachep, time)
850Sstevel@tonic-gate 
860Sstevel@tonic-gate #define	RET_IF_TIME_OVERFLOW(cachep, time)
870Sstevel@tonic-gate 
880Sstevel@tonic-gate #endif /* (_SYSCALL32_IMPL || _LP64) */
890Sstevel@tonic-gate 
900Sstevel@tonic-gate typedef struct cachefs_log_work_list {
910Sstevel@tonic-gate 	void *data;
920Sstevel@tonic-gate 	size_t size;
930Sstevel@tonic-gate 	xdrproc_t translate;
940Sstevel@tonic-gate 	struct cachefs_log_work_list *next;
950Sstevel@tonic-gate } *cachefs_log_work_list_t;
960Sstevel@tonic-gate 
970Sstevel@tonic-gate /* forward declarations of static functions */
980Sstevel@tonic-gate static void cachefs_log_enqueue(cachefscache_t *, void *, int, xdrproc_t);
990Sstevel@tonic-gate static int cachefs_log_save_lc(cachefscache_t *);
1000Sstevel@tonic-gate static int cachefs_log_write_header(struct vnode *, cachefscache_t *, int);
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate static bool_t cachefs_xdr_logfile_header(XDR *,
1030Sstevel@tonic-gate     struct cachefs_log_logfile_header *);
1040Sstevel@tonic-gate static bool_t cachefs_xdr_mount(XDR *, struct cachefs_log_mount_record *);
1050Sstevel@tonic-gate static bool_t cachefs_xdr_umount(XDR *, struct cachefs_log_umount_record *);
1060Sstevel@tonic-gate static bool_t cachefs_xdr_getpage(XDR *, struct cachefs_log_getpage_record *);
1070Sstevel@tonic-gate static bool_t cachefs_xdr_readdir(XDR *, struct cachefs_log_readdir_record *);
1080Sstevel@tonic-gate static bool_t cachefs_xdr_readlink(XDR *,
1090Sstevel@tonic-gate     struct cachefs_log_readlink_record *);
1100Sstevel@tonic-gate static bool_t cachefs_xdr_remove(XDR *, struct cachefs_log_remove_record *);
1110Sstevel@tonic-gate static bool_t cachefs_xdr_rmdir(XDR *, struct cachefs_log_rmdir_record *);
1120Sstevel@tonic-gate static bool_t cachefs_xdr_truncate(XDR *,
1130Sstevel@tonic-gate     struct cachefs_log_truncate_record *);
1140Sstevel@tonic-gate static bool_t cachefs_xdr_putpage(XDR *, struct cachefs_log_putpage_record *);
1150Sstevel@tonic-gate static bool_t cachefs_xdr_create(XDR *, struct cachefs_log_create_record *);
1160Sstevel@tonic-gate static bool_t cachefs_xdr_mkdir(XDR *, struct cachefs_log_mkdir_record *);
1170Sstevel@tonic-gate static bool_t cachefs_xdr_rename(XDR *, struct cachefs_log_rename_record *);
1180Sstevel@tonic-gate static bool_t cachefs_xdr_symlink(XDR *, struct cachefs_log_symlink_record *);
1190Sstevel@tonic-gate static bool_t cachefs_xdr_populate(XDR *,
1200Sstevel@tonic-gate     struct cachefs_log_populate_record *);
1210Sstevel@tonic-gate static bool_t cachefs_xdr_csymlink(XDR *,
1220Sstevel@tonic-gate     struct cachefs_log_csymlink_record *);
1230Sstevel@tonic-gate static bool_t cachefs_xdr_filldir(XDR *,
1240Sstevel@tonic-gate     struct cachefs_log_filldir_record *);
1250Sstevel@tonic-gate static bool_t cachefs_xdr_mdcreate(XDR *,
1260Sstevel@tonic-gate     struct cachefs_log_mdcreate_record *);
1270Sstevel@tonic-gate static bool_t cachefs_xdr_gpfront(XDR *,
1280Sstevel@tonic-gate     struct cachefs_log_gpfront_record *);
1290Sstevel@tonic-gate static bool_t cachefs_xdr_rfdir(XDR *,
1300Sstevel@tonic-gate     struct cachefs_log_rfdir_record *);
1310Sstevel@tonic-gate static bool_t cachefs_xdr_ualloc(XDR *,
1320Sstevel@tonic-gate     struct cachefs_log_ualloc_record *);
1330Sstevel@tonic-gate static bool_t cachefs_xdr_calloc(XDR *,
1340Sstevel@tonic-gate     struct cachefs_log_calloc_record *);
1350Sstevel@tonic-gate static bool_t cachefs_xdr_nocache(XDR *,
1360Sstevel@tonic-gate     struct cachefs_log_nocache_record *);
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate extern time_t time;
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate /*
1420Sstevel@tonic-gate  * cachefs_log_kstat_snapshot(kstat_t *ksp, void *buf, int rw)
1430Sstevel@tonic-gate  *
1440Sstevel@tonic-gate  * called from /dev/kstat or somesuch.
1450Sstevel@tonic-gate  *
1460Sstevel@tonic-gate  */
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate int
cachefs_log_kstat_snapshot(kstat_t * ksp,void * buf,int rw)1490Sstevel@tonic-gate cachefs_log_kstat_snapshot(kstat_t *ksp, void *buf, int rw)
1500Sstevel@tonic-gate {
1510Sstevel@tonic-gate 	cachefs_log_control_t *lc = (cachefs_log_control_t *)ksp->ks_data;
1520Sstevel@tonic-gate 	cachefs_log_control_t *buflc = (cachefs_log_control_t *)buf;
1530Sstevel@tonic-gate 	cachefscache_t *cachep = (cachefscache_t *)(uintptr_t)lc->lc_cachep;
1540Sstevel@tonic-gate 	cachefs_log_cookie_t *cl = cachep->c_log;
1550Sstevel@tonic-gate 	int error = 0;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&cachep->c_log_mutex));
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 	/* if they just want to read the kstat, get that out of the way. */
1600Sstevel@tonic-gate 	if (rw != KSTAT_WRITE) {
1610Sstevel@tonic-gate 		bcopy(lc, buflc, sizeof (*lc));
1620Sstevel@tonic-gate 		return (0);
1630Sstevel@tonic-gate 	}
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	/* make sure they're passing us a valid control cookie */
1660Sstevel@tonic-gate 	if ((buflc->lc_cachep != lc->lc_cachep) ||
1670Sstevel@tonic-gate 	    (buflc->lc_magic != CACHEFS_LOG_MAGIC))
1680Sstevel@tonic-gate 		return (EIO);
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	/*
1710Sstevel@tonic-gate 	 * if logging is currently off
1720Sstevel@tonic-gate 	 *   o insist that we're being handed a logfile path
1730Sstevel@tonic-gate 	 *   o set cl, and give our cachep its value
1740Sstevel@tonic-gate 	 *
1750Sstevel@tonic-gate 	 * after that, if something goes wrong, we must call
1760Sstevel@tonic-gate 	 * cachefs_log_error to clear cachep->c_log.
1770Sstevel@tonic-gate 	 */
1780Sstevel@tonic-gate 	if (cl == NULL) {
1790Sstevel@tonic-gate 		if (buflc->lc_path[0] == '\0')
1800Sstevel@tonic-gate 			return (EIO);
1810Sstevel@tonic-gate 		cl = cachep->c_log = cachefs_log_create_cookie(lc);
1820Sstevel@tonic-gate 		if (cl == NULL) {
1830Sstevel@tonic-gate 			cachefs_log_error(cachep, ENOMEM, 0);
1840Sstevel@tonic-gate 			return (EIO);
1850Sstevel@tonic-gate 		}
1860Sstevel@tonic-gate 	}
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	/*
1890Sstevel@tonic-gate 	 * if we're being handed an empty logpath, then they must be
1900Sstevel@tonic-gate 	 * turning off logging; also, logging must have been turned on
1910Sstevel@tonic-gate 	 * before, or else the previous paragraph would have caught
1920Sstevel@tonic-gate 	 * it.
1930Sstevel@tonic-gate 	 */
1940Sstevel@tonic-gate 	if (buflc->lc_path[0] == '\0') {
1950Sstevel@tonic-gate 		cachefs_log_process_queue(cachep, 0);
1960Sstevel@tonic-gate 		cachep->c_log = NULL;
1970Sstevel@tonic-gate 		cachefs_log_destroy_cookie(cl);
1980Sstevel@tonic-gate 		bzero(lc, sizeof (*lc));
1990Sstevel@tonic-gate 		lc->lc_magic = CACHEFS_LOG_MAGIC;
2000Sstevel@tonic-gate 		lc->lc_cachep = (uint64_t)(uintptr_t)cachep;
201*5331Samw 		(void) VOP_REMOVE(cachep->c_dirvp, LOG_STATUS_NAME, kcred, NULL,
202*5331Samw 		    0);
2030Sstevel@tonic-gate 		return (0);
2040Sstevel@tonic-gate 	}
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	/*
2070Sstevel@tonic-gate 	 * if we get here, we know that we're being handed a valid log
2080Sstevel@tonic-gate 	 * control cookie, and that a path is set.  try to open the
2090Sstevel@tonic-gate 	 * log file, even if it's the same path, because they might
2100Sstevel@tonic-gate 	 * have removed the old log file out from under us.  if it
2110Sstevel@tonic-gate 	 * really is the same file, no harm done.
2120Sstevel@tonic-gate 	 */
2130Sstevel@tonic-gate 	if ((error = cachefs_log_logfile_open(cachep, buflc->lc_path)) != 0) {
2140Sstevel@tonic-gate 		cachefs_log_error(cachep, error, 0);
2150Sstevel@tonic-gate 		return (EIO);
2160Sstevel@tonic-gate 	}
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 	/*
2190Sstevel@tonic-gate 	 * if we get here, we have a valid logfile open.  we don't do
2200Sstevel@tonic-gate 	 * anything here with the bitmap of what's being logged, other
2210Sstevel@tonic-gate 	 * than copy it.  we're home free!
2220Sstevel@tonic-gate 	 */
2230Sstevel@tonic-gate 	bcopy(buflc, lc, sizeof (*lc));
2240Sstevel@tonic-gate 	if ((error = cachefs_log_save_lc(cachep)) != 0) {
2250Sstevel@tonic-gate 		cachefs_log_error(cachep, error, 0);
2260Sstevel@tonic-gate 		return (EIO);
2270Sstevel@tonic-gate 	}
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	return (0);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate static int
cachefs_log_save_lc(cachefscache_t * cachep)2330Sstevel@tonic-gate cachefs_log_save_lc(cachefscache_t *cachep)
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate 	cachefs_log_control_t *lc = (cachefs_log_control_t *)cachep->c_log_ctl;
2360Sstevel@tonic-gate 	struct vnode *savevp;
2370Sstevel@tonic-gate 	struct vattr attr;
2380Sstevel@tonic-gate 	int error = 0;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 	if (lc == NULL)
2410Sstevel@tonic-gate 		return (EINVAL);
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate 	attr.va_mode = S_IFREG | 0666;
2440Sstevel@tonic-gate 	attr.va_uid = 0;
2450Sstevel@tonic-gate 	attr.va_gid = 0;
2460Sstevel@tonic-gate 	attr.va_type = VREG;
2470Sstevel@tonic-gate 	attr.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	if (((error = VOP_LOOKUP(cachep->c_dirvp, LOG_STATUS_NAME, &savevp,
250*5331Samw 	    NULL, 0, NULL, kcred, NULL, NULL, NULL)) != 0) &&
2510Sstevel@tonic-gate 	    ((error = VOP_CREATE(cachep->c_dirvp, LOG_STATUS_NAME, &attr, EXCL,
252*5331Samw 	    0600, &savevp, kcred, 0, NULL, NULL)) != 0))
2530Sstevel@tonic-gate 		return (error);
2540Sstevel@tonic-gate 	ASSERT(savevp != NULL);
2550Sstevel@tonic-gate 	if (savevp == NULL)
2560Sstevel@tonic-gate 		return (ENOENT);
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 	error = vn_rdwr(UIO_WRITE, savevp,
2590Sstevel@tonic-gate 	    (caddr_t)lc, sizeof (*lc),
2600Sstevel@tonic-gate 	    0LL, UIO_SYSSPACE, FSYNC, (rlim64_t)RLIM_INFINITY, kcred, NULL);
2610Sstevel@tonic-gate 
2620Sstevel@tonic-gate 	VN_RELE(savevp);
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 	return (error);
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate /*
2680Sstevel@tonic-gate  * cachefs_log_cookie_t *cachefs_log_create_cookie(void *)
2690Sstevel@tonic-gate  *
2700Sstevel@tonic-gate  * creates and initializes the cookie, which lives in cachep.  called
2710Sstevel@tonic-gate  * from either a kstat write which turns on logging, or from
2720Sstevel@tonic-gate  * initializing cachep when a log-info-file exists.
2730Sstevel@tonic-gate  */
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate cachefs_log_cookie_t *
cachefs_log_create_cookie(cachefs_log_control_t * lc)2760Sstevel@tonic-gate cachefs_log_create_cookie(cachefs_log_control_t *lc)
2770Sstevel@tonic-gate {
2780Sstevel@tonic-gate 	cachefs_log_cookie_t *rc;
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate 	rc = cachefs_kmem_zalloc(sizeof (*rc), KM_NOSLEEP);
2810Sstevel@tonic-gate 	if (rc == NULL)
2820Sstevel@tonic-gate 		return (NULL);
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	rc->cl_magic = CACHEFS_LOG_MAGIC;
2850Sstevel@tonic-gate 	rc->cl_logctl = lc;
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 	return (rc);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate /*
2910Sstevel@tonic-gate  * void cachefs_log_destroy_cookie(cachefs_log_cookie_t *)
2920Sstevel@tonic-gate  *
2930Sstevel@tonic-gate  * destroys the log cookie.  called from cachefs_log_error, or from
2940Sstevel@tonic-gate  * destroying the cachep.
2950Sstevel@tonic-gate  *
2960Sstevel@tonic-gate  */
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate void
cachefs_log_destroy_cookie(cachefs_log_cookie_t * cl)2990Sstevel@tonic-gate cachefs_log_destroy_cookie(cachefs_log_cookie_t *cl)
3000Sstevel@tonic-gate {
3010Sstevel@tonic-gate 	cachefs_log_work_list_t node, oldnode;
3020Sstevel@tonic-gate 
3030Sstevel@tonic-gate 	if (cl == NULL)
3040Sstevel@tonic-gate 		return;
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	ASSERT(cl->cl_magic == CACHEFS_LOG_MAGIC);
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	cl->cl_magic++;
3090Sstevel@tonic-gate 	node = cl->cl_head;
3100Sstevel@tonic-gate 	while (node != NULL) {
3110Sstevel@tonic-gate 		cachefs_kmem_free(node->data, node->size);
3120Sstevel@tonic-gate 		oldnode = node;
3130Sstevel@tonic-gate 		node = node->next;
3140Sstevel@tonic-gate 		cachefs_kmem_free(oldnode, sizeof (*oldnode));
3150Sstevel@tonic-gate 	}
3160Sstevel@tonic-gate 	if (cl->cl_logvp != NULL)
3170Sstevel@tonic-gate 		VN_RELE(cl->cl_logvp);
3180Sstevel@tonic-gate 	cachefs_kmem_free(cl, sizeof (*cl));
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate /*
3220Sstevel@tonic-gate  * int cachefs_log_logfile_open(cachefscache_t *, char *)
3230Sstevel@tonic-gate  *
3240Sstevel@tonic-gate  * opens the logfile, and stores the path string if its successful.
3250Sstevel@tonic-gate  *
326*5331Samw  * returns an errno if one occurred.
3270Sstevel@tonic-gate  *
3280Sstevel@tonic-gate  */
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate int
cachefs_log_logfile_open(cachefscache_t * cachep,char * path)3310Sstevel@tonic-gate cachefs_log_logfile_open(cachefscache_t *cachep, char *path)
3320Sstevel@tonic-gate {
3330Sstevel@tonic-gate 	cachefs_log_cookie_t *cl = cachep->c_log;
3340Sstevel@tonic-gate 	struct vnode *newvp = NULL;
3350Sstevel@tonic-gate 	int error = 0;
3360Sstevel@tonic-gate 	int i;
3370Sstevel@tonic-gate 
3380Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&cachep->c_log_mutex));
3390Sstevel@tonic-gate 	ASSERT(cl != NULL);
3400Sstevel@tonic-gate 	ASSERT(cl->cl_magic == CACHEFS_LOG_MAGIC);
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	/* lookup the pathname -- it must already exist! */
3430Sstevel@tonic-gate 	error = lookupname(path, UIO_SYSSPACE, FOLLOW, NULL, &newvp);
3440Sstevel@tonic-gate 	if (error)
3450Sstevel@tonic-gate 		goto out;
3460Sstevel@tonic-gate 	ASSERT(newvp != NULL);
3470Sstevel@tonic-gate 	if (newvp == NULL) {
3480Sstevel@tonic-gate 		error = ENOENT; /* XXX this shouldn't happen (yeah right) */
3490Sstevel@tonic-gate 		goto out;
3500Sstevel@tonic-gate 	}
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	/* easy out if we just re-opened the same logfile */
3530Sstevel@tonic-gate 	if (cl->cl_logvp == newvp) {
3540Sstevel@tonic-gate 		VN_RELE(newvp);
3550Sstevel@tonic-gate 		goto out;
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate 	/* XXX we may change this to allow named pipes */
3590Sstevel@tonic-gate 	if (newvp->v_type != VREG) {
3600Sstevel@tonic-gate 		error = EINVAL;
3610Sstevel@tonic-gate 		goto out;
3620Sstevel@tonic-gate 	}
3630Sstevel@tonic-gate 	if (vn_matchops(newvp, cachefs_getvnodeops())) {
3640Sstevel@tonic-gate 		error = EINVAL;
3650Sstevel@tonic-gate 		goto out;
3660Sstevel@tonic-gate 	}
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	/* write out the header */
3690Sstevel@tonic-gate 	error = cachefs_log_write_header(newvp, cachep, 0);
3700Sstevel@tonic-gate 	if (error)
3710Sstevel@tonic-gate 		goto out;
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	/* if we get here, we successfully opened the log. */
3740Sstevel@tonic-gate 	if (cl->cl_logvp != NULL)
3750Sstevel@tonic-gate 		VN_RELE(cl->cl_logvp);
3760Sstevel@tonic-gate 	cl->cl_logvp = newvp;
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 	/*
3790Sstevel@tonic-gate 	 * `fake' a mount entry for each mounted cachefs filesystem.
3800Sstevel@tonic-gate 	 * this is overkill, but it's easiest and most foolproof way
3810Sstevel@tonic-gate 	 * to do things here.  the user-level consumers of the logfile
3820Sstevel@tonic-gate 	 * have to expect extraneous mount entries and deal with it
3830Sstevel@tonic-gate 	 * correctly.
3840Sstevel@tonic-gate 	 */
3850Sstevel@tonic-gate 	mutex_exit(&cachep->c_log_mutex);
3860Sstevel@tonic-gate 	for (i = 0; i < cachefs_kstat_key_n; i++) {
3870Sstevel@tonic-gate 		cachefs_kstat_key_t *k;
3880Sstevel@tonic-gate 		struct vfs *vfsp;
3890Sstevel@tonic-gate 		struct fscache *fscp;
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 		k = cachefs_kstat_key + i;
3920Sstevel@tonic-gate 		if (! k->ks_mounted)
3930Sstevel@tonic-gate 			continue;
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 		vfsp = (struct vfs *)(uintptr_t)k->ks_vfsp;
3960Sstevel@tonic-gate 		fscp = VFS_TO_FSCACHE(vfsp);
3970Sstevel@tonic-gate 		cachefs_log_mount(cachep, 0, vfsp, fscp,
3980Sstevel@tonic-gate 		    (char *)(uintptr_t)k->ks_mountpoint, UIO_SYSSPACE,
3990Sstevel@tonic-gate 		    (char *)(uintptr_t)k->ks_cacheid);
4000Sstevel@tonic-gate 	}
4010Sstevel@tonic-gate 	mutex_enter(&cachep->c_log_mutex);
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate out:
4040Sstevel@tonic-gate 	if ((error != 0) && (newvp != NULL))
4050Sstevel@tonic-gate 		VN_RELE(newvp);
4060Sstevel@tonic-gate 	return (error);
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate 
4090Sstevel@tonic-gate /*
410*5331Samw  * called when an error occurred during logging.  send the error to
4110Sstevel@tonic-gate  * syslog, invalidate the logfile, and stop logging.
4120Sstevel@tonic-gate  */
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate void
cachefs_log_error(cachefscache_t * cachep,int error,int getlock)4150Sstevel@tonic-gate cachefs_log_error(cachefscache_t *cachep, int error, int getlock)
4160Sstevel@tonic-gate {
4170Sstevel@tonic-gate 	cachefs_log_cookie_t *cl = cachep->c_log;
4180Sstevel@tonic-gate 	cachefs_log_control_t *lc = cachep->c_log_ctl;
4190Sstevel@tonic-gate 	int writable = 0;
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 	ASSERT((getlock) || (MUTEX_HELD(&cachep->c_log_mutex)));
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate 	if (getlock)
4240Sstevel@tonic-gate 		mutex_enter(&cachep->c_log_mutex);
4250Sstevel@tonic-gate 
4260Sstevel@tonic-gate 	if ((cachep->c_flags & (CACHE_NOCACHE | CACHE_NOFILL)) == 0)
4270Sstevel@tonic-gate 		writable = 1;
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	cmn_err(CE_WARN, "cachefs logging: error %d\n", error);
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate 	if ((writable) && (cl != NULL) && (cl->cl_logvp != NULL))
4320Sstevel@tonic-gate 		(void) cachefs_log_write_header(cl->cl_logvp, cachep, error);
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate 	cachep->c_log = NULL;
4350Sstevel@tonic-gate 	if (cl != NULL)
4360Sstevel@tonic-gate 		cachefs_log_destroy_cookie(cl);
4370Sstevel@tonic-gate 	bzero(lc, sizeof (cachefs_log_control_t));
4380Sstevel@tonic-gate 	lc->lc_magic = CACHEFS_LOG_MAGIC;
4390Sstevel@tonic-gate 	lc->lc_cachep = (uint64_t)(uintptr_t)cachep;
4400Sstevel@tonic-gate 	if (writable)
441*5331Samw 		(void) VOP_REMOVE(cachep->c_dirvp, LOG_STATUS_NAME, kcred, NULL,
442*5331Samw 		    0);
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate 	if (getlock)
4450Sstevel@tonic-gate 		mutex_exit(&cachep->c_log_mutex);
4460Sstevel@tonic-gate }
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate static int
cachefs_log_write_header(struct vnode * vp,cachefscache_t * cachep,int error)4490Sstevel@tonic-gate cachefs_log_write_header(struct vnode *vp, cachefscache_t *cachep, int error)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate 	struct cachefs_log_logfile_header header, oheader;
4520Sstevel@tonic-gate 	char buffy[2 * sizeof (header)];
4530Sstevel@tonic-gate 	int Errno = 0;
4540Sstevel@tonic-gate 	struct vattr attr;
4550Sstevel@tonic-gate 	int gotold = 0;
4560Sstevel@tonic-gate 	XDR xdrm;
4570Sstevel@tonic-gate 
4580Sstevel@tonic-gate 	attr.va_mask = AT_SIZE;
459*5331Samw 	if ((error = VOP_GETATTR(vp, &attr, 0, kcred, NULL)) != 0)
4600Sstevel@tonic-gate 		goto out;
4610Sstevel@tonic-gate 	if (attr.va_size != 0) {
4620Sstevel@tonic-gate 		error = vn_rdwr(UIO_READ, vp, buffy,
4630Sstevel@tonic-gate 		    MIN(sizeof (buffy), attr.va_size),
4640Sstevel@tonic-gate 		    0LL, UIO_SYSSPACE, 0, (rlim64_t)RLIM_INFINITY, kcred, NULL);
4650Sstevel@tonic-gate 		if (error != 0)
4660Sstevel@tonic-gate 			goto out;
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate 		xdrm.x_ops = NULL;
4690Sstevel@tonic-gate 		xdrmem_create(&xdrm, buffy, sizeof (buffy), XDR_DECODE);
4700Sstevel@tonic-gate 		if ((xdrm.x_ops == NULL) ||
4710Sstevel@tonic-gate 		    (! cachefs_xdr_logfile_header(&xdrm, &oheader))) {
4720Sstevel@tonic-gate 			if (xdrm.x_ops != NULL)
4730Sstevel@tonic-gate 				xdr_destroy(&xdrm);
4740Sstevel@tonic-gate 			error = EINVAL;
4750Sstevel@tonic-gate 			goto out;
4760Sstevel@tonic-gate 		}
4770Sstevel@tonic-gate 		xdr_destroy(&xdrm);
4780Sstevel@tonic-gate 		gotold = 1;
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 		if (oheader.lh_magic != CACHEFS_LOG_MAGIC) {
4810Sstevel@tonic-gate 			error = EINVAL;
4820Sstevel@tonic-gate 			goto out;
4830Sstevel@tonic-gate 		}
4840Sstevel@tonic-gate 	}
4850Sstevel@tonic-gate 
4860Sstevel@tonic-gate 	xdrm.x_ops = NULL;
4870Sstevel@tonic-gate 
4880Sstevel@tonic-gate 	xdrmem_create(&xdrm, buffy, sizeof (buffy), XDR_ENCODE);
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 	if (gotold) {
4910Sstevel@tonic-gate 		header = oheader;
4920Sstevel@tonic-gate 	} else {
4930Sstevel@tonic-gate 		header.lh_magic = CACHEFS_LOG_MAGIC;
4940Sstevel@tonic-gate 		header.lh_revision = CACHEFS_LOG_FILE_REV;
4950Sstevel@tonic-gate 		header.lh_blocks = cachep->c_usage.cu_blksused;
4960Sstevel@tonic-gate 		header.lh_files = cachep->c_usage.cu_filesused;
4970Sstevel@tonic-gate 		header.lh_maxbsize = MAXBSIZE;
4980Sstevel@tonic-gate 		header.lh_pagesize = PAGESIZE;
4990Sstevel@tonic-gate 	}
5000Sstevel@tonic-gate 
5010Sstevel@tonic-gate 	/* these are things that we stomp over for every header write */
5020Sstevel@tonic-gate 	header.lh_errno = Errno;
5030Sstevel@tonic-gate 
5040Sstevel@tonic-gate 	if (! cachefs_xdr_logfile_header(&xdrm, &header)) {
5050Sstevel@tonic-gate 		error = ENOMEM;
5060Sstevel@tonic-gate 		goto out;
5070Sstevel@tonic-gate 	}
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 	error = vn_rdwr(UIO_WRITE, vp,
5100Sstevel@tonic-gate 	    (caddr_t)buffy, xdr_getpos(&xdrm),
5110Sstevel@tonic-gate 	    0LL, UIO_SYSSPACE, FSYNC, (rlim64_t)RLIM_INFINITY, kcred, NULL);
5120Sstevel@tonic-gate 	if (error)
5130Sstevel@tonic-gate 		goto out;
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate out:
5160Sstevel@tonic-gate 	if (xdrm.x_ops != NULL)
5170Sstevel@tonic-gate 		xdr_destroy(&xdrm);
5180Sstevel@tonic-gate 	return (error);
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate /*
5220Sstevel@tonic-gate  * enqueues a record to be written to the logfile.
5230Sstevel@tonic-gate  */
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate static void
cachefs_log_enqueue(cachefscache_t * cachep,void * record,int size,xdrproc_t translate)5260Sstevel@tonic-gate cachefs_log_enqueue(cachefscache_t *cachep, void *record, int size,
5270Sstevel@tonic-gate     xdrproc_t translate)
5280Sstevel@tonic-gate {
5290Sstevel@tonic-gate 	cachefs_log_cookie_t *cl;
5300Sstevel@tonic-gate 	cachefs_log_work_list_t newnode, oldnode;
5310Sstevel@tonic-gate 
5320Sstevel@tonic-gate 	mutex_enter(&cachep->c_log_mutex);
5330Sstevel@tonic-gate 	cl = cachep->c_log;
5340Sstevel@tonic-gate 
5350Sstevel@tonic-gate 	if (cl == NULL) { /* someone turned off logging out from under us */
5360Sstevel@tonic-gate 		mutex_exit(&cachep->c_log_mutex);
5370Sstevel@tonic-gate 		cachefs_kmem_free(record, size);
5380Sstevel@tonic-gate 		return;
5390Sstevel@tonic-gate 	}
5400Sstevel@tonic-gate 	ASSERT(cl->cl_magic == CACHEFS_LOG_MAGIC);
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 	cl->cl_size += size;
5430Sstevel@tonic-gate 	newnode = cachefs_kmem_zalloc(sizeof (*newnode), KM_NOSLEEP);
5440Sstevel@tonic-gate 	if ((cl->cl_size > CACHEFS_LOG_MAX_BUFFERED) || (newnode == NULL)) {
5450Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 0);
5460Sstevel@tonic-gate 		if (newnode != NULL)
5470Sstevel@tonic-gate 			cachefs_kmem_free(newnode, sizeof (*newnode));
5480Sstevel@tonic-gate 		cachefs_kmem_free(record, size);
5490Sstevel@tonic-gate 		mutex_exit(&cachep->c_log_mutex);
5500Sstevel@tonic-gate 		return;
5510Sstevel@tonic-gate 	}
5520Sstevel@tonic-gate 
5530Sstevel@tonic-gate 	newnode->data = record;
5540Sstevel@tonic-gate 	newnode->size = size;
5550Sstevel@tonic-gate 	newnode->translate = translate;
5560Sstevel@tonic-gate 	newnode->next = NULL;
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	oldnode = (cachefs_log_work_list_t)cl->cl_tail;
5590Sstevel@tonic-gate 	if (oldnode != NULL)
5600Sstevel@tonic-gate 		oldnode->next = newnode;
5610Sstevel@tonic-gate 	cl->cl_tail = newnode;
5620Sstevel@tonic-gate 	if (cl->cl_head == NULL)
5630Sstevel@tonic-gate 		cl->cl_head = newnode;
5640Sstevel@tonic-gate 	mutex_exit(&cachep->c_log_mutex);
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate 	if (cl->cl_size >= CACHEFS_LOG_LOWATER) {
5670Sstevel@tonic-gate 		mutex_enter(&cachep->c_workq.wq_queue_lock);
5680Sstevel@tonic-gate 		cachep->c_workq.wq_logwork = 1;
5690Sstevel@tonic-gate 		cv_signal(&cachep->c_workq.wq_req_cv);
5700Sstevel@tonic-gate 		mutex_exit(&cachep->c_workq.wq_queue_lock);
5710Sstevel@tonic-gate 	}
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate 
5740Sstevel@tonic-gate /*
5750Sstevel@tonic-gate  * processes the log queue.  run by an async worker thread, or via
5760Sstevel@tonic-gate  * cachefs_cache_sync().
5770Sstevel@tonic-gate  */
5780Sstevel@tonic-gate 
5790Sstevel@tonic-gate void
cachefs_log_process_queue(cachefscache_t * cachep,int getlock)5800Sstevel@tonic-gate cachefs_log_process_queue(cachefscache_t *cachep, int getlock)
5810Sstevel@tonic-gate {
5820Sstevel@tonic-gate 	cachefs_log_cookie_t *cl;
5830Sstevel@tonic-gate 	cachefs_log_work_list_t work, workhead, oldwork;
5840Sstevel@tonic-gate 	struct vnode *logvp = NULL;
5850Sstevel@tonic-gate 	struct uio uio;
5860Sstevel@tonic-gate 	struct iovec iov;
5870Sstevel@tonic-gate 	int error = 0;
5880Sstevel@tonic-gate 	XDR xdrm;
5890Sstevel@tonic-gate 	char *buffy = NULL;
5900Sstevel@tonic-gate 
5910Sstevel@tonic-gate 	/*
5920Sstevel@tonic-gate 	 * NULL out the x_ops field of XDR.  this way, if x_ops !=
5930Sstevel@tonic-gate 	 * NULL, we know that we did the xdr*_create() successfully.
5940Sstevel@tonic-gate 	 * this is documented in the xdr_create man page.
5950Sstevel@tonic-gate 	 */
5960Sstevel@tonic-gate 
5970Sstevel@tonic-gate 	xdrm.x_ops = NULL;
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate 	/* see if we're still logging */
6000Sstevel@tonic-gate 	if (getlock)
6010Sstevel@tonic-gate 		mutex_enter(&cachep->c_log_mutex);
6020Sstevel@tonic-gate 	cl = cachep->c_log;
6030Sstevel@tonic-gate 	if ((cl == NULL) || (cl->cl_magic != CACHEFS_LOG_MAGIC)) {
6040Sstevel@tonic-gate 		if (getlock)
6050Sstevel@tonic-gate 			mutex_exit(&cachep->c_log_mutex);
6060Sstevel@tonic-gate 		return;
6070Sstevel@tonic-gate 	}
6080Sstevel@tonic-gate 
6090Sstevel@tonic-gate 	/* get the work, and let go of the mutex asap. */
6100Sstevel@tonic-gate 	workhead = cl->cl_head;
6110Sstevel@tonic-gate 	cl->cl_head = cl->cl_tail = NULL;
6120Sstevel@tonic-gate 	cl->cl_size = 0;
6130Sstevel@tonic-gate 	logvp = cl->cl_logvp;
6140Sstevel@tonic-gate 	ASSERT(logvp != NULL);
6150Sstevel@tonic-gate 	if (logvp == NULL) {
6160Sstevel@tonic-gate 		if (getlock)
6170Sstevel@tonic-gate 			mutex_exit(&cachep->c_log_mutex);
6180Sstevel@tonic-gate 		return;
6190Sstevel@tonic-gate 	}
6200Sstevel@tonic-gate 	VN_HOLD(logvp);
6210Sstevel@tonic-gate 	if (getlock)
6220Sstevel@tonic-gate 		mutex_exit(&cachep->c_log_mutex);
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate 	/* we don't use vn_rdwr() because there's no way to set FNONBLOCK */
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate 	uio.uio_iov = &iov;
6270Sstevel@tonic-gate 	uio.uio_iovcnt = 1;
6280Sstevel@tonic-gate 	uio.uio_loffset = 0; /* fake -- we do FAPPEND */
6290Sstevel@tonic-gate 	uio.uio_segflg = (short)UIO_SYSSPACE;
6300Sstevel@tonic-gate 	uio.uio_llimit = MAXOFFSET_T;
6310Sstevel@tonic-gate 	uio.uio_fmode = FWRITE | FNONBLOCK;
6320Sstevel@tonic-gate 	uio.uio_extflg = UIO_COPY_CACHED;
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate 	buffy = cachefs_kmem_alloc(CACHEFS_LOG_ENCODE_SIZE, KM_SLEEP);
6350Sstevel@tonic-gate 	xdrmem_create(&xdrm, buffy, CACHEFS_LOG_ENCODE_SIZE, XDR_ENCODE);
6360Sstevel@tonic-gate 
6370Sstevel@tonic-gate 	(void) VOP_RWLOCK(logvp, V_WRITELOCK_TRUE, NULL);
6380Sstevel@tonic-gate 	for (work = workhead; work != NULL; work = work->next) {
6390Sstevel@tonic-gate 		if (! (work->translate)(&xdrm, work->data)) {
6400Sstevel@tonic-gate 			VOP_RWUNLOCK(logvp, V_WRITELOCK_TRUE, NULL);
6410Sstevel@tonic-gate 			error = ENOMEM;
6420Sstevel@tonic-gate 			goto out;
6430Sstevel@tonic-gate 		}
6440Sstevel@tonic-gate 
6450Sstevel@tonic-gate 		iov.iov_base = buffy;
6460Sstevel@tonic-gate 		iov.iov_len = uio.uio_resid = xdr_getpos(&xdrm);
6470Sstevel@tonic-gate 		(void) xdr_setpos(&xdrm, 0);
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 		error = VOP_WRITE(logvp, &uio, FAPPEND, kcred, NULL);
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 		/* XXX future -- check for EAGAIN */
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 		if ((error) || (uio.uio_resid)) {
6540Sstevel@tonic-gate 			if (uio.uio_resid != 0)
6550Sstevel@tonic-gate 				error = EIO;
6560Sstevel@tonic-gate 			VOP_RWUNLOCK(logvp, V_WRITELOCK_TRUE, NULL);
6570Sstevel@tonic-gate 			goto out;
6580Sstevel@tonic-gate 		}
6590Sstevel@tonic-gate 	}
6600Sstevel@tonic-gate 	VOP_RWUNLOCK(logvp, V_WRITELOCK_TRUE, NULL);
6610Sstevel@tonic-gate 
6620Sstevel@tonic-gate out:
6630Sstevel@tonic-gate 	if (xdrm.x_ops != NULL)
6640Sstevel@tonic-gate 		xdr_destroy(&xdrm);
6650Sstevel@tonic-gate 	if (buffy != NULL)
6660Sstevel@tonic-gate 		cachefs_kmem_free(buffy, CACHEFS_LOG_ENCODE_SIZE);
6670Sstevel@tonic-gate 
6680Sstevel@tonic-gate 	/*
669*5331Samw 	 * if an error occurred, we need to free the buffers ourselves.
6700Sstevel@tonic-gate 	 * cachefs_destory_cookie() can't do it.
6710Sstevel@tonic-gate 	 */
6720Sstevel@tonic-gate 
6730Sstevel@tonic-gate 	work = workhead;
6740Sstevel@tonic-gate 	while (work != NULL) {
6750Sstevel@tonic-gate 		cachefs_kmem_free(work->data, work->size);
6760Sstevel@tonic-gate 		oldwork = work;
6770Sstevel@tonic-gate 		work = work->next;
6780Sstevel@tonic-gate 		cachefs_kmem_free(oldwork, sizeof (*oldwork));
6790Sstevel@tonic-gate 	}
6800Sstevel@tonic-gate 	if (logvp != NULL)
6810Sstevel@tonic-gate 		VN_RELE(logvp);
6820Sstevel@tonic-gate 	if (error) {
6830Sstevel@tonic-gate 		cachefs_log_error(cachep, error, 1);
6840Sstevel@tonic-gate 		return;
6850Sstevel@tonic-gate 	}
6860Sstevel@tonic-gate }
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate static bool_t
cachefs_xdr_logfile_header(XDR * xdrs,struct cachefs_log_logfile_header * h)6890Sstevel@tonic-gate cachefs_xdr_logfile_header(XDR *xdrs, struct cachefs_log_logfile_header *h)
6900Sstevel@tonic-gate {
6910Sstevel@tonic-gate 	if ((! xdr_u_int(xdrs, &h->lh_magic)) ||
6920Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &h->lh_revision)) ||
6930Sstevel@tonic-gate 	    (! xdr_int(xdrs, &h->lh_errno)) ||
6940Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &h->lh_blocks)) ||
6950Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &h->lh_files)) ||
6960Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &h->lh_maxbsize)) ||
6970Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &h->lh_pagesize)))
6980Sstevel@tonic-gate 		return (FALSE);
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate 	return (TRUE);
7010Sstevel@tonic-gate }
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate /*
7040Sstevel@tonic-gate  * the routines for logging each transaction follow...
7050Sstevel@tonic-gate  */
7060Sstevel@tonic-gate 
7070Sstevel@tonic-gate void
cachefs_log_mount(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fscache_t * fscp,char * upath,enum uio_seg seg,char * cacheid)7080Sstevel@tonic-gate cachefs_log_mount(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
7090Sstevel@tonic-gate     fscache_t *fscp, char *upath, enum uio_seg seg, char *cacheid)
7100Sstevel@tonic-gate {
7110Sstevel@tonic-gate 	struct cachefs_log_mount_record *record;
7120Sstevel@tonic-gate 	char *cacheidt;
7130Sstevel@tonic-gate 	char *path = NULL;
7140Sstevel@tonic-gate 	size_t len;
7150Sstevel@tonic-gate 	int len1, len2;
7160Sstevel@tonic-gate 	int size, error;
7170Sstevel@tonic-gate 
7180Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
7190Sstevel@tonic-gate 	OUT_IF_TIME_OVERFLOW(cachep, time)
7200Sstevel@tonic-gate 	if (seg == UIO_USERSPACE) {
7210Sstevel@tonic-gate 		path = cachefs_kmem_alloc(MAXPATHLEN, KM_NOSLEEP);
7220Sstevel@tonic-gate 		if (path == NULL) {
7230Sstevel@tonic-gate 			cachefs_log_error(cachep, ENOMEM, 1);
7240Sstevel@tonic-gate 			goto out;
7250Sstevel@tonic-gate 		}
7260Sstevel@tonic-gate 		if ((error = copyinstr(upath, path, MAXPATHLEN, &len)) != 0) {
7270Sstevel@tonic-gate 			cachefs_log_error(cachep, error, 1);
7280Sstevel@tonic-gate 			goto out;
7290Sstevel@tonic-gate 		}
7300Sstevel@tonic-gate 	} else {
7310Sstevel@tonic-gate 		path = upath;
7320Sstevel@tonic-gate 	}
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate 	len1 = (path != NULL) ? strlen(path) : 0;
7350Sstevel@tonic-gate 	len2 = (cacheid != NULL) ? strlen(cacheid) : 0;
7360Sstevel@tonic-gate 	size = (int)sizeof (*record) + len1 + len2 -
7370Sstevel@tonic-gate 	    (int)CLPAD(cachefs_log_mount_record, path);
7380Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(size, KM_NOSLEEP);
7390Sstevel@tonic-gate 	if (record == NULL) {
7400Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
7410Sstevel@tonic-gate 		goto out;
7420Sstevel@tonic-gate 	}
7430Sstevel@tonic-gate 
7440Sstevel@tonic-gate 	record->type = CACHEFS_LOG_MOUNT;
7450Sstevel@tonic-gate 	record->time = time;
7460Sstevel@tonic-gate 
7470Sstevel@tonic-gate 	record->error = Errno;
7480Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
7490Sstevel@tonic-gate 
7500Sstevel@tonic-gate 	if (fscp) {
7510Sstevel@tonic-gate 		record->flags = fscp->fs_info.fi_mntflags;
7520Sstevel@tonic-gate 		record->popsize = fscp->fs_info.fi_popsize;
7530Sstevel@tonic-gate 		record->fgsize = fscp->fs_info.fi_fgsize;
7540Sstevel@tonic-gate 	}
7550Sstevel@tonic-gate 
7560Sstevel@tonic-gate 	record->pathlen = (ushort_t)len1;
7570Sstevel@tonic-gate 	record->cacheidlen = (ushort_t)len2;
7580Sstevel@tonic-gate 	if (path != NULL)
7590Sstevel@tonic-gate 		(void) strcpy(record->path, path);
7600Sstevel@tonic-gate 	cacheidt = record->path + len1 + 1;
7610Sstevel@tonic-gate 	if (cacheid != NULL)
7620Sstevel@tonic-gate 		(void) strcpy(cacheidt, cacheid);
7630Sstevel@tonic-gate 
7640Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, size, cachefs_xdr_mount);
7650Sstevel@tonic-gate 
7660Sstevel@tonic-gate out:
7670Sstevel@tonic-gate 	if ((seg == UIO_USERSPACE) && (path != NULL))
7680Sstevel@tonic-gate 		cachefs_kmem_free(path, MAXPATHLEN);
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate static bool_t
cachefs_xdr_mount(XDR * xdrs,struct cachefs_log_mount_record * rec)7720Sstevel@tonic-gate cachefs_xdr_mount(XDR *xdrs, struct cachefs_log_mount_record *rec)
7730Sstevel@tonic-gate {
7740Sstevel@tonic-gate 	char *path = rec->path;
7750Sstevel@tonic-gate 	char *cacheid;
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 	cacheid = path + strlen(path) + 1;
7780Sstevel@tonic-gate 
7790Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
7800Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
7810Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
7820Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
7830Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->flags)) ||
7840Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->popsize)) ||
7850Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->fgsize)) ||
7860Sstevel@tonic-gate 	    (! xdr_u_short(xdrs, &rec->pathlen)) ||
7870Sstevel@tonic-gate 	    (! xdr_u_short(xdrs, &rec->cacheidlen)) ||
7880Sstevel@tonic-gate 	    (! xdr_wrapstring(xdrs, &path)) ||
7890Sstevel@tonic-gate 	    (! xdr_wrapstring(xdrs, &cacheid)))
7900Sstevel@tonic-gate 		return (FALSE);
7910Sstevel@tonic-gate 
7920Sstevel@tonic-gate 	return (TRUE);
7930Sstevel@tonic-gate }
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate void
cachefs_log_umount(cachefscache_t * cachep,int Errno,struct vfs * vfsp)7960Sstevel@tonic-gate cachefs_log_umount(cachefscache_t *cachep, int Errno, struct vfs *vfsp)
7970Sstevel@tonic-gate {
7980Sstevel@tonic-gate 	struct cachefs_log_umount_record *record;
7990Sstevel@tonic-gate 
8000Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
8010Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
8020Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
8030Sstevel@tonic-gate 	if (record == NULL) {
8040Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
8050Sstevel@tonic-gate 		return;
8060Sstevel@tonic-gate 	}
8070Sstevel@tonic-gate 
8080Sstevel@tonic-gate 	record->type = CACHEFS_LOG_UMOUNT;
8090Sstevel@tonic-gate 	record->time = time;
8100Sstevel@tonic-gate 
8110Sstevel@tonic-gate 	record->error = Errno;
8120Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
8130Sstevel@tonic-gate 
8140Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
8150Sstevel@tonic-gate 	    cachefs_xdr_umount);
8160Sstevel@tonic-gate }
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate static bool_t
cachefs_xdr_umount(XDR * xdrs,struct cachefs_log_umount_record * rec)8190Sstevel@tonic-gate cachefs_xdr_umount(XDR *xdrs, struct cachefs_log_umount_record *rec)
8200Sstevel@tonic-gate {
8210Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
8220Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
8230Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
8240Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))))
8250Sstevel@tonic-gate 		return (FALSE);
8260Sstevel@tonic-gate 
8270Sstevel@tonic-gate 	return (TRUE);
8280Sstevel@tonic-gate }
8290Sstevel@tonic-gate 
8300Sstevel@tonic-gate void
cachefs_log_getpage(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid,u_offset_t offset,size_t len)8310Sstevel@tonic-gate cachefs_log_getpage(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
8320Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, size_t len)
8330Sstevel@tonic-gate {
8340Sstevel@tonic-gate 	struct cachefs_log_getpage_record *record;
8350Sstevel@tonic-gate 
8360Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
8370Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
8380Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
8390Sstevel@tonic-gate 	if (record == NULL) {
8400Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
8410Sstevel@tonic-gate 		return;
8420Sstevel@tonic-gate 	}
8430Sstevel@tonic-gate 
8440Sstevel@tonic-gate 	record->type = CACHEFS_LOG_GETPAGE;
8450Sstevel@tonic-gate 	record->time = time;
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate 	record->error = Errno;
8480Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
8490Sstevel@tonic-gate 	if (fidp != NULL) {
8500Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
8510Sstevel@tonic-gate 	}
8520Sstevel@tonic-gate 	record->fileno = fileno;
8530Sstevel@tonic-gate 	record->uid = uid;
8540Sstevel@tonic-gate 	record->offset = offset;
8550Sstevel@tonic-gate 	record->len = (uint_t)len;
8560Sstevel@tonic-gate 
8570Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
8580Sstevel@tonic-gate 	    cachefs_xdr_getpage);
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate 
8610Sstevel@tonic-gate static bool_t
cachefs_xdr_getpage(XDR * xdrs,struct cachefs_log_getpage_record * rec)8620Sstevel@tonic-gate cachefs_xdr_getpage(XDR *xdrs, struct cachefs_log_getpage_record *rec)
8630Sstevel@tonic-gate {
8640Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
8650Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
8660Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
8670Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
8680Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
8690Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
8704321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)) ||
8710Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, &rec->offset)) ||
8720Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->len)))
8730Sstevel@tonic-gate 		return (FALSE);
8740Sstevel@tonic-gate 
8750Sstevel@tonic-gate 	return (TRUE);
8760Sstevel@tonic-gate }
8770Sstevel@tonic-gate 
8780Sstevel@tonic-gate void
cachefs_log_readdir(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid,u_offset_t offset,int eof)8790Sstevel@tonic-gate cachefs_log_readdir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
8800Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, int eof)
8810Sstevel@tonic-gate {
8820Sstevel@tonic-gate 	struct cachefs_log_readdir_record *record;
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
8850Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
8860Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
8870Sstevel@tonic-gate 	if (record == NULL) {
8880Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
8890Sstevel@tonic-gate 		return;
8900Sstevel@tonic-gate 	}
8910Sstevel@tonic-gate 
8920Sstevel@tonic-gate 	record->type = CACHEFS_LOG_READDIR;
8930Sstevel@tonic-gate 	record->time = time;
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 	record->error = Errno;
8960Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
8970Sstevel@tonic-gate 	if (fidp != NULL) {
8980Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
8990Sstevel@tonic-gate 	}
9000Sstevel@tonic-gate 	record->fileno = fileno;
9010Sstevel@tonic-gate 	record->uid = uid;
9020Sstevel@tonic-gate 	record->offset = offset;
9030Sstevel@tonic-gate 	record->eof = eof;
9040Sstevel@tonic-gate 
9050Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
9060Sstevel@tonic-gate 	    cachefs_xdr_readdir);
9070Sstevel@tonic-gate }
9080Sstevel@tonic-gate 
9090Sstevel@tonic-gate static bool_t
cachefs_xdr_readdir(XDR * xdrs,struct cachefs_log_readdir_record * rec)9100Sstevel@tonic-gate cachefs_xdr_readdir(XDR *xdrs, struct cachefs_log_readdir_record *rec)
9110Sstevel@tonic-gate {
9120Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
9130Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
9140Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
9150Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
9160Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
9170Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
9184321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)) ||
9190Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->offset)) ||
9200Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->eof)))
9210Sstevel@tonic-gate 		return (FALSE);
9220Sstevel@tonic-gate 
9230Sstevel@tonic-gate 	return (TRUE);
9240Sstevel@tonic-gate }
9250Sstevel@tonic-gate 
9260Sstevel@tonic-gate void
cachefs_log_readlink(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid,size_t length)9270Sstevel@tonic-gate cachefs_log_readlink(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
9280Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid, size_t length)
9290Sstevel@tonic-gate {
9300Sstevel@tonic-gate 	struct cachefs_log_readlink_record *record;
9310Sstevel@tonic-gate 
9320Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
9330Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
9340Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
9350Sstevel@tonic-gate 	if (record == NULL) {
9360Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
9370Sstevel@tonic-gate 		return;
9380Sstevel@tonic-gate 	}
9390Sstevel@tonic-gate 
9400Sstevel@tonic-gate 	record->type = CACHEFS_LOG_READLINK;
9410Sstevel@tonic-gate 	record->time = time;
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 	record->error = Errno;
9440Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
9450Sstevel@tonic-gate 	if (fidp != NULL) {
9460Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
9470Sstevel@tonic-gate 	}
9480Sstevel@tonic-gate 	record->fileno = fileno;
9490Sstevel@tonic-gate 	record->uid = uid;
9500Sstevel@tonic-gate 	record->length = (uint_t)length;
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
9530Sstevel@tonic-gate 	    cachefs_xdr_readlink);
9540Sstevel@tonic-gate }
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate static bool_t
cachefs_xdr_readlink(XDR * xdrs,struct cachefs_log_readlink_record * rec)9570Sstevel@tonic-gate cachefs_xdr_readlink(XDR *xdrs, struct cachefs_log_readlink_record *rec)
9580Sstevel@tonic-gate {
9590Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
9600Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
9610Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
9620Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
9630Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
9640Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
9654321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)) ||
9660Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->length)))
9670Sstevel@tonic-gate 		return (FALSE);
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate 	return (TRUE);
9700Sstevel@tonic-gate }
9710Sstevel@tonic-gate 
9720Sstevel@tonic-gate void
cachefs_log_remove(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid)9730Sstevel@tonic-gate cachefs_log_remove(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
9740Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid)
9750Sstevel@tonic-gate {
9760Sstevel@tonic-gate 	struct cachefs_log_remove_record *record;
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
9790Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
9800Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
9810Sstevel@tonic-gate 	if (record == NULL) {
9820Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
9830Sstevel@tonic-gate 		return;
9840Sstevel@tonic-gate 	}
9850Sstevel@tonic-gate 
9860Sstevel@tonic-gate 	record->type = CACHEFS_LOG_REMOVE;
9870Sstevel@tonic-gate 	record->time = time;
9880Sstevel@tonic-gate 
9890Sstevel@tonic-gate 	record->error = Errno;
9900Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
9910Sstevel@tonic-gate 	if (fidp != NULL) {
9920Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
9930Sstevel@tonic-gate 	}
9940Sstevel@tonic-gate 	record->fileno = fileno;
9950Sstevel@tonic-gate 	record->uid = uid;
9960Sstevel@tonic-gate 
9970Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
9980Sstevel@tonic-gate 	    cachefs_xdr_remove);
9990Sstevel@tonic-gate }
10000Sstevel@tonic-gate 
10010Sstevel@tonic-gate static bool_t
cachefs_xdr_remove(XDR * xdrs,struct cachefs_log_remove_record * rec)10020Sstevel@tonic-gate cachefs_xdr_remove(XDR *xdrs, struct cachefs_log_remove_record *rec)
10030Sstevel@tonic-gate {
10040Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
10050Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
10060Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
10070Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
10080Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
10090Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
10104321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)))
10110Sstevel@tonic-gate 		return (FALSE);
10120Sstevel@tonic-gate 
10130Sstevel@tonic-gate 	return (TRUE);
10140Sstevel@tonic-gate }
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate void
cachefs_log_rmdir(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid)10170Sstevel@tonic-gate cachefs_log_rmdir(cachefscache_t *cachep, int Errno,
10180Sstevel@tonic-gate     struct vfs *vfsp, fid_t *fidp, ino64_t fileno, uid_t uid)
10190Sstevel@tonic-gate {
10200Sstevel@tonic-gate 	struct cachefs_log_rmdir_record *record;
10210Sstevel@tonic-gate 
10220Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
10230Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
10240Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
10250Sstevel@tonic-gate 	if (record == NULL) {
10260Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
10270Sstevel@tonic-gate 		return;
10280Sstevel@tonic-gate 	}
10290Sstevel@tonic-gate 
10300Sstevel@tonic-gate 	record->type = CACHEFS_LOG_RMDIR;
10310Sstevel@tonic-gate 	record->time = time;
10320Sstevel@tonic-gate 
10330Sstevel@tonic-gate 	record->error = Errno;
10340Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
10350Sstevel@tonic-gate 	if (fidp != NULL) {
10360Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
10370Sstevel@tonic-gate 	}
10380Sstevel@tonic-gate 	record->fileno = fileno;
10390Sstevel@tonic-gate 	record->uid = uid;
10400Sstevel@tonic-gate 
10410Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
10420Sstevel@tonic-gate 	    cachefs_xdr_rmdir);
10430Sstevel@tonic-gate }
10440Sstevel@tonic-gate 
10450Sstevel@tonic-gate static bool_t
cachefs_xdr_rmdir(XDR * xdrs,struct cachefs_log_rmdir_record * rec)10460Sstevel@tonic-gate cachefs_xdr_rmdir(XDR *xdrs, struct cachefs_log_rmdir_record *rec)
10470Sstevel@tonic-gate {
10480Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
10490Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
10500Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
10510Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
10520Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
10530Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
10544321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)))
10550Sstevel@tonic-gate 		return (FALSE);
10560Sstevel@tonic-gate 
10570Sstevel@tonic-gate 	return (TRUE);
10580Sstevel@tonic-gate }
10590Sstevel@tonic-gate 
10600Sstevel@tonic-gate void
cachefs_log_truncate(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid,u_offset_t size)10610Sstevel@tonic-gate cachefs_log_truncate(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
10620Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t size)
10630Sstevel@tonic-gate {
10640Sstevel@tonic-gate 	struct cachefs_log_truncate_record *record;
10650Sstevel@tonic-gate 
10660Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
10670Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
10680Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
10690Sstevel@tonic-gate 	if (record == NULL) {
10700Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
10710Sstevel@tonic-gate 		return;
10720Sstevel@tonic-gate 	}
10730Sstevel@tonic-gate 
10740Sstevel@tonic-gate 	record->type = CACHEFS_LOG_TRUNCATE;
10750Sstevel@tonic-gate 	record->time = time;
10760Sstevel@tonic-gate 
10770Sstevel@tonic-gate 	record->error = Errno;
10780Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
10790Sstevel@tonic-gate 	if (fidp != NULL) {
10800Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
10810Sstevel@tonic-gate 	}
10820Sstevel@tonic-gate 	record->fileno = fileno;
10830Sstevel@tonic-gate 	record->uid = uid;
10840Sstevel@tonic-gate 	record->size = size;
10850Sstevel@tonic-gate 
10860Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
10870Sstevel@tonic-gate 	    cachefs_xdr_truncate);
10880Sstevel@tonic-gate }
10890Sstevel@tonic-gate 
10900Sstevel@tonic-gate static bool_t
cachefs_xdr_truncate(XDR * xdrs,struct cachefs_log_truncate_record * rec)10910Sstevel@tonic-gate cachefs_xdr_truncate(XDR *xdrs, struct cachefs_log_truncate_record *rec)
10920Sstevel@tonic-gate {
10930Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
10940Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
10950Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
10960Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
10970Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
10980Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
10994321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)) ||
11000Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, &rec->size)))
11010Sstevel@tonic-gate 		return (FALSE);
11020Sstevel@tonic-gate 
11030Sstevel@tonic-gate 	return (TRUE);
11040Sstevel@tonic-gate }
11050Sstevel@tonic-gate 
11060Sstevel@tonic-gate void
cachefs_log_putpage(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid,u_offset_t offset,size_t len)11070Sstevel@tonic-gate cachefs_log_putpage(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
11080Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, size_t len)
11090Sstevel@tonic-gate {
11100Sstevel@tonic-gate 	struct cachefs_log_putpage_record *record;
11110Sstevel@tonic-gate 
11120Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
11130Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
11140Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
11150Sstevel@tonic-gate 	if (record == NULL) {
11160Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
11170Sstevel@tonic-gate 		return;
11180Sstevel@tonic-gate 	}
11190Sstevel@tonic-gate 
11200Sstevel@tonic-gate 	record->type = CACHEFS_LOG_PUTPAGE;
11210Sstevel@tonic-gate 	record->time = time;
11220Sstevel@tonic-gate 
11230Sstevel@tonic-gate 	record->error = Errno;
11240Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
11250Sstevel@tonic-gate 	if (fidp != NULL) {
11260Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
11270Sstevel@tonic-gate 	}
11280Sstevel@tonic-gate 	record->fileno = fileno;
11290Sstevel@tonic-gate 	record->uid = uid;
11300Sstevel@tonic-gate 	record->offset = offset;
11310Sstevel@tonic-gate 	record->len = (uint_t)len;
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
11340Sstevel@tonic-gate 	    cachefs_xdr_putpage);
11350Sstevel@tonic-gate }
11360Sstevel@tonic-gate 
11370Sstevel@tonic-gate static bool_t
cachefs_xdr_putpage(XDR * xdrs,struct cachefs_log_putpage_record * rec)11380Sstevel@tonic-gate cachefs_xdr_putpage(XDR *xdrs, struct cachefs_log_putpage_record *rec)
11390Sstevel@tonic-gate {
11400Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
11410Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
11420Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
11430Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
11440Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
11450Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
11464321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)) ||
11470Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->offset)) ||
11480Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->len)))
11490Sstevel@tonic-gate 		return (FALSE);
11500Sstevel@tonic-gate 
11510Sstevel@tonic-gate 	return (TRUE);
11520Sstevel@tonic-gate }
11530Sstevel@tonic-gate 
11540Sstevel@tonic-gate void
cachefs_log_create(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * filefidp,ino64_t fileno,uid_t uid)11550Sstevel@tonic-gate cachefs_log_create(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
11560Sstevel@tonic-gate     fid_t *filefidp, ino64_t fileno, uid_t uid)
11570Sstevel@tonic-gate {
11580Sstevel@tonic-gate 	struct cachefs_log_create_record *record;
11590Sstevel@tonic-gate 
11600Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
11610Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
11620Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
11630Sstevel@tonic-gate 	if (record == NULL) {
11640Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
11650Sstevel@tonic-gate 		return;
11660Sstevel@tonic-gate 	}
11670Sstevel@tonic-gate 
11680Sstevel@tonic-gate 	record->type = CACHEFS_LOG_CREATE;
11690Sstevel@tonic-gate 	record->time = time;
11700Sstevel@tonic-gate 
11710Sstevel@tonic-gate 	record->error = Errno;
11720Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
11730Sstevel@tonic-gate 	if (filefidp != NULL) {
11740Sstevel@tonic-gate 		CACHEFS_FID_COPY(filefidp, &record->fid);
11750Sstevel@tonic-gate 	}
11760Sstevel@tonic-gate 	record->fileno = fileno;
11770Sstevel@tonic-gate 	record->uid = uid;
11780Sstevel@tonic-gate 
11790Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
11800Sstevel@tonic-gate 	    cachefs_xdr_create);
11810Sstevel@tonic-gate }
11820Sstevel@tonic-gate 
11830Sstevel@tonic-gate static bool_t
cachefs_xdr_create(XDR * xdrs,struct cachefs_log_create_record * rec)11840Sstevel@tonic-gate cachefs_xdr_create(XDR *xdrs, struct cachefs_log_create_record *rec)
11850Sstevel@tonic-gate {
11860Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
11870Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
11880Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
11890Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
11900Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
11910Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
11924321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)))
11930Sstevel@tonic-gate 		return (FALSE);
11940Sstevel@tonic-gate 
11950Sstevel@tonic-gate 	return (TRUE);
11960Sstevel@tonic-gate }
11970Sstevel@tonic-gate 
11980Sstevel@tonic-gate void
cachefs_log_mkdir(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * cfidp,ino64_t fileno,uid_t uid)11990Sstevel@tonic-gate cachefs_log_mkdir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
12000Sstevel@tonic-gate     fid_t *cfidp, ino64_t fileno, uid_t uid)
12010Sstevel@tonic-gate {
12020Sstevel@tonic-gate 	struct cachefs_log_mkdir_record *record;
12030Sstevel@tonic-gate 	int size;
12040Sstevel@tonic-gate 
12050Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
12060Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
12070Sstevel@tonic-gate 	size = (int)sizeof (*record);
12080Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(size, KM_NOSLEEP);
12090Sstevel@tonic-gate 	if (record == NULL) {
12100Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
12110Sstevel@tonic-gate 		return;
12120Sstevel@tonic-gate 	}
12130Sstevel@tonic-gate 
12140Sstevel@tonic-gate 	record->type = CACHEFS_LOG_MKDIR;
12150Sstevel@tonic-gate 	record->time = time;
12160Sstevel@tonic-gate 
12170Sstevel@tonic-gate 	record->error = Errno;
12180Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
12190Sstevel@tonic-gate 	if (cfidp != NULL) {
12200Sstevel@tonic-gate 		CACHEFS_FID_COPY(cfidp, &record->fid);
12210Sstevel@tonic-gate 	}
12220Sstevel@tonic-gate 	record->fileno = fileno;
12230Sstevel@tonic-gate 	record->uid = uid;
12240Sstevel@tonic-gate 
12250Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, size,
12260Sstevel@tonic-gate 	    cachefs_xdr_mkdir);
12270Sstevel@tonic-gate }
12280Sstevel@tonic-gate 
12290Sstevel@tonic-gate static bool_t
cachefs_xdr_mkdir(XDR * xdrs,struct cachefs_log_mkdir_record * rec)12300Sstevel@tonic-gate cachefs_xdr_mkdir(XDR *xdrs, struct cachefs_log_mkdir_record *rec)
12310Sstevel@tonic-gate {
12320Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
12330Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
12340Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
12350Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
12360Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
12370Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
12384321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)))
12390Sstevel@tonic-gate 		return (FALSE);
12400Sstevel@tonic-gate 
12410Sstevel@tonic-gate 	return (TRUE);
12420Sstevel@tonic-gate }
12430Sstevel@tonic-gate 
12440Sstevel@tonic-gate void
cachefs_log_rename(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * gfp,ino64_t fileno,int removed,uid_t uid)12450Sstevel@tonic-gate cachefs_log_rename(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
12460Sstevel@tonic-gate     fid_t *gfp, ino64_t fileno, int removed, uid_t uid)
12470Sstevel@tonic-gate {
12480Sstevel@tonic-gate 	struct cachefs_log_rename_record *record;
12490Sstevel@tonic-gate 
12500Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
12510Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
12520Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
12530Sstevel@tonic-gate 	if (record == NULL) {
12540Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
12550Sstevel@tonic-gate 		return;
12560Sstevel@tonic-gate 	}
12570Sstevel@tonic-gate 
12580Sstevel@tonic-gate 	record->type = CACHEFS_LOG_RENAME;
12590Sstevel@tonic-gate 	record->time = time;
12600Sstevel@tonic-gate 
12610Sstevel@tonic-gate 	record->error = Errno;
12620Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
12630Sstevel@tonic-gate 	if (gfp != NULL) {
12640Sstevel@tonic-gate 		CACHEFS_FID_COPY(gfp, &record->gone);
12650Sstevel@tonic-gate 	}
12660Sstevel@tonic-gate 	record->fileno = fileno;
12670Sstevel@tonic-gate 	record->removed = removed;
12680Sstevel@tonic-gate 	record->uid = uid;
12690Sstevel@tonic-gate 
12700Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
12710Sstevel@tonic-gate 	    cachefs_xdr_rename);
12720Sstevel@tonic-gate }
12730Sstevel@tonic-gate 
12740Sstevel@tonic-gate static bool_t
cachefs_xdr_rename(XDR * xdrs,struct cachefs_log_rename_record * rec)12750Sstevel@tonic-gate cachefs_xdr_rename(XDR *xdrs, struct cachefs_log_rename_record *rec)
12760Sstevel@tonic-gate {
12770Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
12780Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
12790Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
12800Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
12810Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->gone, sizeof (rec->gone))) ||
12820Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->removed)) ||
12834321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)))
12840Sstevel@tonic-gate 		return (FALSE);
12850Sstevel@tonic-gate 
12860Sstevel@tonic-gate 	return (TRUE);
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate 
12890Sstevel@tonic-gate 
12900Sstevel@tonic-gate void
cachefs_log_symlink(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid,int size)12910Sstevel@tonic-gate cachefs_log_symlink(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
12920Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid, int size)
12930Sstevel@tonic-gate {
12940Sstevel@tonic-gate 	struct cachefs_log_symlink_record *record;
12950Sstevel@tonic-gate 
12960Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
12970Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
12980Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
12990Sstevel@tonic-gate 	if (record == NULL) {
13000Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
13010Sstevel@tonic-gate 		return;
13020Sstevel@tonic-gate 	}
13030Sstevel@tonic-gate 
13040Sstevel@tonic-gate 	record->type = CACHEFS_LOG_SYMLINK;
13050Sstevel@tonic-gate 	record->time = time;
13060Sstevel@tonic-gate 
13070Sstevel@tonic-gate 	record->error = Errno;
13080Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
13090Sstevel@tonic-gate 	if (fidp != NULL) {
13100Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
13110Sstevel@tonic-gate 	}
13120Sstevel@tonic-gate 	record->fileno = fileno;
13130Sstevel@tonic-gate 	record->uid = uid;
13140Sstevel@tonic-gate 	record->size = size;
13150Sstevel@tonic-gate 
13160Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
13170Sstevel@tonic-gate 	    cachefs_xdr_symlink);
13180Sstevel@tonic-gate }
13190Sstevel@tonic-gate 
13200Sstevel@tonic-gate static bool_t
cachefs_xdr_symlink(XDR * xdrs,struct cachefs_log_symlink_record * rec)13210Sstevel@tonic-gate cachefs_xdr_symlink(XDR *xdrs, struct cachefs_log_symlink_record *rec)
13220Sstevel@tonic-gate {
13230Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
13240Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
13250Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
13260Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
13270Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
13280Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
13294321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)) ||
13300Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->size)))
13310Sstevel@tonic-gate 		return (FALSE);
13320Sstevel@tonic-gate 
13330Sstevel@tonic-gate 	return (TRUE);
13340Sstevel@tonic-gate }
13350Sstevel@tonic-gate 
13360Sstevel@tonic-gate void
cachefs_log_populate(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,u_offset_t off,size_t popsize)13370Sstevel@tonic-gate cachefs_log_populate(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
13380Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, u_offset_t off, size_t popsize)
13390Sstevel@tonic-gate {
13400Sstevel@tonic-gate 	struct cachefs_log_populate_record *record;
13410Sstevel@tonic-gate 
13420Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
13430Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
13440Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
13450Sstevel@tonic-gate 	if (record == NULL) {
13460Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
13470Sstevel@tonic-gate 		return;
13480Sstevel@tonic-gate 	}
13490Sstevel@tonic-gate 
13500Sstevel@tonic-gate 	record->type = CACHEFS_LOG_POPULATE;
13510Sstevel@tonic-gate 	record->time = time;
13520Sstevel@tonic-gate 	record->error = Errno;
13530Sstevel@tonic-gate 
13540Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
13550Sstevel@tonic-gate 	if (fidp != NULL) {
13560Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
13570Sstevel@tonic-gate 	}
13580Sstevel@tonic-gate 	record->fileno = fileno;
13590Sstevel@tonic-gate 	record->off = off;
13600Sstevel@tonic-gate 	record->size = (int)popsize;
13610Sstevel@tonic-gate 
13620Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
13630Sstevel@tonic-gate 	    cachefs_xdr_populate);
13640Sstevel@tonic-gate }
13650Sstevel@tonic-gate 
13660Sstevel@tonic-gate static bool_t
cachefs_xdr_populate(XDR * xdrs,struct cachefs_log_populate_record * rec)13670Sstevel@tonic-gate cachefs_xdr_populate(XDR *xdrs, struct cachefs_log_populate_record *rec)
13680Sstevel@tonic-gate {
13690Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
13700Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
13710Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
13720Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
13730Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
13740Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
13750Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
13760Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->size)))
13770Sstevel@tonic-gate 		return (FALSE);
13780Sstevel@tonic-gate 
13790Sstevel@tonic-gate 	return (TRUE);
13800Sstevel@tonic-gate }
13810Sstevel@tonic-gate 
13820Sstevel@tonic-gate void
cachefs_log_csymlink(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,int size)13830Sstevel@tonic-gate cachefs_log_csymlink(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
13840Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, int size)
13850Sstevel@tonic-gate {
13860Sstevel@tonic-gate 	struct cachefs_log_csymlink_record *record;
13870Sstevel@tonic-gate 
13880Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
13890Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
13900Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
13910Sstevel@tonic-gate 	if (record == NULL) {
13920Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
13930Sstevel@tonic-gate 		return;
13940Sstevel@tonic-gate 	}
13950Sstevel@tonic-gate 
13960Sstevel@tonic-gate 	record->type = CACHEFS_LOG_CSYMLINK;
13970Sstevel@tonic-gate 	record->time = time;
13980Sstevel@tonic-gate 	record->error = Errno;
13990Sstevel@tonic-gate 
14000Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
14010Sstevel@tonic-gate 	if (fidp != NULL) {
14020Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
14030Sstevel@tonic-gate 	}
14040Sstevel@tonic-gate 	record->fileno = fileno;
14050Sstevel@tonic-gate 	record->size = size;
14060Sstevel@tonic-gate 
14070Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
14080Sstevel@tonic-gate 	    cachefs_xdr_csymlink);
14090Sstevel@tonic-gate }
14100Sstevel@tonic-gate 
14110Sstevel@tonic-gate static bool_t
cachefs_xdr_csymlink(XDR * xdrs,struct cachefs_log_csymlink_record * rec)14120Sstevel@tonic-gate cachefs_xdr_csymlink(XDR *xdrs, struct cachefs_log_csymlink_record *rec)
14130Sstevel@tonic-gate {
14140Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
14150Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
14160Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
14170Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
14180Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
14190Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
14200Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->size)))
14210Sstevel@tonic-gate 		return (FALSE);
14220Sstevel@tonic-gate 
14230Sstevel@tonic-gate 	return (TRUE);
14240Sstevel@tonic-gate }
14250Sstevel@tonic-gate 
14260Sstevel@tonic-gate void
cachefs_log_filldir(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,u_offset_t size)14270Sstevel@tonic-gate cachefs_log_filldir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
14280Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, u_offset_t size)
14290Sstevel@tonic-gate {
14300Sstevel@tonic-gate 	struct cachefs_log_filldir_record *record;
14310Sstevel@tonic-gate 
14320Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
14330Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
14340Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
14350Sstevel@tonic-gate 	if (record == NULL) {
14360Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
14370Sstevel@tonic-gate 		return;
14380Sstevel@tonic-gate 	}
14390Sstevel@tonic-gate 
14400Sstevel@tonic-gate 	record->type = CACHEFS_LOG_FILLDIR;
14410Sstevel@tonic-gate 	record->time = time;
14420Sstevel@tonic-gate 	record->error = Errno;
14430Sstevel@tonic-gate 
14440Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
14450Sstevel@tonic-gate 	if (fidp != NULL) {
14460Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
14470Sstevel@tonic-gate 	}
14480Sstevel@tonic-gate 	record->fileno = fileno;
14490Sstevel@tonic-gate 	record->size = (uint_t)size;
14500Sstevel@tonic-gate 
14510Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
14520Sstevel@tonic-gate 	    cachefs_xdr_filldir);
14530Sstevel@tonic-gate }
14540Sstevel@tonic-gate 
14550Sstevel@tonic-gate static bool_t
cachefs_xdr_filldir(XDR * xdrs,struct cachefs_log_filldir_record * rec)14560Sstevel@tonic-gate cachefs_xdr_filldir(XDR *xdrs, struct cachefs_log_filldir_record *rec)
14570Sstevel@tonic-gate {
14580Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
14590Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
14600Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
14610Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
14620Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
14630Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
14640Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, (uint_t *)&rec->size)))
14650Sstevel@tonic-gate 		return (FALSE);
14660Sstevel@tonic-gate 
14670Sstevel@tonic-gate 	return (TRUE);
14680Sstevel@tonic-gate }
14690Sstevel@tonic-gate 
14700Sstevel@tonic-gate void
cachefs_log_mdcreate(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uint_t count)14710Sstevel@tonic-gate cachefs_log_mdcreate(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
14720Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uint_t count)
14730Sstevel@tonic-gate {
14740Sstevel@tonic-gate 	struct cachefs_log_mdcreate_record *record;
14750Sstevel@tonic-gate 
14760Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
14770Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
14780Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
14790Sstevel@tonic-gate 	if (record == NULL) {
14800Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
14810Sstevel@tonic-gate 		return;
14820Sstevel@tonic-gate 	}
14830Sstevel@tonic-gate 
14840Sstevel@tonic-gate 	record->type = CACHEFS_LOG_MDCREATE;
14850Sstevel@tonic-gate 	record->time = time;
14860Sstevel@tonic-gate 	record->error = Errno;
14870Sstevel@tonic-gate 
14880Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
14890Sstevel@tonic-gate 	if (fidp != NULL) {
14900Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
14910Sstevel@tonic-gate 	}
14920Sstevel@tonic-gate 	record->fileno = fileno;
14930Sstevel@tonic-gate 	record->count = count;
14940Sstevel@tonic-gate 
14950Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
14960Sstevel@tonic-gate 	    cachefs_xdr_mdcreate);
14970Sstevel@tonic-gate }
14980Sstevel@tonic-gate 
14990Sstevel@tonic-gate static bool_t
cachefs_xdr_mdcreate(XDR * xdrs,struct cachefs_log_mdcreate_record * rec)15000Sstevel@tonic-gate cachefs_xdr_mdcreate(XDR *xdrs, struct cachefs_log_mdcreate_record *rec)
15010Sstevel@tonic-gate {
15020Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
15030Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
15040Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
15050Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
15060Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
15070Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
15080Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->count)))
15090Sstevel@tonic-gate 		return (FALSE);
15100Sstevel@tonic-gate 
15110Sstevel@tonic-gate 	return (TRUE);
15120Sstevel@tonic-gate }
15130Sstevel@tonic-gate 
15140Sstevel@tonic-gate void
cachefs_log_gpfront(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid,u_offset_t offset,uint_t len)15150Sstevel@tonic-gate cachefs_log_gpfront(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
15160Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid, u_offset_t offset, uint_t len)
15170Sstevel@tonic-gate {
15180Sstevel@tonic-gate 	struct cachefs_log_gpfront_record *record;
15190Sstevel@tonic-gate 
15200Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
15210Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
15220Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
15230Sstevel@tonic-gate 	if (record == NULL) {
15240Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
15250Sstevel@tonic-gate 		return;
15260Sstevel@tonic-gate 	}
15270Sstevel@tonic-gate 
15280Sstevel@tonic-gate 	record->type = CACHEFS_LOG_GPFRONT;
15290Sstevel@tonic-gate 	record->time = time;
15300Sstevel@tonic-gate 	record->error = Errno;
15310Sstevel@tonic-gate 
15320Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
15330Sstevel@tonic-gate 	if (fidp != NULL) {
15340Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
15350Sstevel@tonic-gate 	}
15360Sstevel@tonic-gate 	record->fileno = fileno;
15370Sstevel@tonic-gate 	record->uid = uid;
15380Sstevel@tonic-gate 	record->off = offset;
15390Sstevel@tonic-gate 	record->len = len;
15400Sstevel@tonic-gate 
15410Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
15420Sstevel@tonic-gate 	    cachefs_xdr_gpfront);
15430Sstevel@tonic-gate }
15440Sstevel@tonic-gate 
15450Sstevel@tonic-gate static bool_t
cachefs_xdr_gpfront(XDR * xdrs,struct cachefs_log_gpfront_record * rec)15460Sstevel@tonic-gate cachefs_xdr_gpfront(XDR *xdrs, struct cachefs_log_gpfront_record *rec)
15470Sstevel@tonic-gate {
15480Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
15490Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
15500Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
15510Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
15520Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
15530Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
15544321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)) ||
15550Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
15560Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->len)))
15570Sstevel@tonic-gate 		return (FALSE);
15580Sstevel@tonic-gate 
15590Sstevel@tonic-gate 	return (TRUE);
15600Sstevel@tonic-gate }
15610Sstevel@tonic-gate 
15620Sstevel@tonic-gate void
cachefs_log_rfdir(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,uid_t uid)15630Sstevel@tonic-gate cachefs_log_rfdir(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
15640Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, uid_t uid)
15650Sstevel@tonic-gate {
15660Sstevel@tonic-gate 	struct cachefs_log_rfdir_record *record;
15670Sstevel@tonic-gate 
15680Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
15690Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
15700Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
15710Sstevel@tonic-gate 	if (record == NULL) {
15720Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
15730Sstevel@tonic-gate 		return;
15740Sstevel@tonic-gate 	}
15750Sstevel@tonic-gate 
15760Sstevel@tonic-gate 	record->type = CACHEFS_LOG_RFDIR;
15770Sstevel@tonic-gate 	record->time = time;
15780Sstevel@tonic-gate 	record->error = Errno;
15790Sstevel@tonic-gate 
15800Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
15810Sstevel@tonic-gate 	if (fidp != NULL) {
15820Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
15830Sstevel@tonic-gate 	}
15840Sstevel@tonic-gate 	record->fileno = fileno;
15850Sstevel@tonic-gate 	record->uid = uid;
15860Sstevel@tonic-gate 
15870Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
15880Sstevel@tonic-gate 	    cachefs_xdr_rfdir);
15890Sstevel@tonic-gate }
15900Sstevel@tonic-gate 
15910Sstevel@tonic-gate static bool_t
cachefs_xdr_rfdir(XDR * xdrs,struct cachefs_log_rfdir_record * rec)15920Sstevel@tonic-gate cachefs_xdr_rfdir(XDR *xdrs, struct cachefs_log_rfdir_record *rec)
15930Sstevel@tonic-gate {
15940Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
15950Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
15960Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
15970Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
15980Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
15990Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
16004321Scasper 	    (! xdr_u_int(xdrs, &rec->uid)))
16010Sstevel@tonic-gate 		return (FALSE);
16020Sstevel@tonic-gate 
16030Sstevel@tonic-gate 	return (TRUE);
16040Sstevel@tonic-gate }
16050Sstevel@tonic-gate 
16060Sstevel@tonic-gate void
cachefs_log_ualloc(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,u_offset_t off,size_t len)16070Sstevel@tonic-gate cachefs_log_ualloc(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
16080Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, u_offset_t off, size_t len)
16090Sstevel@tonic-gate {
16100Sstevel@tonic-gate 	struct cachefs_log_ualloc_record *record;
16110Sstevel@tonic-gate 
16120Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
16130Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
16140Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
16150Sstevel@tonic-gate 	if (record == NULL) {
16160Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
16170Sstevel@tonic-gate 		return;
16180Sstevel@tonic-gate 	}
16190Sstevel@tonic-gate 
16200Sstevel@tonic-gate 	record->type = CACHEFS_LOG_UALLOC;
16210Sstevel@tonic-gate 	record->time = time;
16220Sstevel@tonic-gate 	record->error = Errno;
16230Sstevel@tonic-gate 
16240Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
16250Sstevel@tonic-gate 	if (fidp != NULL) {
16260Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
16270Sstevel@tonic-gate 	}
16280Sstevel@tonic-gate 	record->fileno = fileno;
16290Sstevel@tonic-gate 	record->off = off;
16300Sstevel@tonic-gate 	record->len = (uint_t)len;
16310Sstevel@tonic-gate 
16320Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
16330Sstevel@tonic-gate 	    cachefs_xdr_ualloc);
16340Sstevel@tonic-gate }
16350Sstevel@tonic-gate 
16360Sstevel@tonic-gate static bool_t
cachefs_xdr_ualloc(XDR * xdrs,struct cachefs_log_ualloc_record * rec)16370Sstevel@tonic-gate cachefs_xdr_ualloc(XDR *xdrs, struct cachefs_log_ualloc_record *rec)
16380Sstevel@tonic-gate {
16390Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
16400Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
16410Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
16420Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
16430Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
16440Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
16450Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
16460Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, (uint_t *)&rec->len)))
16470Sstevel@tonic-gate 		return (FALSE);
16480Sstevel@tonic-gate 
16490Sstevel@tonic-gate 	return (TRUE);
16500Sstevel@tonic-gate }
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate void
cachefs_log_calloc(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno,u_offset_t off,size_t len)16530Sstevel@tonic-gate cachefs_log_calloc(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
16540Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno, u_offset_t off, size_t len)
16550Sstevel@tonic-gate {
16560Sstevel@tonic-gate 	struct cachefs_log_calloc_record *record;
16570Sstevel@tonic-gate 
16580Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
16590Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
16600Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
16610Sstevel@tonic-gate 	if (record == NULL) {
16620Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
16630Sstevel@tonic-gate 		return;
16640Sstevel@tonic-gate 	}
16650Sstevel@tonic-gate 
16660Sstevel@tonic-gate 	record->type = CACHEFS_LOG_CALLOC;
16670Sstevel@tonic-gate 	record->time = time;
16680Sstevel@tonic-gate 	record->error = Errno;
16690Sstevel@tonic-gate 
16700Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
16710Sstevel@tonic-gate 	if (fidp != NULL) {
16720Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
16730Sstevel@tonic-gate 	}
16740Sstevel@tonic-gate 	record->fileno = fileno;
16750Sstevel@tonic-gate 	record->off = off;
16760Sstevel@tonic-gate 	record->len = (uint_t)len;
16770Sstevel@tonic-gate 
16780Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
16790Sstevel@tonic-gate 	    cachefs_xdr_calloc);
16800Sstevel@tonic-gate }
16810Sstevel@tonic-gate 
16820Sstevel@tonic-gate static bool_t
cachefs_xdr_calloc(XDR * xdrs,struct cachefs_log_calloc_record * rec)16830Sstevel@tonic-gate cachefs_xdr_calloc(XDR *xdrs, struct cachefs_log_calloc_record *rec)
16840Sstevel@tonic-gate {
16850Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
16860Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
16870Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
16880Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
16890Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
16900Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)) ||
16910Sstevel@tonic-gate 	    (! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
16920Sstevel@tonic-gate 	    (! xdr_u_int(xdrs, &rec->len)))
16930Sstevel@tonic-gate 		return (FALSE);
16940Sstevel@tonic-gate 
16950Sstevel@tonic-gate 	return (TRUE);
16960Sstevel@tonic-gate }
16970Sstevel@tonic-gate 
16980Sstevel@tonic-gate void
cachefs_log_nocache(cachefscache_t * cachep,int Errno,struct vfs * vfsp,fid_t * fidp,ino64_t fileno)16990Sstevel@tonic-gate cachefs_log_nocache(cachefscache_t *cachep, int Errno, struct vfs *vfsp,
17000Sstevel@tonic-gate     fid_t *fidp, ino64_t fileno)
17010Sstevel@tonic-gate {
17020Sstevel@tonic-gate 	struct cachefs_log_nocache_record *record;
17030Sstevel@tonic-gate 
17040Sstevel@tonic-gate 	/* In Solaris 64 - if can't represent time don't bother */
17050Sstevel@tonic-gate 	RET_IF_TIME_OVERFLOW(cachep, time)
17060Sstevel@tonic-gate 	record = cachefs_kmem_zalloc(sizeof (*record), KM_NOSLEEP);
17070Sstevel@tonic-gate 	if (record == NULL) {
17080Sstevel@tonic-gate 		cachefs_log_error(cachep, ENOMEM, 1);
17090Sstevel@tonic-gate 		return;
17100Sstevel@tonic-gate 	}
17110Sstevel@tonic-gate 
17120Sstevel@tonic-gate 	record->type = CACHEFS_LOG_NOCACHE;
17130Sstevel@tonic-gate 	record->time = time;
17140Sstevel@tonic-gate 	record->error = Errno;
17150Sstevel@tonic-gate 
17160Sstevel@tonic-gate 	record->vfsp = (uint64_t)(uintptr_t)vfsp;
17170Sstevel@tonic-gate 	if (fidp != NULL) {
17180Sstevel@tonic-gate 		CACHEFS_FID_COPY(fidp, &record->fid);
17190Sstevel@tonic-gate 	}
17200Sstevel@tonic-gate 	record->fileno = fileno;
17210Sstevel@tonic-gate 
17220Sstevel@tonic-gate 	cachefs_log_enqueue(cachep, record, (int)sizeof (*record),
17230Sstevel@tonic-gate 	    cachefs_xdr_nocache);
17240Sstevel@tonic-gate 
17250Sstevel@tonic-gate }
17260Sstevel@tonic-gate 
17270Sstevel@tonic-gate static bool_t
cachefs_xdr_nocache(XDR * xdrs,struct cachefs_log_nocache_record * rec)17280Sstevel@tonic-gate cachefs_xdr_nocache(XDR *xdrs, struct cachefs_log_nocache_record *rec)
17290Sstevel@tonic-gate {
17300Sstevel@tonic-gate 	if ((! xdr_int(xdrs, &rec->type)) ||
17310Sstevel@tonic-gate 	    (! xdr_int(xdrs, &rec->error)) ||
17320Sstevel@tonic-gate 	    (! xdr_cfs_time_t(xdrs, &rec->time)) ||
17330Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
17340Sstevel@tonic-gate 	    (! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
17350Sstevel@tonic-gate 	    (! xdr_ino64(xdrs, &rec->fileno)))
17360Sstevel@tonic-gate 		return (FALSE);
17370Sstevel@tonic-gate 
17380Sstevel@tonic-gate 	return (TRUE);
17390Sstevel@tonic-gate }
1740