xref: /titanic_41/usr/src/uts/common/fs/cachefs/cachefs_dlog.c (revision 0c79d02b29618f74322989ec8ceafaa5486ac1db)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/param.h>
29 #include <sys/types.h>
30 #include <sys/systm.h>
31 #include <sys/cred.h>
32 #include <sys/proc.h>
33 #include <sys/user.h>
34 #include <sys/time.h>
35 #include <sys/vnode.h>
36 #include <sys/vfs.h>
37 #include <sys/file.h>
38 #include <sys/filio.h>
39 #include <sys/uio.h>
40 #include <sys/buf.h>
41 #include <sys/mman.h>
42 #include <sys/tiuser.h>
43 #include <sys/pathname.h>
44 #include <sys/dirent.h>
45 #include <sys/conf.h>
46 #include <sys/debug.h>
47 #include <sys/vmsystm.h>
48 #include <sys/fcntl.h>
49 #include <sys/flock.h>
50 #include <sys/swap.h>
51 #include <sys/errno.h>
52 #include <sys/sysmacros.h>
53 #include <sys/disp.h>
54 #include <sys/kmem.h>
55 #include <sys/cmn_err.h>
56 #include <sys/vtrace.h>
57 #include <sys/mount.h>
58 #include <sys/bootconf.h>
59 #include <sys/dnlc.h>
60 #include <sys/stat.h>
61 
62 #include <vm/hat.h>
63 #include <vm/as.h>
64 #include <vm/page.h>
65 #include <vm/pvn.h>
66 #include <vm/seg.h>
67 #include <vm/seg_map.h>
68 #include <vm/seg_vn.h>
69 #include <vm/rm.h>
70 #include <sys/fs/cachefs_fs.h>
71 #include <sys/fs/cachefs_dlog.h>
72 #include <fs/fs_subr.h>
73 
74 static int cachefs_dlog_mapreserve(fscache_t *fscp, int size);
75 
76 #ifdef _LP64
77 
78 static void cachefs_dlog_attrchk(vattr_t *vap, char *funcname);
79 
80 #define	CACHEFS_DLOG_TS_COPY(in_tsp, out_tsp, str, str1)		\
81 	{								\
82 		int	ovferr = 0;					\
83 		CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, ovferr);	\
84 		if (ovferr)						\
85 			cmn_err(CE_WARN, "%s%s overflow", str, str1);	\
86 	}
87 
88 #define	CACHEFS_DLOG_DEV_COPY(in_dev, out_dev, str, str1)		\
89 	{								\
90 		int	ovferr = 0;					\
91 		CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, ovferr);	\
92 		if (ovferr)						\
93 			cmn_err(CE_WARN, "%s%s 0x%lx -> 0x%x overflow",	\
94 				str, str1, in_dev, (dev32_t)(out_dev));	\
95 	}
96 
97 #define	CACHEFS_DLOG_VATTR_COPY(in_vap, out_vap, str)			\
98 	{								\
99 		int	ovferr = 0;					\
100 		CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vap, out_vap, ovferr); \
101 		if (ovferr)						\
102 			cachefs_dlog_attrchk(in_vap, str);		\
103 	}
104 
105 /*
106  * check attr error - if we get an overflow error copying vattr, make sure
107  * the field affected is actually wanted, or it might be junk
108  */
109 static void
110 cachefs_dlog_attrchk(vattr_t *vap, char *str)
111 {
112 	dev_t		tmpdev;
113 	cfs_timestruc_t	ts;
114 
115 	if (vap->va_mask & AT_FSID) {
116 		CACHEFS_DLOG_DEV_COPY(vap->va_fsid, tmpdev, str, ".va_fsid");
117 	}
118 	if (vap->va_mask & AT_RDEV) {
119 		CACHEFS_DLOG_DEV_COPY(vap->va_rdev, tmpdev, str, ".va_rdev");
120 	}
121 	if (vap->va_mask & AT_MTIME) {
122 		CACHEFS_DLOG_TS_COPY(&vap->va_mtime, &ts, str, ".va_mtime");
123 	}
124 	if (vap->va_mask & AT_ATIME) {
125 		CACHEFS_DLOG_TS_COPY(&vap->va_atime, &ts, str, ".va_atime");
126 	}
127 	if (vap->va_mask & AT_CTIME) {
128 		CACHEFS_DLOG_TS_COPY(&vap->va_ctime, &ts, str, ".va_ctime");
129 	}
130 }
131 
132 #else /* not _LP64 */
133 
134 #define	CACHEFS_DLOG_TS_COPY(in_tsp, out_tsp, str, str1)		\
135 	CACHEFS_TS_TO_CFS_TS_COPY(in_tsp, out_tsp, error)
136 
137 #define	CACHEFS_DLOG_DEV_COPY(in_dev, out_dev, str, str1)		\
138 	CACHEFS_DEV_TO_CFS_DEV_COPY(in_dev, out_dev, error)
139 
140 #define	CACHEFS_DLOG_VATTR_COPY(in_vap, out_vap, str)			\
141 	CACHEFS_VATTR_TO_CFS_VATTR_COPY(in_vap, out_vap, error)
142 
143 #endif /* _LP64 */
144 
145 /*
146  *
147  * Cachefs used to know too much about how creds looked; since it's
148  * committed to persistent storage, we can't change the layout so
149  * it now has a "dl_cred_t" which (unsurprisingly) looks exactly like
150  * an old credential.
151  *
152  * The dst argument needs to point to:
153  *		struct dl_cred_t;
154  *		<buffer space>			buffer for groups
155  *
156  * The source is a proper kernel cred_t.
157  *
158  */
159 static size_t
160 copy_cred(cred_t *src, dl_cred_t *dst)
161 {
162 	int n;
163 	const gid_t *sgrp = crgetgroups(src);
164 
165 	n = MIN(NGROUPS_MAX_DEFAULT, crgetngroups(src));
166 
167 	/* copy the fixed fields */
168 	dst->cr_uid = crgetuid(src);
169 	dst->cr_ruid = crgetruid(src);
170 	dst->cr_suid = crgetsuid(src);
171 	dst->cr_gid = crgetgid(src);
172 	dst->cr_rgid = crgetrgid(src);
173 	dst->cr_sgid = crgetsgid(src);
174 	dst->cr_groups[0] = sgrp[0];
175 
176 	dst->cr_ngroups = n;
177 	bcopy(sgrp, (void *)(dst + 1), (n - 1) * sizeof (gid_t));
178 	return (sizeof (dl_cred_t) + (n - 1) * sizeof (gid_t));
179 }
180 
181 /*
182  * Sets up for writing to the log files.
183  */
184 int
185 cachefs_dlog_setup(fscache_t *fscp, int createfile)
186 {
187 	struct vattr vattr;
188 	int error = 0;
189 	int createdone = 0;
190 	int lookupdone = 0;
191 	int version = CFS_DLOG_VERSION;
192 	off_t offset;
193 	struct cfs_dlog_trailer trailer;
194 
195 	mutex_enter(&fscp->fs_dlock);
196 
197 	/* all done if the log files already exist */
198 	if (fscp->fs_dlogfile) {
199 		ASSERT(fscp->fs_dmapfile);
200 		goto out;
201 	}
202 
203 	/* see if the log file exists */
204 	error = VOP_LOOKUP(fscp->fs_fscdirvp, CACHEFS_DLOG_FILE,
205 	    &fscp->fs_dlogfile, NULL, 0, NULL, kcred, NULL, NULL, NULL);
206 	if (error && (createfile == 0))
207 		goto out;
208 
209 	/* if the lookup failed then create file log files */
210 	if (error) {
211 		createdone++;
212 
213 		vattr.va_mode = S_IFREG | 0666;
214 		vattr.va_uid = 0;
215 		vattr.va_gid = 0;
216 		vattr.va_type = VREG;
217 		vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
218 		error = VOP_CREATE(fscp->fs_fscdirvp, CACHEFS_DLOG_FILE,
219 		    &vattr, 0, 0666, &fscp->fs_dlogfile, kcred, 0, NULL, NULL);
220 		if (error) {
221 #ifdef CFSDEBUG
222 			CFS_DEBUG(CFSDEBUG_DLOG)
223 				printf("cachefs: log file create fail %d\n",
224 				    error);
225 #endif
226 			goto out;
227 		}
228 
229 		/* write the version number into the log file */
230 		error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile, (caddr_t)&version,
231 		    sizeof (version), (offset_t)0, UIO_SYSSPACE, FSYNC,
232 		    RLIM_INFINITY, kcred, NULL);
233 		if (error) {
234 #ifdef CFSDEBUG
235 			CFS_DEBUG(CFSDEBUG_DLOG)
236 				printf("cachefs: log file init fail %d\n",
237 				    error);
238 #endif
239 			goto out;
240 		}
241 
242 		vattr.va_mode = S_IFREG | 0666;
243 		vattr.va_uid = 0;
244 		vattr.va_gid = 0;
245 		vattr.va_type = VREG;
246 		vattr.va_mask = AT_TYPE|AT_MODE|AT_UID|AT_GID;
247 		error = VOP_CREATE(fscp->fs_fscdirvp, CACHEFS_DMAP_FILE,
248 		    &vattr, 0, 0666, &fscp->fs_dmapfile, kcred, 0, NULL, NULL);
249 		if (error) {
250 #ifdef CFSDEBUG
251 			CFS_DEBUG(CFSDEBUG_DLOG)
252 				printf("cachefs: map file create fail %d\n",
253 				    error);
254 #endif
255 			goto out;
256 		}
257 
258 		fscp->fs_dlogoff = sizeof (version);
259 		fscp->fs_dlogseq = 0;
260 		fscp->fs_dmapoff = 0;
261 		fscp->fs_dmapsize = 0;
262 	}
263 
264 	/*
265 	 * Else the lookup succeeded.
266 	 * Before mounting, fsck should have fixed any problems
267 	 * in the log file.
268 	 */
269 	else {
270 		lookupdone++;
271 
272 		/* find the end of the log file */
273 		vattr.va_mask = AT_ALL;
274 		error = VOP_GETATTR(fscp->fs_dlogfile, &vattr, 0, kcred, NULL);
275 		if (error) {
276 #ifdef CFSDEBUG
277 			CFS_DEBUG(CFSDEBUG_DLOG)
278 				printf("cachefs: log file getattr fail %d\n",
279 				    error);
280 #endif
281 			goto out;
282 		}
283 		/*LINTED alignment okay*/
284 		ASSERT(vattr.va_size <= MAXOFF_T);
285 		fscp->fs_dlogoff = (off_t)vattr.va_size;
286 
287 		offset = vattr.va_size - sizeof (struct cfs_dlog_trailer);
288 		/*
289 		 * The last record in the dlog file is a trailer record
290 		 * that contains the last sequence number used. This is
291 		 * used to reset the sequence number when a logfile already
292 		 * exists.
293 		 */
294 		error = vn_rdwr(UIO_READ, fscp->fs_dlogfile, (caddr_t)&trailer,
295 		    sizeof (struct cfs_dlog_trailer), (offset_t)offset,
296 		    UIO_SYSSPACE, FSYNC, RLIM_INFINITY, kcred, NULL);
297 		if (error == 0) {
298 			if (trailer.dl_op == CFS_DLOG_TRAILER) {
299 				fscp->fs_dlogseq = trailer.dl_seq;
300 				/*
301 				 * Set the offset of the next record to be
302 				 * written, to over write the current
303 				 * trailer.
304 				 */
305 				fscp->fs_dlogoff = offset;
306 			} else {
307 #ifdef CFSDEBUG
308 				CFS_DEBUG(CFSDEBUG_DLOG) {
309 					cmn_err(CE_WARN,
310 					    "cachefs: can't find dlog trailer");
311 					cmn_err(CE_WARN,
312 					    "cachefs: fsck required");
313 				}
314 #endif /* CFSDEBUG */
315 				/*LINTED alignment okay*/
316 				fscp->fs_dlogseq = (uint_t)vattr.va_size;
317 			}
318 		} else {
319 #ifdef CFSDEBUG
320 			CFS_DEBUG(CFSDEBUG_DLOG)
321 				cmn_err(CE_WARN,
322 				    "cachefs: error reading dlog trailer");
323 #endif /* CFSDEBUG */
324 			/*LINTED alignment okay*/
325 			fscp->fs_dlogseq = (uint_t)vattr.va_size;
326 		}
327 
328 
329 		error = VOP_LOOKUP(fscp->fs_fscdirvp, CACHEFS_DMAP_FILE,
330 		    &fscp->fs_dmapfile, NULL, 0, NULL, kcred, NULL, NULL, NULL);
331 		if (error) {
332 #ifdef CFSDEBUG
333 			CFS_DEBUG(CFSDEBUG_DLOG)
334 				printf("cachefs: map file lookup fail %d\n",
335 				    error);
336 #endif
337 			goto out;
338 		}
339 
340 		vattr.va_mask = AT_ALL;
341 		error = VOP_GETATTR(fscp->fs_dmapfile, &vattr, 0, kcred, NULL);
342 		if (error) {
343 #ifdef CFSDEBUG
344 			CFS_DEBUG(CFSDEBUG_DLOG)
345 				printf("cachefs: map file getattr fail %d\n",
346 				    error);
347 #endif
348 			goto out;
349 		}
350 		fscp->fs_dmapoff = (off_t)vattr.va_size;
351 		fscp->fs_dmapsize = (off_t)vattr.va_size;
352 	}
353 
354 out:
355 	if (error) {
356 		if (createdone) {
357 			if (fscp->fs_dlogfile) {
358 				VN_RELE(fscp->fs_dlogfile);
359 				fscp->fs_dlogfile = NULL;
360 				(void) VOP_REMOVE(fscp->fs_fscdirvp,
361 				    CACHEFS_DLOG_FILE, kcred, NULL, 0);
362 			}
363 			if (fscp->fs_dmapfile) {
364 				VN_RELE(fscp->fs_dmapfile);
365 				fscp->fs_dmapfile = NULL;
366 				(void) VOP_REMOVE(fscp->fs_fscdirvp,
367 				    CACHEFS_DMAP_FILE, kcred, NULL, 0);
368 			}
369 		}
370 		if (lookupdone) {
371 			if (fscp->fs_dlogfile) {
372 				VN_RELE(fscp->fs_dlogfile);
373 				fscp->fs_dlogfile = NULL;
374 			}
375 			if (fscp->fs_dmapfile) {
376 				VN_RELE(fscp->fs_dmapfile);
377 				fscp->fs_dmapfile = NULL;
378 			}
379 		}
380 	}
381 
382 	mutex_exit(&fscp->fs_dlock);
383 	return (error);
384 }
385 
386 /*
387  * Drops reference to the log file.
388  */
389 void
390 cachefs_dlog_teardown(fscache_t *fscp)
391 {
392 	vattr_t va;
393 	/*LINTED: set but not used */
394 	int error;
395 
396 	mutex_enter(&fscp->fs_dlock);
397 
398 	/* clean up the log file */
399 	if (fscp->fs_dlogfile) {
400 		VN_RELE(fscp->fs_dlogfile);
401 		fscp->fs_dlogfile = NULL;
402 	}
403 
404 	/* clean up the map file */
405 	if (fscp->fs_dmapfile) {
406 		/* set the map file to the actual size needed */
407 		va.va_mask = AT_SIZE;
408 		va.va_size = fscp->fs_dmapoff;
409 		error = VOP_SETATTR(fscp->fs_dmapfile, &va, 0, kcred, NULL);
410 #ifdef CFSDEBUG
411 		if (error) {
412 			cmn_err(CE_WARN, "cachefs: map setattr failed %d",
413 			    error);
414 		}
415 #endif
416 		VN_RELE(fscp->fs_dmapfile);
417 		fscp->fs_dmapfile = NULL;
418 	}
419 	mutex_exit(&fscp->fs_dlock);
420 }
421 
422 /*
423  * Outputs a dlog message to the log file.
424  */
425 static off_t
426 cachefs_dlog_output(fscache_t *fscp, cfs_dlog_entry_t *entp, uint_t *seqp)
427 {
428 	int error;
429 	off_t offset;
430 	int xx;
431 	uint_t seq;
432 	int len;
433 	struct cfs_dlog_trailer *trail;
434 
435 	ASSERT(entp->dl_len <= CFS_DLOG_ENTRY_MAXSIZE);
436 
437 	if (fscp->fs_dlogfile == NULL) {
438 		error = cachefs_dlog_setup(fscp, 1);
439 		if (error) {
440 			offset = 0;
441 			goto out;
442 		}
443 	}
444 
445 	/* round up length to a 4 byte boundary */
446 	len = entp->dl_len;
447 	xx = len & 0x03;
448 	if (xx) {
449 		xx = 4 - xx;
450 		bzero((void *)((uintptr_t)entp + len), (size_t)xx);
451 		len += xx;
452 		entp->dl_len = len;
453 	}
454 
455 	/* XXX turn this on/off in sync with code in cachefs_dlog_setsecattr */
456 #if 0
457 	/* XXX debugging hack, round up to 16 byte boundary */
458 	len = entp->dl_len;
459 	xx = 16 - (len & 0x0f);
460 	bcopy("UUUUUUUUUUUUUUUU", (void *)((uintptr_t)entp + len), (size_t)xx);
461 	len += xx;
462 	entp->dl_len = len;
463 #endif
464 
465 	/*
466 	 * All functions which allocate a dlog entry buffer must be sure
467 	 * to allocate space for the trailer record. The trailer record,
468 	 * is always located at the end of the log file. It contains the
469 	 * highest sequence number used. This allows cachefs_dlog_setup()
470 	 * to reset the sequence numbers properly when the log file
471 	 * already exists.
472 	 */
473 	trail = (struct cfs_dlog_trailer *)((uintptr_t)entp + entp->dl_len);
474 	trail->dl_len = sizeof (struct cfs_dlog_trailer);
475 	trail->dl_op = CFS_DLOG_TRAILER;
476 	trail->dl_valid = CFS_DLOG_VAL_COMMITTED;
477 	mutex_enter(&fscp->fs_dlock);
478 	ASSERT(fscp->fs_dlogfile);
479 
480 	/* get a sequence number for this log entry */
481 	seq = fscp->fs_dlogseq + 1;
482 	if (seq == 0) {
483 		mutex_exit(&fscp->fs_dlock);
484 		offset = 0;
485 #ifdef CFSDEBUG
486 		cmn_err(CE_WARN, "cachefs: logging failed, seq overflow");
487 #endif
488 		goto out;
489 	}
490 	fscp->fs_dlogseq++;
491 	trail->dl_seq = fscp->fs_dlogseq;
492 
493 	/* add the sequence number to the record */
494 	entp->dl_seq = seq;
495 
496 	/* get offset into file to write record */
497 	offset = fscp->fs_dlogoff;
498 
499 	/* try to write the record to the log file */
500 	/*
501 	 * NOTE This write will over write the previous trailer record and
502 	 * will add a new trailer record. This is done with a single
503 	 * write for performance reasons.
504 	 */
505 	error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile, (caddr_t)entp,
506 	    entp->dl_len+trail->dl_len, (offset_t)offset, UIO_SYSSPACE, FSYNC,
507 	    RLIM_INFINITY, kcred, NULL);
508 
509 	if (error) {
510 		offset = 0;
511 		cmn_err(CE_WARN, "cachefs: logging failed (%d)", error);
512 	} else {
513 		fscp->fs_dlogoff += entp->dl_len;
514 
515 		/* get offset of valid field */
516 		offset += offsetof(struct cfs_dlog_entry, dl_valid);
517 	}
518 
519 	mutex_exit(&fscp->fs_dlock);
520 
521 	/* return sequence number used if requested */
522 	if (seqp)
523 		*seqp = seq;
524 
525 out:
526 	return (offset);
527 }
528 
529 /*
530  * Commits a previously written dlog message.
531  */
532 int
533 cachefs_dlog_commit(fscache_t *fscp, off_t offset, int error)
534 {
535 	cfs_dlog_val_t valid;
536 
537 	if (error)
538 		valid = CFS_DLOG_VAL_ERROR;
539 	else
540 		valid = CFS_DLOG_VAL_COMMITTED;
541 
542 	error = vn_rdwr(UIO_WRITE, fscp->fs_dlogfile,
543 	    (caddr_t)&valid, sizeof (valid), (offset_t)offset,
544 	    UIO_SYSSPACE, FSYNC, RLIM_INFINITY, kcred, NULL);
545 
546 	if (error)
547 		cmn_err(CE_WARN, "cachefs: logging commit failed (%d)", error);
548 	return (error);
549 }
550 
551 /*
552  * Reserves space in the map file.
553  */
554 static int
555 cachefs_dlog_mapreserve(fscache_t *fscp, int size)
556 {
557 	int error = 0;
558 	int len;
559 	char *bufp;
560 
561 	if (fscp->fs_dmapfile == NULL) {
562 		error = cachefs_dlog_setup(fscp, 1);
563 		if (error) {
564 			return (error);
565 		}
566 	}
567 
568 	mutex_enter(&fscp->fs_dlock);
569 	ASSERT(fscp->fs_dmapoff <= fscp->fs_dmapsize);
570 	ASSERT(fscp->fs_dmapfile);
571 
572 	if ((fscp->fs_dmapoff + size) > fscp->fs_dmapsize) {
573 		/* reserve 20% for optimal hashing */
574 		size += MAXBSIZE / 5;
575 
576 		/* grow file by a MAXBSIZE chunk */
577 		len = MAXBSIZE;
578 		ASSERT((fscp->fs_dmapoff + size) < (fscp->fs_dmapsize + len));
579 
580 		bufp = cachefs_kmem_zalloc(len, KM_SLEEP);
581 		error = vn_rdwr(UIO_WRITE, fscp->fs_dmapfile, (caddr_t)bufp,
582 			len, (offset_t)fscp->fs_dmapsize, UIO_SYSSPACE, FSYNC,
583 			RLIM_INFINITY, kcred, NULL);
584 		if (error == 0) {
585 			fscp->fs_dmapoff += size;
586 			fscp->fs_dmapsize += len;
587 		} else {
588 			cmn_err(CE_WARN, "cachefs: logging secondary "
589 			    "failed (%d)", error);
590 		}
591 		cachefs_kmem_free(bufp, len);
592 	} else {
593 		fscp->fs_dmapoff += size;
594 	}
595 	mutex_exit(&fscp->fs_dlock);
596 	return (error);
597 }
598 
599 /*
600  * Reserves space for one cid mapping in the mapping file.
601  */
602 int
603 cachefs_dlog_cidmap(fscache_t *fscp)
604 {
605 	int error;
606 	error = cachefs_dlog_mapreserve(fscp,
607 	    sizeof (struct cfs_dlog_mapping_space));
608 	return (error);
609 }
610 
611 off_t
612 cachefs_dlog_setattr(fscache_t *fscp, struct vattr *vap, int flags,
613     cnode_t *cp, cred_t *cr)
614 {
615 	struct cfs_dlog_entry *entp;
616 	struct cfs_dlog_setattr *up;
617 	size_t	len;
618 	off_t offset;
619 
620 	ASSERT(MUTEX_HELD(&cp->c_statelock));
621 
622 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
623 
624 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
625 	entp->dl_op = CFS_DLOG_SETATTR;
626 	up = &entp->dl_u.dl_setattr;
627 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
628 		"cachefs_dlog_setattr: dl_attr");
629 	up->dl_flags = flags;
630 	up->dl_cid = cp->c_id;
631 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
632 		&up->dl_times.tm_mtime, "cachefs_dlog_setattr: ", "mtime");
633 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
634 		&up->dl_times.tm_ctime, "cachefs_dlog_setattr: ", "ctime");
635 
636 	/* store the cred info */
637 	len = copy_cred(cr, &up->dl_cred);
638 
639 	/* Calculate the length of this record */
640 	entp->dl_len = (int)(((uintptr_t)&up->dl_cred + len) - (uintptr_t)entp);
641 
642 	/* write the record in the log */
643 	offset = cachefs_dlog_output(fscp, entp, NULL);
644 
645 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
646 	return (offset);
647 }
648 
649 off_t
650 /*ARGSUSED*/
651 cachefs_dlog_setsecattr(fscache_t *fscp, vsecattr_t *vsec, int flags,
652     cnode_t *cp, cred_t *cr)
653 {
654 	struct cfs_dlog_entry *entp;
655 	struct cfs_dlog_setsecattr *up;
656 	size_t alen, clen, len;
657 	off_t offset = 0;
658 	aclent_t *aclp;
659 
660 	ASSERT(MUTEX_HELD(&cp->c_statelock));
661 
662 	/* paranoia */
663 	ASSERT((vsec->vsa_mask & VSA_ACL) || (vsec->vsa_aclcnt == 0));
664 	ASSERT((vsec->vsa_mask & VSA_DFACL) || (vsec->vsa_dfaclcnt == 0));
665 	if ((vsec->vsa_mask & VSA_ACL) == 0)
666 		vsec->vsa_aclcnt = 0;
667 	if ((vsec->vsa_mask & VSA_DFACL) == 0)
668 		vsec->vsa_dfaclcnt = 0;
669 
670 	/* calculate length of ACL and cred data */
671 	alen = sizeof (aclent_t) * (vsec->vsa_aclcnt + vsec->vsa_dfaclcnt);
672 	clen = sizeof (dl_cred_t) + (((long)crgetngroups(cr)) * sizeof (gid_t));
673 
674 	/*
675 	 * allocate entry.  ACLs may be up to 24k currently, but they
676 	 * usually won't, so we don't want to make cfs_dlog_entry_t
677 	 * too big.  so, we must compute the length here.
678 	 */
679 
680 	len = sizeof (cfs_dlog_entry_t) - sizeof (up->dl_buffer) -
681 		sizeof (up->dl_cred) + alen + clen;
682 
683 
684 #if 0
685 	/* make up for weird behavior in cachefs_dlog_output */
686 	/* XXX turn this on/off in sync with code in cachefs_dlog_output */
687 	entp = cachefs_kmem_alloc(len + 32 + sizeof (struct cfs_dlog_trailer),
688 	    KM_SLEEP);
689 #else
690 	entp = cachefs_kmem_alloc(len, KM_SLEEP);
691 #endif
692 
693 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
694 	entp->dl_op = CFS_DLOG_SETSECATTR;
695 
696 	up = &entp->dl_u.dl_setsecattr;
697 	up->dl_cid = cp->c_id;
698 
699 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
700 		&up->dl_times.tm_mtime, "cachefs_dlog_setsecattr: ", "mtime");
701 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
702 		&up->dl_times.tm_ctime, "cachefs_dlog_setsecattr: ", "ctime");
703 
704 	/* get the creds */
705 	(void) copy_cred(cr, &up->dl_cred);
706 
707 	/* mask and counts */
708 	up->dl_mask = vsec->vsa_mask;
709 	up->dl_aclcnt = vsec->vsa_aclcnt;
710 	up->dl_dfaclcnt = vsec->vsa_dfaclcnt;
711 
712 	/* get the acls themselves */
713 	aclp = (aclent_t *)((uintptr_t)(&up->dl_cred) + clen);
714 	if (vsec->vsa_aclcnt > 0) {
715 		bcopy(vsec->vsa_aclentp, aclp,
716 		    vsec->vsa_aclcnt * sizeof (aclent_t));
717 		aclp += vsec->vsa_aclcnt;
718 	}
719 	if (vsec->vsa_dfaclcnt > 0) {
720 		bcopy(vsec->vsa_dfaclentp, aclp,
721 		    vsec->vsa_dfaclcnt * sizeof (aclent_t));
722 	}
723 
724 	entp->dl_len = (int)len;
725 
726 	offset = cachefs_dlog_output(fscp, entp, NULL);
727 
728 #if 0
729 	/* XXX turn on/off in sync with code in cachefs_dlog_output */
730 	cachefs_kmem_free(entp, len + 32 + sizeof (struct cfs_dlog_trailer));
731 #else
732 	cachefs_kmem_free(entp, len);
733 #endif
734 
735 	return (offset);
736 }
737 
738 off_t
739 cachefs_dlog_create(fscache_t *fscp, cnode_t *pcp, char *nm,
740     vattr_t *vap, int excl, int mode, cnode_t *cp, int exists, cred_t *cr)
741 {
742 	struct cfs_dlog_entry *entp;
743 	struct cfs_dlog_create *up;
744 	size_t len;
745 	caddr_t curp;
746 	off_t offset;
747 
748 	ASSERT(MUTEX_HELD(&cp->c_statelock));
749 
750 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
751 
752 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
753 	entp->dl_op = CFS_DLOG_CREATE;
754 	up = &entp->dl_u.dl_create;
755 	up->dl_parent_cid = pcp->c_id;
756 	up->dl_new_cid = cp->c_id;
757 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
758 		"cachefs_dlog_create: dl_attr");
759 	up->dl_excl = excl;
760 	up->dl_mode = mode;
761 	up->dl_exists = exists;
762 	bzero(&up->dl_fid, sizeof (up->dl_fid));
763 	if (exists) {
764 		CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
765 			&up->dl_times.tm_mtime,
766 			"cachefs_dlog_create: ", "mtime");
767 		CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
768 			&up->dl_times.tm_ctime,
769 			"cachefs_dlog_create: ", "ctime");
770 	} else {
771 		up->dl_times.tm_ctime.tv_sec = 0;
772 		up->dl_times.tm_ctime.tv_nsec = 0;
773 		up->dl_times.tm_mtime.tv_sec = 0;
774 		up->dl_times.tm_mtime.tv_nsec = 0;
775 	}
776 
777 	/* store the cred info */
778 	len = copy_cred(cr, &up->dl_cred);
779 
780 	/* find the address in buffer past where the creds are stored */
781 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
782 
783 	/* store the created name */
784 	len = strlen(nm) + 1;
785 	bcopy(nm, curp, len);
786 
787 	/* calculate the length of this record */
788 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
789 
790 	/* write the record in the log */
791 	offset = cachefs_dlog_output(fscp, entp, NULL);
792 
793 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
794 	return (offset);
795 }
796 
797 off_t
798 cachefs_dlog_remove(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
799     cred_t *cr)
800 {
801 	struct cfs_dlog_entry *entp;
802 	struct cfs_dlog_remove *up;
803 	size_t len;
804 	caddr_t curp;
805 	off_t offset;
806 
807 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
808 
809 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
810 	entp->dl_op = CFS_DLOG_REMOVE;
811 	up = &entp->dl_u.dl_remove;
812 	up->dl_parent_cid = pcp->c_id;
813 	up->dl_child_cid = cp->c_id;
814 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
815 		&up->dl_times.tm_mtime, "cachefs_dlog_remove: ", "mtime");
816 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
817 		&up->dl_times.tm_ctime, "cachefs_dlog_remove: ", "ctime");
818 	/* store the cred info */
819 	len = copy_cred(cr, &up->dl_cred);
820 
821 	/* find the address in buffer past where the creds are stored */
822 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
823 
824 	/* store the removed name */
825 	len = strlen(nm) + 1;
826 	bcopy(nm, curp, len);
827 
828 	/* calculate the length of this record */
829 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
830 
831 	/* write the record in the log */
832 	offset = cachefs_dlog_output(fscp, entp, NULL);
833 
834 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
835 	return (offset);
836 }
837 
838 off_t
839 cachefs_dlog_link(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
840     cred_t *cr)
841 {
842 	struct cfs_dlog_entry *entp;
843 	struct cfs_dlog_link *up;
844 	size_t len;
845 	caddr_t curp;
846 	off_t offset;
847 
848 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
849 
850 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
851 	entp->dl_op = CFS_DLOG_LINK;
852 	up = &entp->dl_u.dl_link;
853 	up->dl_parent_cid = pcp->c_id;
854 	up->dl_child_cid = cp->c_id;
855 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
856 		&up->dl_times.tm_mtime, "cachefs_dlog_link: ", "mtime");
857 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
858 		&up->dl_times.tm_ctime, "cachefs_dlog_link: ", "ctime");
859 
860 	/* store the cred info */
861 	len = copy_cred(cr, &up->dl_cred);
862 
863 	/* find the address in buffer past where the creds are stored */
864 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
865 
866 	/* store the link name */
867 	len = strlen(nm) + 1;
868 	bcopy(nm, curp, len);
869 
870 	/* calculate the length of this record */
871 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
872 
873 	/* write the record in the log */
874 	offset = cachefs_dlog_output(fscp, entp, NULL);
875 
876 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
877 	return (offset);
878 }
879 
880 off_t
881 cachefs_dlog_rename(fscache_t *fscp, cnode_t *odcp, char *onm, cnode_t *ndcp,
882     char *nnm, cred_t *cr, cnode_t *cp, cnode_t *delcp)
883 {
884 	struct cfs_dlog_entry *entp;
885 	struct cfs_dlog_rename *up;
886 	size_t len;
887 	caddr_t curp;
888 	off_t offset;
889 
890 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
891 
892 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
893 	entp->dl_op = CFS_DLOG_RENAME;
894 	up = &entp->dl_u.dl_rename;
895 	up->dl_oparent_cid = odcp->c_id;
896 	up->dl_nparent_cid = ndcp->c_id;
897 	up->dl_child_cid = cp->c_id;
898 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
899 		&up->dl_times.tm_mtime, "cachefs_dlog_rename: ", "mtime");
900 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
901 		&up->dl_times.tm_ctime, "cachefs_dlog_rename: ", "ctime");
902 	if (delcp) {
903 		up->dl_del_cid = delcp->c_id;
904 		CACHEFS_DLOG_TS_COPY(&delcp->c_metadata.md_vattr.va_mtime,
905 			&up->dl_del_times.tm_mtime,
906 			"cachefs_dlog_rename: ", "del mtime");
907 		CACHEFS_DLOG_TS_COPY(&delcp->c_metadata.md_vattr.va_ctime,
908 			&up->dl_del_times.tm_ctime,
909 			"cachefs_dlog_rename: ", "del ctime");
910 	} else {
911 		up->dl_del_cid.cid_fileno = 0;
912 		up->dl_del_cid.cid_flags = 0;
913 		up->dl_del_times.tm_mtime.tv_sec = 0;
914 		up->dl_del_times.tm_mtime.tv_nsec = 0;
915 		up->dl_del_times.tm_ctime.tv_sec = 0;
916 		up->dl_del_times.tm_ctime.tv_nsec = 0;
917 	}
918 
919 	/* store the cred info */
920 	len = copy_cred(cr, &up->dl_cred);
921 
922 	/* find the address in buffer past where the creds are stored */
923 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
924 
925 	/* store the old name */
926 	len = strlen(onm) + 1;
927 	bcopy(onm, curp, len);
928 
929 	/* store the new name */
930 	curp += len;
931 	len = strlen(nnm) + 1;
932 	bcopy(nnm, curp, len);
933 
934 	/* calculate the length of this record */
935 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
936 
937 	/* write the record in the log */
938 	offset = cachefs_dlog_output(fscp, entp, NULL);
939 
940 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
941 	return (offset);
942 }
943 
944 off_t
945 cachefs_dlog_mkdir(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *nm,
946     vattr_t *vap, cred_t *cr)
947 {
948 	struct cfs_dlog_entry *entp;
949 	struct cfs_dlog_mkdir *up;
950 	size_t len;
951 	caddr_t curp;
952 	off_t offset;
953 
954 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
955 
956 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
957 	entp->dl_op = CFS_DLOG_MKDIR;
958 	up = &entp->dl_u.dl_mkdir;
959 	up->dl_parent_cid = pcp->c_id;
960 	up->dl_child_cid = cp->c_id;
961 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
962 		"cachefs_dlog_mkdir: dl_attr");
963 	bzero(&up->dl_fid, sizeof (up->dl_fid));
964 
965 	/* store the cred info */
966 	len = copy_cred(cr, &up->dl_cred);
967 
968 	/* find the address in buffer past where the creds are stored */
969 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
970 
971 	/* store the new directory name */
972 	len = strlen(nm) + 1;
973 	bcopy(nm, curp, len);
974 
975 	/* calculate the length of this record */
976 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
977 
978 	/* write the record in the dlog */
979 	offset = cachefs_dlog_output(fscp, entp, NULL);
980 
981 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
982 	return (offset);
983 }
984 
985 off_t
986 cachefs_dlog_rmdir(fscache_t *fscp, cnode_t *pcp, char *nm, cnode_t *cp,
987     cred_t *cr)
988 {
989 	struct cfs_dlog_entry *entp;
990 	struct cfs_dlog_rmdir *up;
991 	size_t len;
992 	caddr_t curp;
993 	off_t offset;
994 
995 	/* if not a local dir, log the cid to fid mapping */
996 	if ((cp->c_id.cid_flags & CFS_CID_LOCAL) == 0) {
997 		if (cachefs_dlog_mapfid(fscp, cp))
998 			return (0);
999 		if (cachefs_dlog_cidmap(fscp))
1000 			return (0);
1001 	}
1002 
1003 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
1004 
1005 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
1006 	entp->dl_op = CFS_DLOG_RMDIR;
1007 	up = &entp->dl_u.dl_rmdir;
1008 	up->dl_parent_cid = pcp->c_id;
1009 
1010 	/* store the cred info */
1011 	len = copy_cred(cr, &up->dl_cred);
1012 
1013 	/* find the address in buffer past where the creds are stored */
1014 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
1015 
1016 	/* store the created name */
1017 	len = strlen(nm) + 1;
1018 	bcopy(nm, curp, len);
1019 
1020 	/* calculate the length of this record */
1021 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
1022 
1023 	/* write the record in the log */
1024 	offset = cachefs_dlog_output(fscp, entp, NULL);
1025 
1026 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
1027 	return (offset);
1028 }
1029 
1030 off_t
1031 cachefs_dlog_symlink(fscache_t *fscp, cnode_t *pcp, cnode_t *cp, char *lnm,
1032     vattr_t *vap, char *tnm, cred_t *cr)
1033 {
1034 	struct cfs_dlog_entry *entp;
1035 	struct cfs_dlog_symlink *up;
1036 	size_t len;
1037 	caddr_t curp;
1038 	off_t offset;
1039 
1040 	ASSERT(MUTEX_HELD(&cp->c_statelock));
1041 
1042 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
1043 
1044 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
1045 	entp->dl_op = CFS_DLOG_SYMLINK;
1046 	up = &entp->dl_u.dl_symlink;
1047 	up->dl_parent_cid = pcp->c_id;
1048 	up->dl_child_cid = cp->c_id;
1049 	CACHEFS_DLOG_VATTR_COPY(vap, &up->dl_attrs,
1050 		"cachefs_dlog_symlink: dl_attr");
1051 	up->dl_times.tm_ctime.tv_sec = 0;
1052 	up->dl_times.tm_ctime.tv_nsec = 0;
1053 	up->dl_times.tm_mtime.tv_sec = 0;
1054 	up->dl_times.tm_mtime.tv_nsec = 0;
1055 	bzero(&up->dl_fid, sizeof (up->dl_fid));
1056 
1057 	/* store the cred info */
1058 	len = copy_cred(cr, &up->dl_cred);
1059 
1060 	/* find the address in buffer past where the creds are stored */
1061 	curp = (caddr_t)(((uintptr_t)&up->dl_cred) + len);
1062 
1063 	/* store the link name */
1064 	len = strlen(lnm) + 1;
1065 	bcopy(lnm, curp, len);
1066 
1067 	/* store new name */
1068 	curp += len;
1069 	len = strlen(tnm) + 1;
1070 	bcopy(tnm, curp, len);
1071 
1072 	/* calculate the length of this record */
1073 	entp->dl_len = (int)(((uintptr_t)curp + len) - (uintptr_t)entp);
1074 
1075 	/* write the record in the log */
1076 	offset = cachefs_dlog_output(fscp, entp, NULL);
1077 
1078 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
1079 	return (offset);
1080 }
1081 
1082 off_t
1083 cachefs_dlog_modify(fscache_t *fscp, cnode_t *cp, cred_t *cr, uint_t *seqp)
1084 {
1085 	struct cfs_dlog_entry *entp;
1086 	struct cfs_dlog_modify *up;
1087 	off_t offset;
1088 	uint_t seq;
1089 	size_t len;
1090 
1091 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
1092 
1093 	entp->dl_valid = CFS_DLOG_VAL_CRASH;
1094 	entp->dl_op = CFS_DLOG_MODIFIED;
1095 	up = &entp->dl_u.dl_modify;
1096 	up->dl_cid = cp->c_id;
1097 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_mtime,
1098 		&up->dl_times.tm_mtime,
1099 		"cachefs_dlog_modify: ", "mtime");
1100 	CACHEFS_DLOG_TS_COPY(&cp->c_metadata.md_vattr.va_ctime,
1101 		&up->dl_times.tm_ctime,
1102 		"cachefs_dlog_modify: ", "ctime");
1103 
1104 	up->dl_next = 0;
1105 
1106 	/* store the cred info */
1107 	len = copy_cred(cr, &up->dl_cred);
1108 
1109 	/* calculate the length of this record */
1110 	entp->dl_len = (int)(((uintptr_t)&up->dl_cred + len) - (uintptr_t)entp);
1111 
1112 	/* write the record in the log */
1113 	offset = cachefs_dlog_output(fscp, entp, &seq);
1114 
1115 	/* return sequence number */
1116 	*seqp = seq;
1117 
1118 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
1119 	return (offset);
1120 }
1121 
1122 int
1123 cachefs_dlog_mapfid(fscache_t *fscp, cnode_t *cp)
1124 {
1125 	struct cfs_dlog_entry *entp;
1126 	struct cfs_dlog_mapfid *up;
1127 	off_t offset;
1128 
1129 	entp = cachefs_kmem_alloc(sizeof (cfs_dlog_entry_t), KM_SLEEP);
1130 
1131 	entp->dl_valid = CFS_DLOG_VAL_COMMITTED;
1132 	entp->dl_op = CFS_DLOG_MAPFID;
1133 	up = &entp->dl_u.dl_mapfid;
1134 	up->dl_cid = cp->c_id;
1135 	CACHEFS_FID_COPY(&cp->c_cookie, &up->dl_fid);
1136 
1137 	/* calculate the length of this record */
1138 	/* entp->dl_len = ((caddr_t)up - (caddr_t)entp + sizeof (*up)); */
1139 	entp->dl_len = (int)(offsetof(struct cfs_dlog_entry, dl_u.dl_mapfid) +
1140 				sizeof (struct cfs_dlog_mapfid));
1141 
1142 	/* write the record in the log */
1143 	offset = cachefs_dlog_output(fscp, entp, NULL);
1144 
1145 	cachefs_kmem_free(entp, sizeof (cfs_dlog_entry_t));
1146 	return (offset == 0);
1147 }
1148 
1149 /* Returns the next sequence number, 0 if an error */
1150 uint_t
1151 cachefs_dlog_seqnext(fscache_t *fscp)
1152 {
1153 	int error;
1154 	uint_t seq;
1155 
1156 	if (fscp->fs_dlogfile == NULL) {
1157 		error = cachefs_dlog_setup(fscp, 1);
1158 		if (error)
1159 			return (0);
1160 	}
1161 
1162 	mutex_enter(&fscp->fs_dlock);
1163 	ASSERT(fscp->fs_dlogfile);
1164 
1165 	/* get a sequence number for this log entry */
1166 	seq = fscp->fs_dlogseq + 1;
1167 	if (seq != 0) {
1168 		fscp->fs_dlogseq++;
1169 	}
1170 #ifdef CFSDEBUG
1171 	else {
1172 		cmn_err(CE_WARN, "cachefs: logging failed, seq overflow 2.");
1173 	}
1174 #endif
1175 	mutex_exit(&fscp->fs_dlock);
1176 	return (seq);
1177 }
1178