xref: /onnv-gate/usr/src/uts/common/fs/cachefs/cachefs_dlog.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
5*5331Samw  * Common Development and Distribution License (the "License").
6*5331Samw  * 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 /*
22*5331Samw  * 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/param.h>
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <sys/systm.h>
310Sstevel@tonic-gate #include <sys/cred.h>
320Sstevel@tonic-gate #include <sys/proc.h>
330Sstevel@tonic-gate #include <sys/user.h>
340Sstevel@tonic-gate #include <sys/time.h>
350Sstevel@tonic-gate #include <sys/vnode.h>
360Sstevel@tonic-gate #include <sys/vfs.h>
370Sstevel@tonic-gate #include <sys/file.h>
380Sstevel@tonic-gate #include <sys/filio.h>
390Sstevel@tonic-gate #include <sys/uio.h>
400Sstevel@tonic-gate #include <sys/buf.h>
410Sstevel@tonic-gate #include <sys/mman.h>
420Sstevel@tonic-gate #include <sys/tiuser.h>
430Sstevel@tonic-gate #include <sys/pathname.h>
440Sstevel@tonic-gate #include <sys/dirent.h>
450Sstevel@tonic-gate #include <sys/conf.h>
460Sstevel@tonic-gate #include <sys/debug.h>
470Sstevel@tonic-gate #include <sys/vmsystm.h>
480Sstevel@tonic-gate #include <sys/fcntl.h>
490Sstevel@tonic-gate #include <sys/flock.h>
500Sstevel@tonic-gate #include <sys/swap.h>
510Sstevel@tonic-gate #include <sys/errno.h>
520Sstevel@tonic-gate #include <sys/sysmacros.h>
530Sstevel@tonic-gate #include <sys/disp.h>
540Sstevel@tonic-gate #include <sys/kmem.h>
550Sstevel@tonic-gate #include <sys/cmn_err.h>
560Sstevel@tonic-gate #include <sys/vtrace.h>
570Sstevel@tonic-gate #include <sys/mount.h>
580Sstevel@tonic-gate #include <sys/bootconf.h>
590Sstevel@tonic-gate #include <sys/dnlc.h>
600Sstevel@tonic-gate #include <sys/stat.h>
610Sstevel@tonic-gate 
620Sstevel@tonic-gate #include <vm/hat.h>
630Sstevel@tonic-gate #include <vm/as.h>
640Sstevel@tonic-gate #include <vm/page.h>
650Sstevel@tonic-gate #include <vm/pvn.h>
660Sstevel@tonic-gate #include <vm/seg.h>
670Sstevel@tonic-gate #include <vm/seg_map.h>
680Sstevel@tonic-gate #include <vm/seg_vn.h>
690Sstevel@tonic-gate #include <vm/rm.h>
700Sstevel@tonic-gate #include <sys/fs/cachefs_fs.h>
710Sstevel@tonic-gate #include <sys/fs/cachefs_dlog.h>
720Sstevel@tonic-gate #include <fs/fs_subr.h>
730Sstevel@tonic-gate 
740Sstevel@tonic-gate static int cachefs_dlog_mapreserve(fscache_t *fscp, int size);
750Sstevel@tonic-gate 
760Sstevel@tonic-gate #ifdef _LP64
770Sstevel@tonic-gate 
780Sstevel@tonic-gate static void cachefs_dlog_attrchk(vattr_t *vap, char *funcname);
790Sstevel@tonic-gate 
800Sstevel@tonic-gate #define	CACHEFS_DLOG_TS_COPY(in_tsp, out_tsp, str, str1)		\
810Sstevel@tonic-gate 	{								\
820Sstevel@tonic-gate 		int	ovferr = 0;					\
830Sstevel@tonic-gate 		CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, ovferr);	\
840Sstevel@tonic-gate 		if (ovferr)						\
850Sstevel@tonic-gate 			cmn_err(CE_WARN, "%s%s overflow", str, str1);	\
860Sstevel@tonic-gate 	}
870Sstevel@tonic-gate 
880Sstevel@tonic-gate #define	CACHEFS_DLOG_DEV_COPY(in_dev, out_dev, str, str1)		\
890Sstevel@tonic-gate 	{								\
900Sstevel@tonic-gate 		int	ovferr = 0;					\
910Sstevel@tonic-gate 		CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, ovferr);	\
920Sstevel@tonic-gate 		if (ovferr)						\
930Sstevel@tonic-gate 			cmn_err(CE_WARN, "%s%s 0x%lx -> 0x%x overflow",	\
940Sstevel@tonic-gate 				str, str1, in_dev, (dev32_t)(out_dev));	\
950Sstevel@tonic-gate 	}
960Sstevel@tonic-gate 
970Sstevel@tonic-gate #define	CACHEFS_DLOG_VATTR_COPY(in_vap, out_vap, str)			\
980Sstevel@tonic-gate 	{								\
990Sstevel@tonic-gate 		int	ovferr = 0;					\
1000Sstevel@tonic-gate 		CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vap, out_vap, ovferr); \
1010Sstevel@tonic-gate 		if (ovferr)						\
1020Sstevel@tonic-gate 			cachefs_dlog_attrchk(in_vap, str);		\
1030Sstevel@tonic-gate 	}
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate /*
1060Sstevel@tonic-gate  * check attr error - if we get an overflow error copying vattr, make sure
1070Sstevel@tonic-gate  * the field affected is actually wanted, or it might be junk
1080Sstevel@tonic-gate  */
1090Sstevel@tonic-gate static void
cachefs_dlog_attrchk(vattr_t * vap,char * str)1100Sstevel@tonic-gate cachefs_dlog_attrchk(vattr_t *vap, char *str)
1110Sstevel@tonic-gate {
1120Sstevel@tonic-gate 	dev_t		tmpdev;
1130Sstevel@tonic-gate 	cfs_timestruc_t	ts;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	if (vap->va_mask & AT_FSID) {
1160Sstevel@tonic-gate 		CACHEFS_DLOG_DEV_COPY(vap->va_fsid, tmpdev, str, ".va_fsid");
1170Sstevel@tonic-gate 	}
1180Sstevel@tonic-gate 	if (vap->va_mask & AT_RDEV) {
1190Sstevel@tonic-gate 		CACHEFS_DLOG_DEV_COPY(vap->va_rdev, tmpdev, str, ".va_rdev");
1200Sstevel@tonic-gate 	}
1210Sstevel@tonic-gate 	if (vap->va_mask & AT_MTIME) {
1220Sstevel@tonic-gate 		CACHEFS_DLOG_TS_COPY(&vap->va_mtime, &ts, str, ".va_mtime");
1230Sstevel@tonic-gate 	}
1240Sstevel@tonic-gate 	if (vap->va_mask & AT_ATIME) {
1250Sstevel@tonic-gate 		CACHEFS_DLOG_TS_COPY(&vap->va_atime, &ts, str, ".va_atime");
1260Sstevel@tonic-gate 	}
1270Sstevel@tonic-gate 	if (vap->va_mask & AT_CTIME) {
1280Sstevel@tonic-gate 		CACHEFS_DLOG_TS_COPY(&vap->va_ctime, &ts, str, ".va_ctime");
1290Sstevel@tonic-gate 	}
1300Sstevel@tonic-gate }
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate #else /* not _LP64 */
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate #define	CACHEFS_DLOG_TS_COPY(in_tsp, out_tsp, str, str1)		\
1350Sstevel@tonic-gate 	CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, error)
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate #define	CACHEFS_DLOG_DEV_COPY(in_dev, out_dev, str, str1)		\
1380Sstevel@tonic-gate 	CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, error)
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate #define	CACHEFS_DLOG_VATTR_COPY(in_vap, out_vap, str)			\
1410Sstevel@tonic-gate 	CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vap, out_vap, error)
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate #endif /* _LP64 */
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate /*
1460Sstevel@tonic-gate  *
1470Sstevel@tonic-gate  * Cachefs used to know too much about how creds looked; since it's
1480Sstevel@tonic-gate  * committed to persistent storage, we can't change the layout so
1490Sstevel@tonic-gate  * it now has a "dl_cred_t" which (unsurprisingly) looks exactly like
1500Sstevel@tonic-gate  * an old credential.
1510Sstevel@tonic-gate  *
1520Sstevel@tonic-gate  * The dst argument needs to point to:
1530Sstevel@tonic-gate  *		struct dl_cred_t;
1540Sstevel@tonic-gate  *		<buffer space>			buffer for groups
1550Sstevel@tonic-gate  *
1560Sstevel@tonic-gate  * The source is a proper kernel cred_t.
1570Sstevel@tonic-gate  *
1580Sstevel@tonic-gate  */
1590Sstevel@tonic-gate static size_t
copy_cred(cred_t * src,dl_cred_t * dst)1600Sstevel@tonic-gate copy_cred(cred_t *src, dl_cred_t *dst)
1610Sstevel@tonic-gate {
1620Sstevel@tonic-gate 	int n;
1630Sstevel@tonic-gate 	const gid_t *sgrp = crgetgroups(src);
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	n = MIN(NGROUPS_MAX_DEFAULT, crgetngroups(src));
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 	/* copy the fixed fields */
1680Sstevel@tonic-gate 	dst->cr_uid = crgetuid(src);
1690Sstevel@tonic-gate 	dst->cr_ruid = crgetruid(src);
1700Sstevel@tonic-gate 	dst->cr_suid = crgetsuid(src);
1710Sstevel@tonic-gate 	dst->cr_gid = crgetgid(src);
1720Sstevel@tonic-gate 	dst->cr_rgid = crgetrgid(src);
1730Sstevel@tonic-gate 	dst->cr_sgid = crgetsgid(src);
1740Sstevel@tonic-gate 	dst->cr_groups[0] = sgrp[0];
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	dst->cr_ngroups = n;
1770Sstevel@tonic-gate 	bcopy(sgrp, (void *)(dst + 1), (n - 1) * sizeof (gid_t));
1780Sstevel@tonic-gate 	return (sizeof (dl_cred_t) + (n - 1) * sizeof (gid_t));
1790Sstevel@tonic-gate }
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate /*
1820Sstevel@tonic-gate  * Sets up for writing to the log files.
1830Sstevel@tonic-gate  */
1840Sstevel@tonic-gate int
cachefs_dlog_setup(fscache_t * fscp,int createfile)1850Sstevel@tonic-gate cachefs_dlog_setup(fscache_t *fscp, int createfile)
1860Sstevel@tonic-gate {
1870Sstevel@tonic-gate 	struct vattr vattr;
1880Sstevel@tonic-gate 	int error = 0;
1890Sstevel@tonic-gate 	int createdone = 0;
1900Sstevel@tonic-gate 	int lookupdone = 0;
1910Sstevel@tonic-gate 	int version = CFS_DLOG_VERSION;
1920Sstevel@tonic-gate 	off_t offset;
1930Sstevel@tonic-gate 	struct cfs_dlog_trailer trailer;
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	mutex_enter(&fscp->fs_dlock);
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	/* all done if the log files already exist */
1980Sstevel@tonic-gate 	if (fscp->fs_dlogfile) {
1990Sstevel@tonic-gate 		ASSERT(fscp->fs_dmapfile);
2000Sstevel@tonic-gate 		goto out;
2010Sstevel@tonic-gate 	}
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	/* see if the log file exists */
2040Sstevel@tonic-gate 	error = VOP_LOOKUP(fscp->fs_fscdirvp, CACHEFS_DLOG_FILE,
205*5331Samw 	    &fscp->fs_dlogfile, NULL, 0, NULL, kcred, NULL, NULL, NULL);
2060Sstevel@tonic-gate 	if (error && (createfile == 0))
2070Sstevel@tonic-gate 		goto out;
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	/* if the lookup failed then create file log files */
2100Sstevel@tonic-gate 	if (error) {
2110Sstevel@tonic-gate 		createdone++;
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 		vattr.va_mode = S_IFREG | 0666;
2140Sstevel@tonic-gate 		vattr.va_uid = 0;
2150Sstevel@tonic-gate 		vattr.va_gid = 0;
2160Sstevel@tonic-gate 		vattr.va_type = VREG;
2170Sstevel@tonic-gate 		vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
2180Sstevel@tonic-gate 		error = VOP_CREATE(fscp->fs_fscdirvp, CACHEFS_DLOG_FILE,
219*5331Samw 		    &vattr, 0, 0666, &fscp->fs_dlogfile, kcred, 0, NULL, NULL);
2200Sstevel@tonic-gate 		if (error) {
2210Sstevel@tonic-gate #ifdef CFSDEBUG
2220Sstevel@tonic-gate 			CFS_DEBUG(CFSDEBUG_DLOG)
2230Sstevel@tonic-gate 				printf("cachefs: log file create fail %d\n",
2240Sstevel@tonic-gate 				    error);
2250Sstevel@tonic-gate #endif
2260Sstevel@tonic-gate 			goto out;
2270Sstevel@tonic-gate 		}
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 		/* write the version number into the log file */
2300Sstevel@tonic-gate 		error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile, (caddr_t)&version,
2310Sstevel@tonic-gate 		    sizeof (version), (offset_t)0, UIO_SYSSPACE, FSYNC,
2320Sstevel@tonic-gate 		    RLIM_INFINITY, kcred, NULL);
2330Sstevel@tonic-gate 		if (error) {
2340Sstevel@tonic-gate #ifdef CFSDEBUG
2350Sstevel@tonic-gate 			CFS_DEBUG(CFSDEBUG_DLOG)
2360Sstevel@tonic-gate 				printf("cachefs: log file init fail %d\n",
2370Sstevel@tonic-gate 				    error);
2380Sstevel@tonic-gate #endif
2390Sstevel@tonic-gate 			goto out;
2400Sstevel@tonic-gate 		}
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 		vattr.va_mode = S_IFREG | 0666;
2430Sstevel@tonic-gate 		vattr.va_uid = 0;
2440Sstevel@tonic-gate 		vattr.va_gid = 0;
2450Sstevel@tonic-gate 		vattr.va_type = VREG;
2460Sstevel@tonic-gate 		vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
2470Sstevel@tonic-gate 		error = VOP_CREATE(fscp->fs_fscdirvp, CACHEFS_DMAP_FILE,
248*5331Samw 		    &vattr, 0, 0666, &fscp->fs_dmapfile, kcred, 0, NULL, NULL);
2490Sstevel@tonic-gate 		if (error) {
2500Sstevel@tonic-gate #ifdef CFSDEBUG
2510Sstevel@tonic-gate 			CFS_DEBUG(CFSDEBUG_DLOG)
2520Sstevel@tonic-gate 				printf("cachefs: map file create fail %d\n",
2530Sstevel@tonic-gate 				    error);
2540Sstevel@tonic-gate #endif
2550Sstevel@tonic-gate 			goto out;
2560Sstevel@tonic-gate 		}
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 		fscp->fs_dlogoff = sizeof (version);
2590Sstevel@tonic-gate 		fscp->fs_dlogseq = 0;
2600Sstevel@tonic-gate 		fscp->fs_dmapoff = 0;
2610Sstevel@tonic-gate 		fscp->fs_dmapsize = 0;
2620Sstevel@tonic-gate 	}
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate 	/*
2650Sstevel@tonic-gate 	 * Else the lookup succeeded.
2660Sstevel@tonic-gate 	 * Before mounting, fsck should have fixed any problems
2670Sstevel@tonic-gate 	 * in the log file.
2680Sstevel@tonic-gate 	 */
2690Sstevel@tonic-gate 	else {
2700Sstevel@tonic-gate 		lookupdone++;
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 		/* find the end of the log file */
2730Sstevel@tonic-gate 		vattr.va_mask = AT_ALL;
274*5331Samw 		error = VOP_GETATTR(fscp->fs_dlogfile, &vattr, 0, kcred, NULL);
2750Sstevel@tonic-gate 		if (error) {
2760Sstevel@tonic-gate #ifdef CFSDEBUG
2770Sstevel@tonic-gate 			CFS_DEBUG(CFSDEBUG_DLOG)
2780Sstevel@tonic-gate 				printf("cachefs: log file getattr fail %d\n",
2790Sstevel@tonic-gate 				    error);
2800Sstevel@tonic-gate #endif
2810Sstevel@tonic-gate 			goto out;
2820Sstevel@tonic-gate 		}
2830Sstevel@tonic-gate 		/*LINTED alignment okay*/
2840Sstevel@tonic-gate 		ASSERT(vattr.va_size <= MAXOFF_T);
2850Sstevel@tonic-gate 		fscp->fs_dlogoff = (off_t)vattr.va_size;
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 		offset = vattr.va_size - sizeof (struct cfs_dlog_trailer);
2880Sstevel@tonic-gate 		/*
2890Sstevel@tonic-gate 		 * The last record in the dlog file is a trailer record
2900Sstevel@tonic-gate 		 * that contains the last sequence number used. This is
2910Sstevel@tonic-gate 		 * used to reset the sequence number when a logfile already
2920Sstevel@tonic-gate 		 * exists.
2930Sstevel@tonic-gate 		 */
2940Sstevel@tonic-gate 		error = vn_rdwr(UIO_READ, fscp->fs_dlogfile, (caddr_t)&trailer,
2950Sstevel@tonic-gate 		    sizeof (struct cfs_dlog_trailer), (offset_t)offset,
2960Sstevel@tonic-gate 		    UIO_SYSSPACE, FSYNC, RLIM_INFINITY, kcred, NULL);
2970Sstevel@tonic-gate 		if (error == 0) {
2980Sstevel@tonic-gate 			if (trailer.dl_op == CFS_DLOG_TRAILER) {
2990Sstevel@tonic-gate 				fscp->fs_dlogseq = trailer.dl_seq;
3000Sstevel@tonic-gate 				/*
3010Sstevel@tonic-gate 				 * Set the offset of the next record to be
3020Sstevel@tonic-gate 				 * written, to over write the current
3030Sstevel@tonic-gate 				 * trailer.
3040Sstevel@tonic-gate 				 */
3050Sstevel@tonic-gate 				fscp->fs_dlogoff = offset;
3060Sstevel@tonic-gate 			} else {
3070Sstevel@tonic-gate #ifdef CFSDEBUG
3080Sstevel@tonic-gate 				CFS_DEBUG(CFSDEBUG_DLOG) {
3090Sstevel@tonic-gate 					cmn_err(CE_WARN,
3100Sstevel@tonic-gate 					    "cachefs: can't find dlog trailer");
3110Sstevel@tonic-gate 					cmn_err(CE_WARN,
3120Sstevel@tonic-gate 					    "cachefs: fsck required");
3130Sstevel@tonic-gate 				}
3140Sstevel@tonic-gate #endif /* CFSDEBUG */
3150Sstevel@tonic-gate 				/*LINTED alignment okay*/
3160Sstevel@tonic-gate 				fscp->fs_dlogseq = (uint_t)vattr.va_size;
3170Sstevel@tonic-gate 			}
3180Sstevel@tonic-gate 		} else {
3190Sstevel@tonic-gate #ifdef CFSDEBUG
3200Sstevel@tonic-gate 			CFS_DEBUG(CFSDEBUG_DLOG)
3210Sstevel@tonic-gate 				cmn_err(CE_WARN,
3220Sstevel@tonic-gate 				    "cachefs: error reading dlog trailer");
3230Sstevel@tonic-gate #endif /* CFSDEBUG */
3240Sstevel@tonic-gate 			/*LINTED alignment okay*/
3250Sstevel@tonic-gate 			fscp->fs_dlogseq = (uint_t)vattr.va_size;
3260Sstevel@tonic-gate 		}
3270Sstevel@tonic-gate 
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 		error = VOP_LOOKUP(fscp->fs_fscdirvp, CACHEFS_DMAP_FILE,
330*5331Samw 		    &fscp->fs_dmapfile, NULL, 0, NULL, kcred, NULL, NULL, NULL);
3310Sstevel@tonic-gate 		if (error) {
3320Sstevel@tonic-gate #ifdef CFSDEBUG
3330Sstevel@tonic-gate 			CFS_DEBUG(CFSDEBUG_DLOG)
3340Sstevel@tonic-gate 				printf("cachefs: map file lookup fail %d\n",
3350Sstevel@tonic-gate 				    error);
3360Sstevel@tonic-gate #endif
3370Sstevel@tonic-gate 			goto out;
3380Sstevel@tonic-gate 		}
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 		vattr.va_mask = AT_ALL;
341*5331Samw 		error = VOP_GETATTR(fscp->fs_dmapfile, &vattr, 0, kcred, NULL);
3420Sstevel@tonic-gate 		if (error) {
3430Sstevel@tonic-gate #ifdef CFSDEBUG
3440Sstevel@tonic-gate 			CFS_DEBUG(CFSDEBUG_DLOG)
3450Sstevel@tonic-gate 				printf("cachefs: map file getattr fail %d\n",
3460Sstevel@tonic-gate 				    error);
3470Sstevel@tonic-gate #endif
3480Sstevel@tonic-gate 			goto out;
3490Sstevel@tonic-gate 		}
3500Sstevel@tonic-gate 		fscp->fs_dmapoff = (off_t)vattr.va_size;
3510Sstevel@tonic-gate 		fscp->fs_dmapsize = (off_t)vattr.va_size;
3520Sstevel@tonic-gate 	}
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate out:
3550Sstevel@tonic-gate 	if (error) {
3560Sstevel@tonic-gate 		if (createdone) {
3570Sstevel@tonic-gate 			if (fscp->fs_dlogfile) {
3580Sstevel@tonic-gate 				VN_RELE(fscp->fs_dlogfile);
3590Sstevel@tonic-gate 				fscp->fs_dlogfile = NULL;
3600Sstevel@tonic-gate 				(void) VOP_REMOVE(fscp->fs_fscdirvp,
361*5331Samw 				    CACHEFS_DLOG_FILE, kcred, NULL, 0);
3620Sstevel@tonic-gate 			}
3630Sstevel@tonic-gate 			if (fscp->fs_dmapfile) {
3640Sstevel@tonic-gate 				VN_RELE(fscp->fs_dmapfile);
3650Sstevel@tonic-gate 				fscp->fs_dmapfile = NULL;
3660Sstevel@tonic-gate 				(void) VOP_REMOVE(fscp->fs_fscdirvp,
367*5331Samw 				    CACHEFS_DMAP_FILE, kcred, NULL, 0);
3680Sstevel@tonic-gate 			}
3690Sstevel@tonic-gate 		}
3700Sstevel@tonic-gate 		if (lookupdone) {
3710Sstevel@tonic-gate 			if (fscp->fs_dlogfile) {
3720Sstevel@tonic-gate 				VN_RELE(fscp->fs_dlogfile);
3730Sstevel@tonic-gate 				fscp->fs_dlogfile = NULL;
3740Sstevel@tonic-gate 			}
3750Sstevel@tonic-gate 			if (fscp->fs_dmapfile) {
3760Sstevel@tonic-gate 				VN_RELE(fscp->fs_dmapfile);
3770Sstevel@tonic-gate 				fscp->fs_dmapfile = NULL;
3780Sstevel@tonic-gate 			}
3790Sstevel@tonic-gate 		}
3800Sstevel@tonic-gate 	}
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 	mutex_exit(&fscp->fs_dlock);
3830Sstevel@tonic-gate 	return (error);
3840Sstevel@tonic-gate }
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate /*
3870Sstevel@tonic-gate  * Drops reference to the log file.
3880Sstevel@tonic-gate  */
3890Sstevel@tonic-gate void
cachefs_dlog_teardown(fscache_t * fscp)3900Sstevel@tonic-gate cachefs_dlog_teardown(fscache_t *fscp)
3910Sstevel@tonic-gate {
3920Sstevel@tonic-gate 	vattr_t va;
3930Sstevel@tonic-gate 	/*LINTED: set but not used */
3940Sstevel@tonic-gate 	int error;
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate 	mutex_enter(&fscp->fs_dlock);
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	/* clean up the log file */
3990Sstevel@tonic-gate 	if (fscp->fs_dlogfile) {
4000Sstevel@tonic-gate 		VN_RELE(fscp->fs_dlogfile);
4010Sstevel@tonic-gate 		fscp->fs_dlogfile = NULL;
4020Sstevel@tonic-gate 	}
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate 	/* clean up the map file */
4050Sstevel@tonic-gate 	if (fscp->fs_dmapfile) {
4060Sstevel@tonic-gate 		/* set the map file to the actual size needed */
4070Sstevel@tonic-gate 		va.va_mask = AT_SIZE;
4080Sstevel@tonic-gate 		va.va_size = fscp->fs_dmapoff;
4090Sstevel@tonic-gate 		error = VOP_SETATTR(fscp->fs_dmapfile, &va, 0, kcred, NULL);
4100Sstevel@tonic-gate #ifdef CFSDEBUG
4110Sstevel@tonic-gate 		if (error) {
4120Sstevel@tonic-gate 			cmn_err(CE_WARN, "cachefs: map setattr failed %d",
4130Sstevel@tonic-gate 			    error);
4140Sstevel@tonic-gate 		}
4150Sstevel@tonic-gate #endif
4160Sstevel@tonic-gate 		VN_RELE(fscp->fs_dmapfile);
4170Sstevel@tonic-gate 		fscp->fs_dmapfile = NULL;
4180Sstevel@tonic-gate 	}
4190Sstevel@tonic-gate 	mutex_exit(&fscp->fs_dlock);
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate /*
4230Sstevel@tonic-gate  * Outputs a dlog message to the log file.
4240Sstevel@tonic-gate  */
4250Sstevel@tonic-gate static off_t
cachefs_dlog_output(fscache_t * fscp,cfs_dlog_entry_t * entp,uint_t * seqp)4260Sstevel@tonic-gate cachefs_dlog_output(fscache_t *fscp, cfs_dlog_entry_t *entp, uint_t *seqp)
4270Sstevel@tonic-gate {
4280Sstevel@tonic-gate 	int error;
4290Sstevel@tonic-gate 	off_t offset;
4300Sstevel@tonic-gate 	int xx;
4310Sstevel@tonic-gate 	uint_t seq;
4320Sstevel@tonic-gate 	int len;
4330Sstevel@tonic-gate 	struct cfs_dlog_trailer *trail;
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 	ASSERT(entp->dl_len <= CFS_DLOG_ENTRY_MAXSIZE);
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate 	if (fscp->fs_dlogfile == NULL) {
4380Sstevel@tonic-gate 		error = cachefs_dlog_setup(fscp, 1);
4390Sstevel@tonic-gate 		if (error) {
4400Sstevel@tonic-gate 			offset = 0;
4410Sstevel@tonic-gate 			goto out;
4420Sstevel@tonic-gate 		}
4430Sstevel@tonic-gate 	}
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	/* round up length to a 4 byte boundary */
4460Sstevel@tonic-gate 	len = entp->dl_len;
4470Sstevel@tonic-gate 	xx = len & 0x03;
4480Sstevel@tonic-gate 	if (xx) {
4490Sstevel@tonic-gate 		xx = 4 - xx;
4500Sstevel@tonic-gate 		bzero((void *)((uintptr_t)entp + len), (size_t)xx);
4510Sstevel@tonic-gate 		len += xx;
4520Sstevel@tonic-gate 		entp->dl_len = len;
4530Sstevel@tonic-gate 	}
4540Sstevel@tonic-gate 
4550Sstevel@tonic-gate 	/* XXX turn this on/off in sync with code in cachefs_dlog_setsecattr */
4560Sstevel@tonic-gate #if 0
4570Sstevel@tonic-gate 	/* XXX debugging hack, round up to 16 byte boundary */
4580Sstevel@tonic-gate 	len = entp->dl_len;
4590Sstevel@tonic-gate 	xx = 16 - (len & 0x0f);
4600Sstevel@tonic-gate 	bcopy("UUUUUUUUUUUUUUUU", (void *)((uintptr_t)entp + len), (size_t)xx);
4610Sstevel@tonic-gate 	len += xx;
4620Sstevel@tonic-gate 	entp->dl_len = len;
4630Sstevel@tonic-gate #endif
4640Sstevel@tonic-gate 
4650Sstevel@tonic-gate 	/*
4660Sstevel@tonic-gate 	 * All functions which allocate a dlog entry buffer must be sure
4670Sstevel@tonic-gate 	 * to allocate space for the trailer record. The trailer record,
4680Sstevel@tonic-gate 	 * is always located at the end of the log file. It contains the
4690Sstevel@tonic-gate 	 * highest sequence number used. This allows cachefs_dlog_setup()
4700Sstevel@tonic-gate 	 * to reset the sequence numbers properly when the log file
4710Sstevel@tonic-gate 	 * already exists.
4720Sstevel@tonic-gate 	 */
4730Sstevel@tonic-gate 	trail = (struct cfs_dlog_trailer *)((uintptr_t)entp + entp->dl_len);
4740Sstevel@tonic-gate 	trail->dl_len = sizeof (struct cfs_dlog_trailer);
4750Sstevel@tonic-gate 	trail->dl_op = CFS_DLOG_TRAILER;
4760Sstevel@tonic-gate 	trail->dl_valid = CFS_DLOG_VAL_COMMITTED;
4770Sstevel@tonic-gate 	mutex_enter(&fscp->fs_dlock);
4780Sstevel@tonic-gate 	ASSERT(fscp->fs_dlogfile);
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 	/* get a sequence number for this log entry */
4810Sstevel@tonic-gate 	seq = fscp->fs_dlogseq + 1;
4820Sstevel@tonic-gate 	if (seq == 0) {
4830Sstevel@tonic-gate 		mutex_exit(&fscp->fs_dlock);
4840Sstevel@tonic-gate 		offset = 0;
4850Sstevel@tonic-gate #ifdef CFSDEBUG
4860Sstevel@tonic-gate 		cmn_err(CE_WARN, "cachefs: logging failed, seq overflow");
4870Sstevel@tonic-gate #endif
4880Sstevel@tonic-gate 		goto out;
4890Sstevel@tonic-gate 	}
4900Sstevel@tonic-gate 	fscp->fs_dlogseq++;
4910Sstevel@tonic-gate 	trail->dl_seq = fscp->fs_dlogseq;
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate 	/* add the sequence number to the record */
4940Sstevel@tonic-gate 	entp->dl_seq = seq;
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate 	/* get offset into file to write record */
4970Sstevel@tonic-gate 	offset = fscp->fs_dlogoff;
4980Sstevel@tonic-gate 
4990Sstevel@tonic-gate 	/* try to write the record to the log file */
5000Sstevel@tonic-gate 	/*
5010Sstevel@tonic-gate 	 * NOTE This write will over write the previous trailer record and
5020Sstevel@tonic-gate 	 * will add a new trailer record. This is done with a single
5030Sstevel@tonic-gate 	 * write for performance reasons.
5040Sstevel@tonic-gate 	 */
5050Sstevel@tonic-gate 	error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile, (caddr_t)entp,
5060Sstevel@tonic-gate 	    entp->dl_len+trail->dl_len, (offset_t)offset, UIO_SYSSPACE, FSYNC,
5070Sstevel@tonic-gate 	    RLIM_INFINITY, kcred, NULL);
5080Sstevel@tonic-gate 
5090Sstevel@tonic-gate 	if (error) {
5100Sstevel@tonic-gate 		offset = 0;
5110Sstevel@tonic-gate 		cmn_err(CE_WARN, "cachefs: logging failed (%d)", error);
5120Sstevel@tonic-gate 	} else {
5130Sstevel@tonic-gate 		fscp->fs_dlogoff += entp->dl_len;
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 		/* get offset of valid field */
5160Sstevel@tonic-gate 		offset += offsetof(struct cfs_dlog_entry, dl_valid);
5170Sstevel@tonic-gate 	}
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate 	mutex_exit(&fscp->fs_dlock);
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	/* return sequence number used if requested */
5220Sstevel@tonic-gate 	if (seqp)
5230Sstevel@tonic-gate 		*seqp = seq;
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate out:
5260Sstevel@tonic-gate 	return (offset);
5270Sstevel@tonic-gate }
5280Sstevel@tonic-gate 
5290Sstevel@tonic-gate /*
530*5331Samw  * Commits a previously written dlog message.
5310Sstevel@tonic-gate  */
5320Sstevel@tonic-gate int
cachefs_dlog_commit(fscache_t * fscp,off_t offset,int error)5330Sstevel@tonic-gate cachefs_dlog_commit(fscache_t *fscp, off_t offset, int error)
5340Sstevel@tonic-gate {
5350Sstevel@tonic-gate 	cfs_dlog_val_t valid;
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	if (error)
5380Sstevel@tonic-gate 		valid = CFS_DLOG_VAL_ERROR;
5390Sstevel@tonic-gate 	else
5400Sstevel@tonic-gate 		valid = CFS_DLOG_VAL_COMMITTED;
5410Sstevel@tonic-gate 
5420Sstevel@tonic-gate 	error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile,
5430Sstevel@tonic-gate 	    (caddr_t)&valid, sizeof (valid), (offset_t)offset,
5440Sstevel@tonic-gate 	    UIO_SYSSPACE, FSYNC, RLIM_INFINITY, kcred, NULL);
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate 	if (error)
5470Sstevel@tonic-gate 		cmn_err(CE_WARN, "cachefs: logging commit failed (%d)", error);
5480Sstevel@tonic-gate 	return (error);
5490Sstevel@tonic-gate }
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate /*
5520Sstevel@tonic-gate  * Reserves space in the map file.
5530Sstevel@tonic-gate  */
5540Sstevel@tonic-gate static int
cachefs_dlog_mapreserve(fscache_t * fscp,int size)5550Sstevel@tonic-gate cachefs_dlog_mapreserve(fscache_t *fscp, int size)
5560Sstevel@tonic-gate {
5570Sstevel@tonic-gate 	int error = 0;
5580Sstevel@tonic-gate 	int len;
5590Sstevel@tonic-gate 	char *bufp;
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate 	if (fscp->fs_dmapfile == NULL) {
5620Sstevel@tonic-gate 		error = cachefs_dlog_setup(fscp, 1);
5630Sstevel@tonic-gate 		if (error) {
5640Sstevel@tonic-gate 			return (error);
5650Sstevel@tonic-gate 		}
5660Sstevel@tonic-gate 	}
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate 	mutex_enter(&fscp->fs_dlock);
5690Sstevel@tonic-gate 	ASSERT(fscp->fs_dmapoff <= fscp->fs_dmapsize);
5700Sstevel@tonic-gate 	ASSERT(fscp->fs_dmapfile);
5710Sstevel@tonic-gate 
5720Sstevel@tonic-gate 	if ((fscp->fs_dmapoff + size) > fscp->fs_dmapsize) {
5730Sstevel@tonic-gate 		/* reserve 20% for optimal hashing */
5740Sstevel@tonic-gate 		size += MAXBSIZE / 5;
5750Sstevel@tonic-gate 
5760Sstevel@tonic-gate 		/* grow file by a MAXBSIZE chunk */
5770Sstevel@tonic-gate 		len = MAXBSIZE;
5780Sstevel@tonic-gate 		ASSERT((fscp->fs_dmapoff + size) < (fscp->fs_dmapsize + len));
5790Sstevel@tonic-gate 
5800Sstevel@tonic-gate 		bufp = cachefs_kmem_zalloc(len, KM_SLEEP);
5810Sstevel@tonic-gate 		error = vn_rdwr(UIO_WRITE, fscp->fs_dmapfile, (caddr_t)bufp,
5820Sstevel@tonic-gate 			len, (offset_t)fscp->fs_dmapsize, UIO_SYSSPACE, FSYNC,
5830Sstevel@tonic-gate 			RLIM_INFINITY, kcred, NULL);
5840Sstevel@tonic-gate 		if (error == 0) {
5850Sstevel@tonic-gate 			fscp->fs_dmapoff += size;
5860Sstevel@tonic-gate 			fscp->fs_dmapsize += len;
5870Sstevel@tonic-gate 		} else {
5880Sstevel@tonic-gate 			cmn_err(CE_WARN, "cachefs: logging secondary "
5890Sstevel@tonic-gate 			    "failed (%d)", error);
5900Sstevel@tonic-gate 		}
5910Sstevel@tonic-gate 		cachefs_kmem_free(bufp, len);
5920Sstevel@tonic-gate 	} else {
5930Sstevel@tonic-gate 		fscp->fs_dmapoff += size;
5940Sstevel@tonic-gate 	}
5950Sstevel@tonic-gate 	mutex_exit(&fscp->fs_dlock);
5960Sstevel@tonic-gate 	return (error);
5970Sstevel@tonic-gate }
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate /*
6000Sstevel@tonic-gate  * Reserves space for one cid mapping in the mapping file.
6010Sstevel@tonic-gate  */
6020Sstevel@tonic-gate int
cachefs_dlog_cidmap(fscache_t * fscp)6030Sstevel@tonic-gate cachefs_dlog_cidmap(fscache_t *fscp)
6040Sstevel@tonic-gate {
6050Sstevel@tonic-gate 	int error;
6060Sstevel@tonic-gate 	error = cachefs_dlog_mapreserve(fscp,
6070Sstevel@tonic-gate 	    sizeof (struct cfs_dlog_mapping_space));
6080Sstevel@tonic-gate 	return (error);
6090Sstevel@tonic-gate }
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate off_t
cachefs_dlog_setattr(fscache_t * fscp,struct vattr * vap,int flags,cnode_t * cp,cred_t * cr)6120Sstevel@tonic-gate cachefs_dlog_setattr(fscache_t *fscp, struct vattr *vap, int flags,
6130Sstevel@tonic-gate     cnode_t *cp, cred_t *cr)
6140Sstevel@tonic-gate {
6150Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
6160Sstevel@tonic-gate 	struct cfs_dlog_setattr *up;
6170Sstevel@tonic-gate 	size_t	len;
6180Sstevel@tonic-gate 	off_t offset;
6190Sstevel@tonic-gate 
6200Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&cp->c_statelock));
6210Sstevel@tonic-gate 
6220Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
6250Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_SETATTR;
6260Sstevel@tonic-gate 	up = &entp->dl_u.dl_setattr;
6270Sstevel@tonic-gate 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
6280Sstevel@tonic-gate 		"cachefs_dlog_setattr: dl_attr");
6290Sstevel@tonic-gate 	up->dl_flags = flags;
6300Sstevel@tonic-gate 	up->dl_cid = cp->c_id;
6310Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
6320Sstevel@tonic-gate 		&up->dl_times.tm_mtime, "cachefs_dlog_setattr: ", "mtime");
6330Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
6340Sstevel@tonic-gate 		&up->dl_times.tm_ctime, "cachefs_dlog_setattr: ", "ctime");
6350Sstevel@tonic-gate 
6360Sstevel@tonic-gate 	/* store the cred info */
6370Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
6380Sstevel@tonic-gate 
6390Sstevel@tonic-gate 	/* Calculate the length of this record */
6400Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)&up->dl_cred + len) - (uintptr_t)entp);
6410Sstevel@tonic-gate 
6420Sstevel@tonic-gate 	/* write the record in the log */
6430Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
6440Sstevel@tonic-gate 
6450Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
6460Sstevel@tonic-gate 	return (offset);
6470Sstevel@tonic-gate }
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate off_t
6500Sstevel@tonic-gate /*ARGSUSED*/
cachefs_dlog_setsecattr(fscache_t * fscp,vsecattr_t * vsec,int flags,cnode_t * cp,cred_t * cr)6510Sstevel@tonic-gate cachefs_dlog_setsecattr(fscache_t *fscp, vsecattr_t *vsec, int flags,
6520Sstevel@tonic-gate     cnode_t *cp, cred_t *cr)
6530Sstevel@tonic-gate {
6540Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
6550Sstevel@tonic-gate 	struct cfs_dlog_setsecattr *up;
6560Sstevel@tonic-gate 	size_t alen, clen, len;
6570Sstevel@tonic-gate 	off_t offset = 0;
6580Sstevel@tonic-gate 	aclent_t *aclp;
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&cp->c_statelock));
6610Sstevel@tonic-gate 
6620Sstevel@tonic-gate 	/* paranoia */
6630Sstevel@tonic-gate 	ASSERT((vsec->vsa_mask & VSA_ACL) || (vsec->vsa_aclcnt == 0));
6640Sstevel@tonic-gate 	ASSERT((vsec->vsa_mask & VSA_DFACL) || (vsec->vsa_dfaclcnt == 0));
6650Sstevel@tonic-gate 	if ((vsec->vsa_mask & VSA_ACL) == 0)
6660Sstevel@tonic-gate 		vsec->vsa_aclcnt = 0;
6670Sstevel@tonic-gate 	if ((vsec->vsa_mask & VSA_DFACL) == 0)
6680Sstevel@tonic-gate 		vsec->vsa_dfaclcnt = 0;
6690Sstevel@tonic-gate 
6700Sstevel@tonic-gate 	/* calculate length of ACL and cred data */
6710Sstevel@tonic-gate 	alen = sizeof (aclent_t) * (vsec->vsa_aclcnt + vsec->vsa_dfaclcnt);
6720Sstevel@tonic-gate 	clen = sizeof (dl_cred_t) + (((long)crgetngroups(cr)) * sizeof (gid_t));
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 	/*
6750Sstevel@tonic-gate 	 * allocate entry.  ACLs may be up to 24k currently, but they
6760Sstevel@tonic-gate 	 * usually won't, so we don't want to make cfs_dlog_entry_t
6770Sstevel@tonic-gate 	 * too big.  so, we must compute the length here.
6780Sstevel@tonic-gate 	 */
6790Sstevel@tonic-gate 
6800Sstevel@tonic-gate 	len = sizeof (cfs_dlog_entry_t) - sizeof (up->dl_buffer) -
6810Sstevel@tonic-gate 		sizeof (up->dl_cred) + alen + clen;
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 
6840Sstevel@tonic-gate #if 0
6850Sstevel@tonic-gate 	/* make up for weird behavior in cachefs_dlog_output */
6860Sstevel@tonic-gate 	/* XXX turn this on/off in sync with code in cachefs_dlog_output */
6870Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(len + 32 + sizeof (struct cfs_dlog_trailer),
6880Sstevel@tonic-gate 	    KM_SLEEP);
6890Sstevel@tonic-gate #else
6900Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(len, KM_SLEEP);
6910Sstevel@tonic-gate #endif
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
6940Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_SETSECATTR;
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate 	up = &entp->dl_u.dl_setsecattr;
6970Sstevel@tonic-gate 	up->dl_cid = cp->c_id;
6980Sstevel@tonic-gate 
6990Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
7000Sstevel@tonic-gate 		&up->dl_times.tm_mtime, "cachefs_dlog_setsecattr: ", "mtime");
7010Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
7020Sstevel@tonic-gate 		&up->dl_times.tm_ctime, "cachefs_dlog_setsecattr: ", "ctime");
7030Sstevel@tonic-gate 
7040Sstevel@tonic-gate 	/* get the creds */
7050Sstevel@tonic-gate 	(void) copy_cred(cr, &up->dl_cred);
7060Sstevel@tonic-gate 
7070Sstevel@tonic-gate 	/* mask and counts */
7080Sstevel@tonic-gate 	up->dl_mask = vsec->vsa_mask;
7090Sstevel@tonic-gate 	up->dl_aclcnt = vsec->vsa_aclcnt;
7100Sstevel@tonic-gate 	up->dl_dfaclcnt = vsec->vsa_dfaclcnt;
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 	/* get the acls themselves */
7130Sstevel@tonic-gate 	aclp = (aclent_t *)((uintptr_t)(&up->dl_cred) + clen);
7140Sstevel@tonic-gate 	if (vsec->vsa_aclcnt > 0) {
7150Sstevel@tonic-gate 		bcopy(vsec->vsa_aclentp, aclp,
7160Sstevel@tonic-gate 		    vsec->vsa_aclcnt * sizeof (aclent_t));
7170Sstevel@tonic-gate 		aclp += vsec->vsa_aclcnt;
7180Sstevel@tonic-gate 	}
7190Sstevel@tonic-gate 	if (vsec->vsa_dfaclcnt > 0) {
7200Sstevel@tonic-gate 		bcopy(vsec->vsa_dfaclentp, aclp,
7210Sstevel@tonic-gate 		    vsec->vsa_dfaclcnt * sizeof (aclent_t));
7220Sstevel@tonic-gate 	}
7230Sstevel@tonic-gate 
7240Sstevel@tonic-gate 	entp->dl_len = (int)len;
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate #if 0
7290Sstevel@tonic-gate 	/* XXX turn on/off in sync with code in cachefs_dlog_output */
7300Sstevel@tonic-gate 	cachefs_kmem_free(entp, len + 32 + sizeof (struct cfs_dlog_trailer));
7310Sstevel@tonic-gate #else
7320Sstevel@tonic-gate 	cachefs_kmem_free(entp, len);
7330Sstevel@tonic-gate #endif
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate 	return (offset);
7360Sstevel@tonic-gate }
7370Sstevel@tonic-gate 
7380Sstevel@tonic-gate off_t
cachefs_dlog_create(fscache_t * fscp,cnode_t * pcp,char * nm,vattr_t * vap,int excl,int mode,cnode_t * cp,int exists,cred_t * cr)7390Sstevel@tonic-gate cachefs_dlog_create(fscache_t *fscp, cnode_t *pcp, char *nm,
7400Sstevel@tonic-gate     vattr_t *vap, int excl, int mode, cnode_t *cp, int exists, cred_t *cr)
7410Sstevel@tonic-gate {
7420Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
7430Sstevel@tonic-gate 	struct cfs_dlog_create *up;
7440Sstevel@tonic-gate 	size_t len;
7450Sstevel@tonic-gate 	caddr_t curp;
7460Sstevel@tonic-gate 	off_t offset;
7470Sstevel@tonic-gate 
7480Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&cp->c_statelock));
7490Sstevel@tonic-gate 
7500Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
7510Sstevel@tonic-gate 
7520Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
7530Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_CREATE;
7540Sstevel@tonic-gate 	up = &entp->dl_u.dl_create;
7550Sstevel@tonic-gate 	up->dl_parent_cid = pcp->c_id;
7560Sstevel@tonic-gate 	up->dl_new_cid = cp->c_id;
7570Sstevel@tonic-gate 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
7580Sstevel@tonic-gate 		"cachefs_dlog_create: dl_attr");
7590Sstevel@tonic-gate 	up->dl_excl = excl;
7600Sstevel@tonic-gate 	up->dl_mode = mode;
7610Sstevel@tonic-gate 	up->dl_exists = exists;
7620Sstevel@tonic-gate 	bzero(&up->dl_fid, sizeof (up->dl_fid));
7630Sstevel@tonic-gate 	if (exists) {
7640Sstevel@tonic-gate 		CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
7650Sstevel@tonic-gate 			&up->dl_times.tm_mtime,
7660Sstevel@tonic-gate 			"cachefs_dlog_create: ", "mtime");
7670Sstevel@tonic-gate 		CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
7680Sstevel@tonic-gate 			&up->dl_times.tm_ctime,
7690Sstevel@tonic-gate 			"cachefs_dlog_create: ", "ctime");
7700Sstevel@tonic-gate 	} else {
7710Sstevel@tonic-gate 		up->dl_times.tm_ctime.tv_sec = 0;
7720Sstevel@tonic-gate 		up->dl_times.tm_ctime.tv_nsec = 0;
7730Sstevel@tonic-gate 		up->dl_times.tm_mtime.tv_sec = 0;
7740Sstevel@tonic-gate 		up->dl_times.tm_mtime.tv_nsec = 0;
7750Sstevel@tonic-gate 	}
7760Sstevel@tonic-gate 
7770Sstevel@tonic-gate 	/* store the cred info */
7780Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate 	/* find the address in buffer past where the creds are stored */
7810Sstevel@tonic-gate 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
7820Sstevel@tonic-gate 
7830Sstevel@tonic-gate 	/* store the created name */
7840Sstevel@tonic-gate 	len = strlen(nm) + 1;
7850Sstevel@tonic-gate 	bcopy(nm, curp, len);
7860Sstevel@tonic-gate 
7870Sstevel@tonic-gate 	/* calculate the length of this record */
7880Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate 	/* write the record in the log */
7910Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
7940Sstevel@tonic-gate 	return (offset);
7950Sstevel@tonic-gate }
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate off_t
cachefs_dlog_remove(fscache_t * fscp,cnode_t * pcp,char * nm,cnode_t * cp,cred_t * cr)7980Sstevel@tonic-gate cachefs_dlog_remove(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
7990Sstevel@tonic-gate     cred_t *cr)
8000Sstevel@tonic-gate {
8010Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
8020Sstevel@tonic-gate 	struct cfs_dlog_remove *up;
8030Sstevel@tonic-gate 	size_t len;
8040Sstevel@tonic-gate 	caddr_t curp;
8050Sstevel@tonic-gate 	off_t offset;
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
8100Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_REMOVE;
8110Sstevel@tonic-gate 	up = &entp->dl_u.dl_remove;
8120Sstevel@tonic-gate 	up->dl_parent_cid = pcp->c_id;
8130Sstevel@tonic-gate 	up->dl_child_cid = cp->c_id;
8140Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
8150Sstevel@tonic-gate 		&up->dl_times.tm_mtime, "cachefs_dlog_remove: ", "mtime");
8160Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
8170Sstevel@tonic-gate 		&up->dl_times.tm_ctime, "cachefs_dlog_remove: ", "ctime");
8180Sstevel@tonic-gate 	/* store the cred info */
8190Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
8200Sstevel@tonic-gate 
8210Sstevel@tonic-gate 	/* find the address in buffer past where the creds are stored */
8220Sstevel@tonic-gate 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
8230Sstevel@tonic-gate 
8240Sstevel@tonic-gate 	/* store the removed name */
8250Sstevel@tonic-gate 	len = strlen(nm) + 1;
8260Sstevel@tonic-gate 	bcopy(nm, curp, len);
8270Sstevel@tonic-gate 
8280Sstevel@tonic-gate 	/* calculate the length of this record */
8290Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
8300Sstevel@tonic-gate 
8310Sstevel@tonic-gate 	/* write the record in the log */
8320Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
8350Sstevel@tonic-gate 	return (offset);
8360Sstevel@tonic-gate }
8370Sstevel@tonic-gate 
8380Sstevel@tonic-gate off_t
cachefs_dlog_link(fscache_t * fscp,cnode_t * pcp,char * nm,cnode_t * cp,cred_t * cr)8390Sstevel@tonic-gate cachefs_dlog_link(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
8400Sstevel@tonic-gate     cred_t *cr)
8410Sstevel@tonic-gate {
8420Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
8430Sstevel@tonic-gate 	struct cfs_dlog_link *up;
8440Sstevel@tonic-gate 	size_t len;
8450Sstevel@tonic-gate 	caddr_t curp;
8460Sstevel@tonic-gate 	off_t offset;
8470Sstevel@tonic-gate 
8480Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
8490Sstevel@tonic-gate 
8500Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
8510Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_LINK;
8520Sstevel@tonic-gate 	up = &entp->dl_u.dl_link;
8530Sstevel@tonic-gate 	up->dl_parent_cid = pcp->c_id;
8540Sstevel@tonic-gate 	up->dl_child_cid = cp->c_id;
8550Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
8560Sstevel@tonic-gate 		&up->dl_times.tm_mtime, "cachefs_dlog_link: ", "mtime");
8570Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
8580Sstevel@tonic-gate 		&up->dl_times.tm_ctime, "cachefs_dlog_link: ", "ctime");
8590Sstevel@tonic-gate 
8600Sstevel@tonic-gate 	/* store the cred info */
8610Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
8620Sstevel@tonic-gate 
8630Sstevel@tonic-gate 	/* find the address in buffer past where the creds are stored */
8640Sstevel@tonic-gate 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 	/* store the link name */
8670Sstevel@tonic-gate 	len = strlen(nm) + 1;
8680Sstevel@tonic-gate 	bcopy(nm, curp, len);
8690Sstevel@tonic-gate 
8700Sstevel@tonic-gate 	/* calculate the length of this record */
8710Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate 	/* write the record in the log */
8740Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
8750Sstevel@tonic-gate 
8760Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
8770Sstevel@tonic-gate 	return (offset);
8780Sstevel@tonic-gate }
8790Sstevel@tonic-gate 
8800Sstevel@tonic-gate off_t
cachefs_dlog_rename(fscache_t * fscp,cnode_t * odcp,char * onm,cnode_t * ndcp,char * nnm,cred_t * cr,cnode_t * cp,cnode_t * delcp)8810Sstevel@tonic-gate cachefs_dlog_rename(fscache_t *fscp, cnode_t *odcp, char *onm, cnode_t *ndcp,
8820Sstevel@tonic-gate     char *nnm, cred_t *cr, cnode_t *cp, cnode_t *delcp)
8830Sstevel@tonic-gate {
8840Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
8850Sstevel@tonic-gate 	struct cfs_dlog_rename *up;
8860Sstevel@tonic-gate 	size_t len;
8870Sstevel@tonic-gate 	caddr_t curp;
8880Sstevel@tonic-gate 	off_t offset;
8890Sstevel@tonic-gate 
8900Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
8910Sstevel@tonic-gate 
8920Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
8930Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_RENAME;
8940Sstevel@tonic-gate 	up = &entp->dl_u.dl_rename;
8950Sstevel@tonic-gate 	up->dl_oparent_cid = odcp->c_id;
8960Sstevel@tonic-gate 	up->dl_nparent_cid = ndcp->c_id;
8970Sstevel@tonic-gate 	up->dl_child_cid = cp->c_id;
8980Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
8990Sstevel@tonic-gate 		&up->dl_times.tm_mtime, "cachefs_dlog_rename: ", "mtime");
9000Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
9010Sstevel@tonic-gate 		&up->dl_times.tm_ctime, "cachefs_dlog_rename: ", "ctime");
9020Sstevel@tonic-gate 	if (delcp) {
9030Sstevel@tonic-gate 		up->dl_del_cid = delcp->c_id;
9040Sstevel@tonic-gate 		CACHEFS_DLOG_TS_COPY(&delcp->c_metadata.md_vattr.va_mtime,
9050Sstevel@tonic-gate 			&up->dl_del_times.tm_mtime,
9060Sstevel@tonic-gate 			"cachefs_dlog_rename: ", "del mtime");
9070Sstevel@tonic-gate 		CACHEFS_DLOG_TS_COPY(&delcp->c_metadata.md_vattr.va_ctime,
9080Sstevel@tonic-gate 			&up->dl_del_times.tm_ctime,
9090Sstevel@tonic-gate 			"cachefs_dlog_rename: ", "del ctime");
9100Sstevel@tonic-gate 	} else {
9110Sstevel@tonic-gate 		up->dl_del_cid.cid_fileno = 0;
9120Sstevel@tonic-gate 		up->dl_del_cid.cid_flags = 0;
9130Sstevel@tonic-gate 		up->dl_del_times.tm_mtime.tv_sec = 0;
9140Sstevel@tonic-gate 		up->dl_del_times.tm_mtime.tv_nsec = 0;
9150Sstevel@tonic-gate 		up->dl_del_times.tm_ctime.tv_sec = 0;
9160Sstevel@tonic-gate 		up->dl_del_times.tm_ctime.tv_nsec = 0;
9170Sstevel@tonic-gate 	}
9180Sstevel@tonic-gate 
9190Sstevel@tonic-gate 	/* store the cred info */
9200Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
9210Sstevel@tonic-gate 
9220Sstevel@tonic-gate 	/* find the address in buffer past where the creds are stored */
9230Sstevel@tonic-gate 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
9240Sstevel@tonic-gate 
9250Sstevel@tonic-gate 	/* store the old name */
9260Sstevel@tonic-gate 	len = strlen(onm) + 1;
9270Sstevel@tonic-gate 	bcopy(onm, curp, len);
9280Sstevel@tonic-gate 
9290Sstevel@tonic-gate 	/* store the new name */
9300Sstevel@tonic-gate 	curp += len;
9310Sstevel@tonic-gate 	len = strlen(nnm) + 1;
9320Sstevel@tonic-gate 	bcopy(nnm, curp, len);
9330Sstevel@tonic-gate 
9340Sstevel@tonic-gate 	/* calculate the length of this record */
9350Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
9360Sstevel@tonic-gate 
9370Sstevel@tonic-gate 	/* write the record in the log */
9380Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
9390Sstevel@tonic-gate 
9400Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
9410Sstevel@tonic-gate 	return (offset);
9420Sstevel@tonic-gate }
9430Sstevel@tonic-gate 
9440Sstevel@tonic-gate off_t
cachefs_dlog_mkdir(fscache_t * fscp,cnode_t * pcp,cnode_t * cp,char * nm,vattr_t * vap,cred_t * cr)9450Sstevel@tonic-gate cachefs_dlog_mkdir(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *nm,
9460Sstevel@tonic-gate     vattr_t *vap, cred_t *cr)
9470Sstevel@tonic-gate {
9480Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
9490Sstevel@tonic-gate 	struct cfs_dlog_mkdir *up;
9500Sstevel@tonic-gate 	size_t len;
9510Sstevel@tonic-gate 	caddr_t curp;
9520Sstevel@tonic-gate 	off_t offset;
9530Sstevel@tonic-gate 
9540Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
9550Sstevel@tonic-gate 
9560Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
9570Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_MKDIR;
9580Sstevel@tonic-gate 	up = &entp->dl_u.dl_mkdir;
9590Sstevel@tonic-gate 	up->dl_parent_cid = pcp->c_id;
9600Sstevel@tonic-gate 	up->dl_child_cid = cp->c_id;
9610Sstevel@tonic-gate 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
9620Sstevel@tonic-gate 		"cachefs_dlog_mkdir: dl_attr");
9630Sstevel@tonic-gate 	bzero(&up->dl_fid, sizeof (up->dl_fid));
9640Sstevel@tonic-gate 
9650Sstevel@tonic-gate 	/* store the cred info */
9660Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
9670Sstevel@tonic-gate 
9680Sstevel@tonic-gate 	/* find the address in buffer past where the creds are stored */
9690Sstevel@tonic-gate 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
9700Sstevel@tonic-gate 
9710Sstevel@tonic-gate 	/* store the new directory name */
9720Sstevel@tonic-gate 	len = strlen(nm) + 1;
9730Sstevel@tonic-gate 	bcopy(nm, curp, len);
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate 	/* calculate the length of this record */
9760Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 	/* write the record in the dlog */
9790Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
9800Sstevel@tonic-gate 
9810Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
9820Sstevel@tonic-gate 	return (offset);
9830Sstevel@tonic-gate }
9840Sstevel@tonic-gate 
9850Sstevel@tonic-gate off_t
cachefs_dlog_rmdir(fscache_t * fscp,cnode_t * pcp,char * nm,cnode_t * cp,cred_t * cr)9860Sstevel@tonic-gate cachefs_dlog_rmdir(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
9870Sstevel@tonic-gate     cred_t *cr)
9880Sstevel@tonic-gate {
9890Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
9900Sstevel@tonic-gate 	struct cfs_dlog_rmdir *up;
9910Sstevel@tonic-gate 	size_t len;
9920Sstevel@tonic-gate 	caddr_t curp;
9930Sstevel@tonic-gate 	off_t offset;
9940Sstevel@tonic-gate 
9950Sstevel@tonic-gate 	/* if not a local dir, log the cid to fid mapping */
9960Sstevel@tonic-gate 	if ((cp->c_id.cid_flags & CFS_CID_LOCAL) == 0) {
9970Sstevel@tonic-gate 		if (cachefs_dlog_mapfid(fscp, cp))
9980Sstevel@tonic-gate 			return (0);
9990Sstevel@tonic-gate 		if (cachefs_dlog_cidmap(fscp))
10000Sstevel@tonic-gate 			return (0);
10010Sstevel@tonic-gate 	}
10020Sstevel@tonic-gate 
10030Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
10040Sstevel@tonic-gate 
10050Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
10060Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_RMDIR;
10070Sstevel@tonic-gate 	up = &entp->dl_u.dl_rmdir;
10080Sstevel@tonic-gate 	up->dl_parent_cid = pcp->c_id;
10090Sstevel@tonic-gate 
10100Sstevel@tonic-gate 	/* store the cred info */
10110Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
10120Sstevel@tonic-gate 
10130Sstevel@tonic-gate 	/* find the address in buffer past where the creds are stored */
10140Sstevel@tonic-gate 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate 	/* store the created name */
10170Sstevel@tonic-gate 	len = strlen(nm) + 1;
10180Sstevel@tonic-gate 	bcopy(nm, curp, len);
10190Sstevel@tonic-gate 
10200Sstevel@tonic-gate 	/* calculate the length of this record */
10210Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
10220Sstevel@tonic-gate 
10230Sstevel@tonic-gate 	/* write the record in the log */
10240Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
10250Sstevel@tonic-gate 
10260Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
10270Sstevel@tonic-gate 	return (offset);
10280Sstevel@tonic-gate }
10290Sstevel@tonic-gate 
10300Sstevel@tonic-gate off_t
cachefs_dlog_symlink(fscache_t * fscp,cnode_t * pcp,cnode_t * cp,char * lnm,vattr_t * vap,char * tnm,cred_t * cr)10310Sstevel@tonic-gate cachefs_dlog_symlink(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *lnm,
10320Sstevel@tonic-gate     vattr_t *vap, char *tnm, cred_t *cr)
10330Sstevel@tonic-gate {
10340Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
10350Sstevel@tonic-gate 	struct cfs_dlog_symlink *up;
10360Sstevel@tonic-gate 	size_t len;
10370Sstevel@tonic-gate 	caddr_t curp;
10380Sstevel@tonic-gate 	off_t offset;
10390Sstevel@tonic-gate 
10400Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&cp->c_statelock));
10410Sstevel@tonic-gate 
10420Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
10430Sstevel@tonic-gate 
10440Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
10450Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_SYMLINK;
10460Sstevel@tonic-gate 	up = &entp->dl_u.dl_symlink;
10470Sstevel@tonic-gate 	up->dl_parent_cid = pcp->c_id;
10480Sstevel@tonic-gate 	up->dl_child_cid = cp->c_id;
10490Sstevel@tonic-gate 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
10500Sstevel@tonic-gate 		"cachefs_dlog_symlink: dl_attr");
10510Sstevel@tonic-gate 	up->dl_times.tm_ctime.tv_sec = 0;
10520Sstevel@tonic-gate 	up->dl_times.tm_ctime.tv_nsec = 0;
10530Sstevel@tonic-gate 	up->dl_times.tm_mtime.tv_sec = 0;
10540Sstevel@tonic-gate 	up->dl_times.tm_mtime.tv_nsec = 0;
10550Sstevel@tonic-gate 	bzero(&up->dl_fid, sizeof (up->dl_fid));
10560Sstevel@tonic-gate 
10570Sstevel@tonic-gate 	/* store the cred info */
10580Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
10590Sstevel@tonic-gate 
10600Sstevel@tonic-gate 	/* find the address in buffer past where the creds are stored */
10610Sstevel@tonic-gate 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
10620Sstevel@tonic-gate 
10630Sstevel@tonic-gate 	/* store the link name */
10640Sstevel@tonic-gate 	len = strlen(lnm) + 1;
10650Sstevel@tonic-gate 	bcopy(lnm, curp, len);
10660Sstevel@tonic-gate 
10670Sstevel@tonic-gate 	/* store new name */
10680Sstevel@tonic-gate 	curp += len;
10690Sstevel@tonic-gate 	len = strlen(tnm) + 1;
10700Sstevel@tonic-gate 	bcopy(tnm, curp, len);
10710Sstevel@tonic-gate 
10720Sstevel@tonic-gate 	/* calculate the length of this record */
10730Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
10740Sstevel@tonic-gate 
10750Sstevel@tonic-gate 	/* write the record in the log */
10760Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
10770Sstevel@tonic-gate 
10780Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
10790Sstevel@tonic-gate 	return (offset);
10800Sstevel@tonic-gate }
10810Sstevel@tonic-gate 
10820Sstevel@tonic-gate off_t
cachefs_dlog_modify(fscache_t * fscp,cnode_t * cp,cred_t * cr,uint_t * seqp)10830Sstevel@tonic-gate cachefs_dlog_modify(fscache_t *fscp, cnode_t *cp, cred_t *cr, uint_t *seqp)
10840Sstevel@tonic-gate {
10850Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
10860Sstevel@tonic-gate 	struct cfs_dlog_modify *up;
10870Sstevel@tonic-gate 	off_t offset;
10880Sstevel@tonic-gate 	uint_t seq;
10890Sstevel@tonic-gate 	size_t len;
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
10920Sstevel@tonic-gate 
10930Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
10940Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_MODIFIED;
10950Sstevel@tonic-gate 	up = &entp->dl_u.dl_modify;
10960Sstevel@tonic-gate 	up->dl_cid = cp->c_id;
10970Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
10980Sstevel@tonic-gate 		&up->dl_times.tm_mtime,
10990Sstevel@tonic-gate 		"cachefs_dlog_modify: ", "mtime");
11000Sstevel@tonic-gate 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
11010Sstevel@tonic-gate 		&up->dl_times.tm_ctime,
11020Sstevel@tonic-gate 		"cachefs_dlog_modify: ", "ctime");
11030Sstevel@tonic-gate 
11040Sstevel@tonic-gate 	up->dl_next = 0;
11050Sstevel@tonic-gate 
11060Sstevel@tonic-gate 	/* store the cred info */
11070Sstevel@tonic-gate 	len = copy_cred(cr, &up->dl_cred);
11080Sstevel@tonic-gate 
11090Sstevel@tonic-gate 	/* calculate the length of this record */
11100Sstevel@tonic-gate 	entp->dl_len = (int)(((uintptr_t)&up->dl_cred + len) - (uintptr_t)entp);
11110Sstevel@tonic-gate 
11120Sstevel@tonic-gate 	/* write the record in the log */
11130Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, &seq);
11140Sstevel@tonic-gate 
11150Sstevel@tonic-gate 	/* return sequence number */
11160Sstevel@tonic-gate 	*seqp = seq;
11170Sstevel@tonic-gate 
11180Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
11190Sstevel@tonic-gate 	return (offset);
11200Sstevel@tonic-gate }
11210Sstevel@tonic-gate 
11220Sstevel@tonic-gate int
cachefs_dlog_mapfid(fscache_t * fscp,cnode_t * cp)11230Sstevel@tonic-gate cachefs_dlog_mapfid(fscache_t *fscp, cnode_t *cp)
11240Sstevel@tonic-gate {
11250Sstevel@tonic-gate 	struct cfs_dlog_entry *entp;
11260Sstevel@tonic-gate 	struct cfs_dlog_mapfid *up;
11270Sstevel@tonic-gate 	off_t offset;
11280Sstevel@tonic-gate 
11290Sstevel@tonic-gate 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
11300Sstevel@tonic-gate 
11310Sstevel@tonic-gate 	entp->dl_valid = CFS_DLOG_VAL_COMMITTED;
11320Sstevel@tonic-gate 	entp->dl_op = CFS_DLOG_MAPFID;
11330Sstevel@tonic-gate 	up = &entp->dl_u.dl_mapfid;
11340Sstevel@tonic-gate 	up->dl_cid = cp->c_id;
11350Sstevel@tonic-gate 	CACHEFS_FID_COPY(&cp->c_cookie, &up->dl_fid);
11360Sstevel@tonic-gate 
11370Sstevel@tonic-gate 	/* calculate the length of this record */
11380Sstevel@tonic-gate 	/* entp->dl_len = ((caddr_t)up - (caddr_t)entp + sizeof (*up)); */
11390Sstevel@tonic-gate 	entp->dl_len = (int)(offsetof(struct cfs_dlog_entry, dl_u.dl_mapfid) +
11400Sstevel@tonic-gate 				sizeof (struct cfs_dlog_mapfid));
11410Sstevel@tonic-gate 
11420Sstevel@tonic-gate 	/* write the record in the log */
11430Sstevel@tonic-gate 	offset = cachefs_dlog_output(fscp, entp, NULL);
11440Sstevel@tonic-gate 
11450Sstevel@tonic-gate 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
11460Sstevel@tonic-gate 	return (offset == 0);
11470Sstevel@tonic-gate }
11480Sstevel@tonic-gate 
11490Sstevel@tonic-gate /* Returns the next sequence number, 0 if an error */
11500Sstevel@tonic-gate uint_t
cachefs_dlog_seqnext(fscache_t * fscp)11510Sstevel@tonic-gate cachefs_dlog_seqnext(fscache_t *fscp)
11520Sstevel@tonic-gate {
11530Sstevel@tonic-gate 	int error;
11540Sstevel@tonic-gate 	uint_t seq;
11550Sstevel@tonic-gate 
11560Sstevel@tonic-gate 	if (fscp->fs_dlogfile == NULL) {
11570Sstevel@tonic-gate 		error = cachefs_dlog_setup(fscp, 1);
11580Sstevel@tonic-gate 		if (error)
11590Sstevel@tonic-gate 			return (0);
11600Sstevel@tonic-gate 	}
11610Sstevel@tonic-gate 
11620Sstevel@tonic-gate 	mutex_enter(&fscp->fs_dlock);
11630Sstevel@tonic-gate 	ASSERT(fscp->fs_dlogfile);
11640Sstevel@tonic-gate 
11650Sstevel@tonic-gate 	/* get a sequence number for this log entry */
11660Sstevel@tonic-gate 	seq = fscp->fs_dlogseq + 1;
11670Sstevel@tonic-gate 	if (seq != 0) {
11680Sstevel@tonic-gate 		fscp->fs_dlogseq++;
11690Sstevel@tonic-gate 	}
11700Sstevel@tonic-gate #ifdef CFSDEBUG
11710Sstevel@tonic-gate 	else {
11720Sstevel@tonic-gate 		cmn_err(CE_WARN, "cachefs: logging failed, seq overflow 2.");
11730Sstevel@tonic-gate 	}
11740Sstevel@tonic-gate #endif
11750Sstevel@tonic-gate 	mutex_exit(&fscp->fs_dlock);
11760Sstevel@tonic-gate 	return (seq);
11770Sstevel@tonic-gate }
1178