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