xref: /freebsd/sbin/growfs/debug.c (revision 3494f7c0)
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 2000 Christoph Herrmann, Thomas-Henning von Kamptz
5  * Copyright (c) 1980, 1989, 1993 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Christoph Herrmann and Thomas-Henning von Kamptz, Munich and Frankfurt.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgment:
21  *      This product includes software developed by the University of
22  *      California, Berkeley and its contributors, as well as Christoph
23  *      Herrmann and Thomas-Henning von Kamptz.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  * $TSHeader: src/sbin/growfs/debug.c,v 1.3 2000/12/12 19:31:00 tomsoft Exp $
41  *
42  */
43 
44 #include <sys/param.h>
45 
46 #include <limits.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <ufs/ufs/dinode.h>
50 #include <ufs/ffs/fs.h>
51 
52 #include "debug.h"
53 
54 #ifdef FS_DEBUG
55 
56 static FILE		*dbg_log = NULL;
57 static unsigned int	indent = 0;
58 
59 /*
60  * prototypes not done here, as they come with debug.h
61  */
62 
63 /*
64  * Open the filehandle where all debug output has to go.
65  */
66 void
67 dbg_open(const char *fn)
68 {
69 
70 	if (strcmp(fn, "-") == 0)
71 		dbg_log = fopen("/dev/stdout", "a");
72 	else
73 		dbg_log = fopen(fn, "a");
74 
75 	return;
76 }
77 
78 /*
79  * Close the filehandle where all debug output went to.
80  */
81 void
82 dbg_close(void)
83 {
84 
85 	if (dbg_log) {
86 		fclose(dbg_log);
87 		dbg_log = NULL;
88 	}
89 
90 	return;
91 }
92 
93 /*
94  * Dump out a full file system block in hex.
95  */
96 void
97 dbg_dump_hex(struct fs *sb, const char *comment, unsigned char *mem)
98 {
99 	int i, j, k;
100 
101 	if (!dbg_log)
102 		return;
103 
104 	fprintf(dbg_log, "===== START HEXDUMP =====\n");
105 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)mem, comment);
106 	indent++;
107 	for (i = 0; i < sb->fs_bsize; i += 24) {
108 		for (j = 0; j < 3; j++) {
109 			for (k = 0; k < 8; k++)
110 				fprintf(dbg_log, "%02x ", *mem++);
111 			fprintf(dbg_log, "  ");
112 		}
113 		fprintf(dbg_log, "\n");
114 	}
115 	indent--;
116 	fprintf(dbg_log, "===== END HEXDUMP =====\n");
117 
118 	return;
119 }
120 
121 /*
122  * Dump the superblock.
123  */
124 void
125 dbg_dump_fs(struct fs *sb, const char *comment)
126 {
127 	int j;
128 
129 	if (!dbg_log)
130 		return;
131 
132 	fprintf(dbg_log, "===== START SUPERBLOCK =====\n");
133 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)sb, comment);
134 	indent++;
135 
136 	fprintf(dbg_log, "sblkno            int32_t          0x%08x\n",
137 	    sb->fs_sblkno);
138 	fprintf(dbg_log, "cblkno            int32_t          0x%08x\n",
139 	    sb->fs_cblkno);
140 	fprintf(dbg_log, "iblkno            int32_t          0x%08x\n",
141 	    sb->fs_iblkno);
142 	fprintf(dbg_log, "dblkno            int32_t          0x%08x\n",
143 	    sb->fs_dblkno);
144 
145 	fprintf(dbg_log, "old_cgoffset      int32_t          0x%08x\n",
146 	    sb->fs_old_cgoffset);
147 	fprintf(dbg_log, "old_cgmask        int32_t          0x%08x\n",
148 	    sb->fs_old_cgmask);
149 	fprintf(dbg_log, "old_time          int32_t          %10u\n",
150 	    (unsigned int)sb->fs_old_time);
151 	fprintf(dbg_log, "old_size          int32_t          0x%08x\n",
152 	    sb->fs_old_size);
153 	fprintf(dbg_log, "old_dsize         int32_t          0x%08x\n",
154 	    sb->fs_old_dsize);
155 	fprintf(dbg_log, "ncg               int32_t          0x%08x\n",
156 	    sb->fs_ncg);
157 	fprintf(dbg_log, "bsize             int32_t          0x%08x\n",
158 	    sb->fs_bsize);
159 	fprintf(dbg_log, "fsize             int32_t          0x%08x\n",
160 	    sb->fs_fsize);
161 	fprintf(dbg_log, "frag              int32_t          0x%08x\n",
162 	    sb->fs_frag);
163 
164 	fprintf(dbg_log, "minfree           int32_t          0x%08x\n",
165 	    sb->fs_minfree);
166 	fprintf(dbg_log, "old_rotdelay      int32_t          0x%08x\n",
167 	    sb->fs_old_rotdelay);
168 	fprintf(dbg_log, "old_rps           int32_t          0x%08x\n",
169 	    sb->fs_old_rps);
170 
171 	fprintf(dbg_log, "bmask             int32_t          0x%08x\n",
172 	    sb->fs_bmask);
173 	fprintf(dbg_log, "fmask             int32_t          0x%08x\n",
174 	    sb->fs_fmask);
175 	fprintf(dbg_log, "bshift            int32_t          0x%08x\n",
176 	    sb->fs_bshift);
177 	fprintf(dbg_log, "fshift            int32_t          0x%08x\n",
178 	    sb->fs_fshift);
179 
180 	fprintf(dbg_log, "maxcontig         int32_t          0x%08x\n",
181 	    sb->fs_maxcontig);
182 	fprintf(dbg_log, "maxbpg            int32_t          0x%08x\n",
183 	    sb->fs_maxbpg);
184 
185 	fprintf(dbg_log, "fragshift         int32_t          0x%08x\n",
186 	    sb->fs_fragshift);
187 	fprintf(dbg_log, "fsbtodb           int32_t          0x%08x\n",
188 	    sb->fs_fsbtodb);
189 	fprintf(dbg_log, "sbsize            int32_t          0x%08x\n",
190 	    sb->fs_sbsize);
191 	fprintf(dbg_log, "spare1            int32_t[2]       0x%08x 0x%08x\n",
192 	    sb->fs_spare1[0], sb->fs_spare1[1]);
193 	fprintf(dbg_log, "nindir            int32_t          0x%08x\n",
194 	    sb->fs_nindir);
195 	fprintf(dbg_log, "inopb             int32_t          0x%08x\n",
196 	    sb->fs_inopb);
197 	fprintf(dbg_log, "old_nspf          int32_t          0x%08x\n",
198 	    sb->fs_old_nspf);
199 
200 	fprintf(dbg_log, "optim             int32_t          0x%08x\n",
201 	    sb->fs_optim);
202 
203 	fprintf(dbg_log, "old_npsect        int32_t          0x%08x\n",
204 	    sb->fs_old_npsect);
205 	fprintf(dbg_log, "old_interleave    int32_t          0x%08x\n",
206 	    sb->fs_old_interleave);
207 	fprintf(dbg_log, "old_trackskew     int32_t          0x%08x\n",
208 	    sb->fs_old_trackskew);
209 
210 	fprintf(dbg_log, "id                int32_t[2]       0x%08x 0x%08x\n",
211 	    sb->fs_id[0], sb->fs_id[1]);
212 
213 	fprintf(dbg_log, "old_csaddr        int32_t          0x%08x\n",
214 	    sb->fs_old_csaddr);
215 	fprintf(dbg_log, "cssize            int32_t          0x%08x\n",
216 	    sb->fs_cssize);
217 	fprintf(dbg_log, "cgsize            int32_t          0x%08x\n",
218 	    sb->fs_cgsize);
219 
220 	fprintf(dbg_log, "spare2            int32_t          0x%08x\n",
221 	    sb->fs_spare2);
222 	fprintf(dbg_log, "old_nsect         int32_t          0x%08x\n",
223 	    sb->fs_old_nsect);
224 	fprintf(dbg_log, "old_spc           int32_t          0x%08x\n",
225 	    sb->fs_old_spc);
226 
227 	fprintf(dbg_log, "old_ncyl          int32_t          0x%08x\n",
228 	    sb->fs_old_ncyl);
229 
230 	fprintf(dbg_log, "old_cpg           int32_t          0x%08x\n",
231 	    sb->fs_old_cpg);
232 	fprintf(dbg_log, "ipg               int32_t          0x%08x\n",
233 	    sb->fs_ipg);
234 	fprintf(dbg_log, "fpg               int32_t          0x%08x\n",
235 	    sb->fs_fpg);
236 
237 	dbg_dump_csum("internal old_cstotal", &sb->fs_old_cstotal);
238 
239 	fprintf(dbg_log, "fmod              int8_t           0x%02x\n",
240 	    sb->fs_fmod);
241 	fprintf(dbg_log, "clean             int8_t           0x%02x\n",
242 	    sb->fs_clean);
243 	fprintf(dbg_log, "ronly             int8_t           0x%02x\n",
244 	    sb->fs_ronly);
245 	fprintf(dbg_log, "old_flags         int8_t           0x%02x\n",
246 	    sb->fs_old_flags);
247 	fprintf(dbg_log, "fsmnt             u_char[MAXMNTLEN] \"%s\"\n",
248 	    sb->fs_fsmnt);
249 	fprintf(dbg_log, "volname           u_char[MAXVOLLEN] \"%s\"\n",
250 	    sb->fs_volname);
251 	fprintf(dbg_log, "swuid             u_int64_t        0x%08x%08x\n",
252 	    ((unsigned int *)&(sb->fs_swuid))[1],
253 		((unsigned int *)&(sb->fs_swuid))[0]);
254 
255 	fprintf(dbg_log, "pad               int32_t          0x%08x\n",
256 	    sb->fs_pad);
257 
258 	fprintf(dbg_log, "cgrotor           int32_t          0x%08x\n",
259 	    sb->fs_cgrotor);
260 /*
261  * struct csum[MAXCSBUFS] - is only maintained in memory
262  */
263 /*	fprintf(dbg_log, " int32_t\n", sb->*fs_maxcluster);*/
264 	fprintf(dbg_log, "old_cpc           int32_t          0x%08x\n",
265 	    sb->fs_old_cpc);
266 /*
267  * int16_t fs_opostbl[16][8] - is dumped when used in dbg_dump_sptbl
268  */
269 	fprintf(dbg_log, "maxbsize          int32_t          0x%08x\n",
270 	    sb->fs_maxbsize);
271 	fprintf(dbg_log, "unrefs            int64_t          0x%08jx\n",
272 	    sb->fs_unrefs);
273 	fprintf(dbg_log, "sblockloc         int64_t          0x%08x%08x\n",
274 		((unsigned int *)&(sb->fs_sblockloc))[1],
275 		((unsigned int *)&(sb->fs_sblockloc))[0]);
276 
277 	dbg_dump_csum_total("internal cstotal", &sb->fs_cstotal);
278 
279 	fprintf(dbg_log, "time              ufs_time_t       %10u\n",
280 	    (unsigned int)sb->fs_time);
281 
282 	fprintf(dbg_log, "size              int64_t          0x%08x%08x\n",
283 		((unsigned int *)&(sb->fs_size))[1],
284 		((unsigned int *)&(sb->fs_size))[0]);
285 	fprintf(dbg_log, "dsize             int64_t          0x%08x%08x\n",
286 		((unsigned int *)&(sb->fs_dsize))[1],
287 		((unsigned int *)&(sb->fs_dsize))[0]);
288 	fprintf(dbg_log, "csaddr            ufs2_daddr_t     0x%08x%08x\n",
289 		((unsigned int *)&(sb->fs_csaddr))[1],
290 		((unsigned int *)&(sb->fs_csaddr))[0]);
291 	fprintf(dbg_log, "pendingblocks     int64_t          0x%08x%08x\n",
292 		((unsigned int *)&(sb->fs_pendingblocks))[1],
293 		((unsigned int *)&(sb->fs_pendingblocks))[0]);
294 	fprintf(dbg_log, "pendinginodes     int32_t          0x%08x\n",
295 	    sb->fs_pendinginodes);
296 
297 	for (j = 0; j < FSMAXSNAP; j++) {
298 		fprintf(dbg_log, "snapinum          int32_t[%2d]      0x%08x\n",
299 		    j, sb->fs_snapinum[j]);
300 		if (!sb->fs_snapinum[j]) { /* list is dense */
301 			break;
302 		}
303 	}
304 	fprintf(dbg_log, "avgfilesize       int32_t          0x%08x\n",
305 	    sb->fs_avgfilesize);
306 	fprintf(dbg_log, "avgfpdir          int32_t          0x%08x\n",
307 	    sb->fs_avgfpdir);
308 	fprintf(dbg_log, "save_cgsize       int32_t          0x%08x\n",
309 	    sb->fs_save_cgsize);
310 	fprintf(dbg_log, "flags             int32_t          0x%08x\n",
311 	    sb->fs_flags);
312 	fprintf(dbg_log, "contigsumsize     int32_t          0x%08x\n",
313 	    sb->fs_contigsumsize);
314 	fprintf(dbg_log, "maxsymlinklen     int32_t          0x%08x\n",
315 	    sb->fs_maxsymlinklen);
316 	fprintf(dbg_log, "old_inodefmt      int32_t          0x%08x\n",
317 	    sb->fs_old_inodefmt);
318 	fprintf(dbg_log, "maxfilesize       u_int64_t        0x%08x%08x\n",
319 	    ((unsigned int *)&(sb->fs_maxfilesize))[1],
320 	    ((unsigned int *)&(sb->fs_maxfilesize))[0]);
321 	fprintf(dbg_log, "qbmask            int64_t          0x%08x%08x\n",
322 	    ((unsigned int *)&(sb->fs_qbmask))[1],
323 	    ((unsigned int *)&(sb->fs_qbmask))[0]);
324 	fprintf(dbg_log, "qfmask            int64_t          0x%08x%08x\n",
325 	    ((unsigned int *)&(sb->fs_qfmask))[1],
326 	    ((unsigned int *)&(sb->fs_qfmask))[0]);
327 	fprintf(dbg_log, "state             int32_t          0x%08x\n",
328 	    sb->fs_state);
329 	fprintf(dbg_log, "old_postblformat  int32_t          0x%08x\n",
330 	    sb->fs_old_postblformat);
331 	fprintf(dbg_log, "old_nrpos         int32_t          0x%08x\n",
332 	    sb->fs_old_nrpos);
333 	fprintf(dbg_log, "spare5            int32_t[2]       0x%08x 0x%08x\n",
334 	    sb->fs_spare5[0], sb->fs_spare5[1]);
335 	fprintf(dbg_log, "magic             int32_t          0x%08x\n",
336 	    sb->fs_magic);
337 
338 	indent--;
339 	fprintf(dbg_log, "===== END SUPERBLOCK =====\n");
340 
341 	return;
342 }
343 
344 /*
345  * Dump a cylinder group.
346  */
347 void
348 dbg_dump_cg(const char *comment, struct cg *cgr)
349 {
350 	int j;
351 
352 	if (!dbg_log)
353 		return;
354 
355 	fprintf(dbg_log, "===== START CYLINDER GROUP =====\n");
356 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cgr, comment);
357 	indent++;
358 
359 	fprintf(dbg_log, "magic         int32_t    0x%08x\n", cgr->cg_magic);
360 	fprintf(dbg_log, "old_time      int32_t    0x%08x\n", cgr->cg_old_time);
361 	fprintf(dbg_log, "cgx           int32_t    0x%08x\n", cgr->cg_cgx);
362 	fprintf(dbg_log, "old_ncyl      int16_t    0x%04x\n", cgr->cg_old_ncyl);
363 	fprintf(dbg_log, "old_niblk     int16_t    0x%04x\n", cgr->cg_old_niblk);
364 	fprintf(dbg_log, "ndblk         int32_t    0x%08x\n", cgr->cg_ndblk);
365 	dbg_dump_csum("internal cs", &cgr->cg_cs);
366 	fprintf(dbg_log, "rotor         int32_t    0x%08x\n", cgr->cg_rotor);
367 	fprintf(dbg_log, "frotor        int32_t    0x%08x\n", cgr->cg_frotor);
368 	fprintf(dbg_log, "irotor        int32_t    0x%08x\n", cgr->cg_irotor);
369 	for (j = 0; j < MAXFRAG; j++) {
370 		fprintf(dbg_log, "frsum         int32_t[%d] 0x%08x\n", j,
371 		    cgr->cg_frsum[j]);
372 	}
373 	fprintf(dbg_log, "old_btotoff   int32_t    0x%08x\n", cgr->cg_old_btotoff);
374 	fprintf(dbg_log, "old_boff      int32_t    0x%08x\n", cgr->cg_old_boff);
375 	fprintf(dbg_log, "iusedoff      int32_t    0x%08x\n", cgr->cg_iusedoff);
376 	fprintf(dbg_log, "freeoff       int32_t    0x%08x\n", cgr->cg_freeoff);
377 	fprintf(dbg_log, "nextfreeoff   int32_t    0x%08x\n",
378 	    cgr->cg_nextfreeoff);
379 	fprintf(dbg_log, "clustersumoff int32_t    0x%08x\n",
380 	    cgr->cg_clustersumoff);
381 	fprintf(dbg_log, "clusteroff    int32_t    0x%08x\n",
382 	    cgr->cg_clusteroff);
383 	fprintf(dbg_log, "nclusterblks  int32_t    0x%08x\n",
384 	    cgr->cg_nclusterblks);
385 	fprintf(dbg_log, "niblk         int32_t    0x%08x\n", cgr->cg_niblk);
386 	fprintf(dbg_log, "initediblk    int32_t    0x%08x\n", cgr->cg_initediblk);
387 	fprintf(dbg_log, "unrefs        int32_t    0x%08x\n", cgr->cg_unrefs);
388 	fprintf(dbg_log, "time          ufs_time_t %10u\n",
389 		(unsigned int)cgr->cg_initediblk);
390 
391 	indent--;
392 	fprintf(dbg_log, "===== END CYLINDER GROUP =====\n");
393 
394 	return;
395 }
396 
397 /*
398  * Dump a cylinder summary.
399  */
400 void
401 dbg_dump_csum(const char *comment, struct csum *cs)
402 {
403 
404 	if (!dbg_log)
405 		return;
406 
407 	fprintf(dbg_log, "===== START CYLINDER SUMMARY =====\n");
408 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cs, comment);
409 	indent++;
410 
411 	fprintf(dbg_log, "ndir   int32_t 0x%08x\n", cs->cs_ndir);
412 	fprintf(dbg_log, "nbfree int32_t 0x%08x\n", cs->cs_nbfree);
413 	fprintf(dbg_log, "nifree int32_t 0x%08x\n", cs->cs_nifree);
414 	fprintf(dbg_log, "nffree int32_t 0x%08x\n", cs->cs_nffree);
415 
416 	indent--;
417 	fprintf(dbg_log, "===== END CYLINDER SUMMARY =====\n");
418 
419 	return;
420 }
421 
422 /*
423  * Dump a cylinder summary.
424  */
425 void
426 dbg_dump_csum_total(const char *comment, struct csum_total *cs)
427 {
428 
429 	if (!dbg_log)
430 		return;
431 
432 	fprintf(dbg_log, "===== START CYLINDER SUMMARY TOTAL =====\n");
433 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cs, comment);
434 	indent++;
435 
436 	fprintf(dbg_log, "ndir        int64_t 0x%08x%08x\n",
437 		((unsigned int *)&(cs->cs_ndir))[1],
438 		((unsigned int *)&(cs->cs_ndir))[0]);
439 	fprintf(dbg_log, "nbfree      int64_t 0x%08x%08x\n",
440 		((unsigned int *)&(cs->cs_nbfree))[1],
441 		((unsigned int *)&(cs->cs_nbfree))[0]);
442 	fprintf(dbg_log, "nifree      int64_t 0x%08x%08x\n",
443 		((unsigned int *)&(cs->cs_nifree))[1],
444 		((unsigned int *)&(cs->cs_nifree))[0]);
445 	fprintf(dbg_log, "nffree      int64_t 0x%08x%08x\n",
446 		((unsigned int *)&(cs->cs_nffree))[1],
447 		((unsigned int *)&(cs->cs_nffree))[0]);
448 	fprintf(dbg_log, "numclusters int64_t 0x%08x%08x\n",
449 		((unsigned int *)&(cs->cs_numclusters))[1],
450 		((unsigned int *)&(cs->cs_numclusters))[0]);
451 
452 	indent--;
453 	fprintf(dbg_log, "===== END CYLINDER SUMMARY TOTAL =====\n");
454 
455 	return;
456 }
457 /*
458  * Dump the inode allocation map in one cylinder group.
459  */
460 void
461 dbg_dump_inmap(struct fs *sb, const char *comment, struct cg *cgr)
462 {
463 	int j,k,l,e;
464 	unsigned char *cp;
465 
466 	if (!dbg_log)
467 		return;
468 
469 	fprintf(dbg_log, "===== START INODE ALLOCATION MAP =====\n");
470 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cgr, comment);
471 	indent++;
472 
473 	cp = (unsigned char *)cg_inosused(cgr);
474 	e = sb->fs_ipg / 8;
475 	for (j = 0; j < e; j += 32) {
476 		fprintf(dbg_log, "%08x: ", j);
477 		for (k = 0; k < 32; k += 8) {
478 			if (j + k + 8 < e) {
479 				fprintf(dbg_log,
480 				    "%02x%02x%02x%02x%02x%02x%02x%02x ",
481 				    cp[0], cp[1], cp[2], cp[3],
482 				    cp[4], cp[5], cp[6], cp[7]);
483 			} else {
484 				for (l = 0; (l < 8) && (j + k + l < e); l++) {
485 					fprintf(dbg_log, "%02x", cp[l]);
486 				}
487 			}
488 			cp += 8;
489 		}
490 		fprintf(dbg_log, "\n");
491 	}
492 
493 	indent--;
494 	fprintf(dbg_log, "===== END INODE ALLOCATION MAP =====\n");
495 
496 	return;
497 }
498 
499 
500 /*
501  * Dump the fragment allocation map in one cylinder group.
502  */
503 void
504 dbg_dump_frmap(struct fs *sb, const char *comment, struct cg *cgr)
505 {
506 	int j,k,l,e;
507 	unsigned char *cp;
508 
509 	if (!dbg_log)
510 		return;
511 
512 	fprintf(dbg_log, "===== START FRAGMENT ALLOCATION MAP =====\n");
513 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cgr, comment);
514 	indent++;
515 
516 	cp = (unsigned char *)cg_blksfree(cgr);
517 	if (sb->fs_old_nspf)
518 		e = howmany(sb->fs_old_cpg * sb->fs_old_spc / sb->fs_old_nspf,
519 		    CHAR_BIT);
520 	else
521 		e = 0;
522 	for (j = 0; j < e; j += 32) {
523 		fprintf(dbg_log, "%08x: ", j);
524 		for (k = 0; k < 32; k += 8) {
525 			if (j + k + 8 <e) {
526 				fprintf(dbg_log,
527 				    "%02x%02x%02x%02x%02x%02x%02x%02x ",
528 				    cp[0], cp[1], cp[2], cp[3],
529 				    cp[4], cp[5], cp[6], cp[7]);
530 			} else {
531 				for (l = 0; (l < 8) && (j + k + l < e); l++) {
532 					fprintf(dbg_log, "%02x", cp[l]);
533 				}
534 			}
535 			cp += 8;
536 		}
537 		fprintf(dbg_log, "\n");
538 	}
539 
540 	indent--;
541 	fprintf(dbg_log, "===== END FRAGMENT ALLOCATION MAP =====\n");
542 
543 	return;
544 }
545 
546 /*
547  * Dump the cluster allocation map in one cylinder group.
548  */
549 void
550 dbg_dump_clmap(struct fs *sb, const char *comment, struct cg *cgr)
551 {
552 	int j,k,l,e;
553 	unsigned char *cp;
554 
555 	if (!dbg_log)
556 		return;
557 
558 	fprintf(dbg_log, "===== START CLUSTER ALLOCATION MAP =====\n");
559 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cgr, comment);
560 	indent++;
561 
562 	cp = (unsigned char *)cg_clustersfree(cgr);
563 	if (sb->fs_old_nspf)
564 		e = howmany(sb->fs_old_cpg * sb->fs_old_spc / (sb->fs_old_nspf << sb->fs_fragshift), CHAR_BIT);
565 	else
566 		e = 0;
567 	for (j = 0; j < e; j += 32) {
568 		fprintf(dbg_log, "%08x: ", j);
569 		for (k = 0; k < 32; k += 8) {
570 			if (j + k + 8 < e) {
571 				fprintf(dbg_log,
572 				    "%02x%02x%02x%02x%02x%02x%02x%02x ",
573 				    cp[0], cp[1], cp[2], cp[3],
574 				    cp[4], cp[5], cp[6], cp[7]);
575 			} else {
576 				for (l = 0; (l < 8) && (j + k + l <e); l++) {
577 					fprintf(dbg_log, "%02x", cp[l]);
578 				}
579 			}
580 			cp += 8;
581 		}
582 		fprintf(dbg_log, "\n");
583 	}
584 
585 	indent--;
586 	fprintf(dbg_log, "===== END CLUSTER ALLOCATION MAP =====\n");
587 
588 	return;
589 }
590 
591 /*
592  * Dump the cluster availability summary of one cylinder group.
593  */
594 void
595 dbg_dump_clsum(struct fs *sb, const char *comment, struct cg *cgr)
596 {
597 	int j;
598 	int *ip;
599 
600 	if (!dbg_log)
601 		return;
602 
603 	fprintf(dbg_log, "===== START CLUSTER SUMMARY =====\n");
604 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cgr, comment);
605 	indent++;
606 
607 	ip = (int *)cg_clustersum(cgr);
608 	for (j = 0; j <= sb->fs_contigsumsize; j++) {
609 		fprintf(dbg_log, "%02d: %8d\n", j, *ip++);
610 	}
611 
612 	indent--;
613 	fprintf(dbg_log, "===== END CLUSTER SUMMARY =====\n");
614 
615 	return;
616 }
617 
618 #ifdef NOT_CURRENTLY
619 /*
620  * This code dates from before the UFS2 integration, and doesn't compile
621  * post-UFS2 due to the use of cg_blks().  I'm not sure how best to update
622  * this for UFS2, where the rotational bits of UFS no longer apply, so
623  * will leave it disabled for now; it should probably be re-enabled
624  * specifically for UFS1.
625  */
626 /*
627  * Dump the block summary, and the rotational layout table.
628  */
629 void
630 dbg_dump_sptbl(struct fs *sb, const char *comment, struct cg *cgr)
631 {
632 	int j,k;
633 	int *ip;
634 
635 	if (!dbg_log)
636 		return;
637 
638 	fprintf(dbg_log,
639 	    "===== START BLOCK SUMMARY AND POSITION TABLE =====\n");
640 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)cgr, comment);
641 	indent++;
642 
643 	ip = (int *)cg_blktot(cgr);
644 	for (j = 0; j < sb->fs_old_cpg; j++) {
645 		fprintf(dbg_log, "%2d: %5d = ", j, *ip++);
646 		for (k = 0; k < sb->fs_old_nrpos; k++) {
647 			fprintf(dbg_log, "%4d", cg_blks(sb, cgr, j)[k]);
648 			if (k < sb->fs_old_nrpos - 1)
649 				fprintf(dbg_log, " + ");
650 		}
651 		fprintf(dbg_log, "\n");
652 	}
653 
654 	indent--;
655 	fprintf(dbg_log, "===== END BLOCK SUMMARY AND POSITION TABLE =====\n");
656 
657 	return;
658 }
659 #endif
660 
661 /*
662  * Dump a UFS1 inode structure.
663  */
664 void
665 dbg_dump_ufs1_ino(struct fs *sb, const char *comment, struct ufs1_dinode *ino)
666 {
667 	int ictr;
668 	int remaining_blocks;
669 
670 	if (!dbg_log)
671 		return;
672 
673 	fprintf(dbg_log, "===== START UFS1 INODE DUMP =====\n");
674 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)ino, comment);
675 	indent++;
676 
677 	fprintf(dbg_log, "mode       u_int16_t      0%o\n", ino->di_mode);
678 	fprintf(dbg_log, "nlink      int16_t        0x%04x\n", ino->di_nlink);
679 	fprintf(dbg_log, "size       u_int64_t      0x%08x%08x\n",
680 	    ((unsigned int *)&(ino->di_size))[1],
681 	    ((unsigned int *)&(ino->di_size))[0]);
682 	fprintf(dbg_log, "atime      int32_t        0x%08x\n", ino->di_atime);
683 	fprintf(dbg_log, "atimensec  int32_t        0x%08x\n",
684 	    ino->di_atimensec);
685 	fprintf(dbg_log, "mtime      int32_t        0x%08x\n",
686 	    ino->di_mtime);
687 	fprintf(dbg_log, "mtimensec  int32_t        0x%08x\n",
688 	    ino->di_mtimensec);
689 	fprintf(dbg_log, "ctime      int32_t        0x%08x\n", ino->di_ctime);
690 	fprintf(dbg_log, "ctimensec  int32_t        0x%08x\n",
691 	    ino->di_ctimensec);
692 
693 	remaining_blocks = howmany(ino->di_size, sb->fs_bsize); /* XXX ts - +1? */
694 	for (ictr = 0; ictr < MIN(UFS_NDADDR, remaining_blocks); ictr++) {
695 		fprintf(dbg_log, "db         ufs_daddr_t[%x] 0x%08x\n", ictr,
696 		    ino->di_db[ictr]);
697 	}
698 	remaining_blocks -= UFS_NDADDR;
699 	if (remaining_blocks > 0) {
700 		fprintf(dbg_log, "ib         ufs_daddr_t[0] 0x%08x\n",
701 		    ino->di_ib[0]);
702 	}
703 	remaining_blocks -= howmany(sb->fs_bsize, sizeof(ufs1_daddr_t));
704 	if (remaining_blocks > 0) {
705 		fprintf(dbg_log, "ib         ufs_daddr_t[1] 0x%08x\n",
706 		    ino->di_ib[1]);
707 	}
708 #define SQUARE(a) ((a) * (a))
709 	remaining_blocks -= SQUARE(howmany(sb->fs_bsize, sizeof(ufs1_daddr_t)));
710 #undef SQUARE
711 	if (remaining_blocks > 0) {
712 		fprintf(dbg_log, "ib         ufs_daddr_t[2] 0x%08x\n",
713 		    ino->di_ib[2]);
714 	}
715 
716 	fprintf(dbg_log, "flags      u_int32_t      0x%08x\n", ino->di_flags);
717 	fprintf(dbg_log, "blocks     int32_t        0x%08x\n", ino->di_blocks);
718 	fprintf(dbg_log, "gen        int32_t        0x%08x\n", ino->di_gen);
719 	fprintf(dbg_log, "uid        u_int32_t      0x%08x\n", ino->di_uid);
720 	fprintf(dbg_log, "gid        u_int32_t      0x%08x\n", ino->di_gid);
721 
722 	indent--;
723 	fprintf(dbg_log, "===== END UFS1 INODE DUMP =====\n");
724 
725 	return;
726 }
727 
728 /*
729  * Dump a UFS2 inode structure.
730  */
731 void
732 dbg_dump_ufs2_ino(struct fs *sb, const char *comment, struct ufs2_dinode *ino)
733 {
734 	int ictr;
735 	int remaining_blocks;
736 
737 	if (!dbg_log)
738 		return;
739 
740 	fprintf(dbg_log, "===== START UFS2 INODE DUMP =====\n");
741 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)ino, comment);
742 	indent++;
743 
744 	fprintf(dbg_log, "mode       u_int16_t      0%o\n", ino->di_mode);
745 	fprintf(dbg_log, "nlink      int16_t        0x%04x\n", ino->di_nlink);
746 	fprintf(dbg_log, "uid        u_int32_t      0x%08x\n", ino->di_uid);
747 	fprintf(dbg_log, "gid        u_int32_t      0x%08x\n", ino->di_gid);
748 	fprintf(dbg_log, "blksize    u_int32_t      0x%08x\n", ino->di_blksize);
749 	fprintf(dbg_log, "size       u_int64_t      0x%08x%08x\n",
750 	    ((unsigned int *)&(ino->di_size))[1],
751 	    ((unsigned int *)&(ino->di_size))[0]);
752 	fprintf(dbg_log, "blocks     u_int64_t      0x%08x%08x\n",
753 	    ((unsigned int *)&(ino->di_blocks))[1],
754 	    ((unsigned int *)&(ino->di_blocks))[0]);
755 	fprintf(dbg_log, "atime      ufs_time_t     %10jd\n", ino->di_atime);
756 	fprintf(dbg_log, "mtime      ufs_time_t     %10jd\n", ino->di_mtime);
757 	fprintf(dbg_log, "ctime      ufs_time_t     %10jd\n", ino->di_ctime);
758 	fprintf(dbg_log, "birthtime  ufs_time_t     %10jd\n", ino->di_birthtime);
759 	fprintf(dbg_log, "mtimensec  int32_t        0x%08x\n", ino->di_mtimensec);
760 	fprintf(dbg_log, "atimensec  int32_t        0x%08x\n", ino->di_atimensec);
761 	fprintf(dbg_log, "ctimensec  int32_t        0x%08x\n", ino->di_ctimensec);
762 	fprintf(dbg_log, "birthnsec  int32_t        0x%08x\n", ino->di_birthnsec);
763 	fprintf(dbg_log, "gen        int32_t        0x%08x\n", ino->di_gen);
764 	fprintf(dbg_log, "kernflags  u_int32_t      0x%08x\n", ino->di_kernflags);
765 	fprintf(dbg_log, "flags      u_int32_t      0x%08x\n", ino->di_flags);
766 	fprintf(dbg_log, "extsize    u_int32_t      0x%08x\n", ino->di_extsize);
767 
768 	/* XXX: What do we do with di_extb[UFS_NXADDR]? */
769 
770 	remaining_blocks = howmany(ino->di_size, sb->fs_bsize); /* XXX ts - +1? */
771 	for (ictr = 0; ictr < MIN(UFS_NDADDR, remaining_blocks); ictr++) {
772 		fprintf(dbg_log, "db         ufs2_daddr_t[%x] 0x%16jx\n", ictr,
773 		    ino->di_db[ictr]);
774 	}
775 	remaining_blocks -= UFS_NDADDR;
776 	if (remaining_blocks > 0) {
777 		fprintf(dbg_log, "ib         ufs2_daddr_t[0] 0x%16jx\n",
778 		    ino->di_ib[0]);
779 	}
780 	remaining_blocks -= howmany(sb->fs_bsize, sizeof(ufs2_daddr_t));
781 	if (remaining_blocks > 0) {
782 		fprintf(dbg_log, "ib         ufs2_daddr_t[1] 0x%16jx\n",
783 		    ino->di_ib[1]);
784 	}
785 #define SQUARE(a) ((a) * (a))
786 	remaining_blocks -= SQUARE(howmany(sb->fs_bsize, sizeof(ufs2_daddr_t)));
787 #undef SQUARE
788 	if (remaining_blocks > 0) {
789 		fprintf(dbg_log, "ib         ufs2_daddr_t[2] 0x%16jx\n",
790 		    ino->di_ib[2]);
791 	}
792 
793 	indent--;
794 	fprintf(dbg_log, "===== END UFS2 INODE DUMP =====\n");
795 
796 	return;
797 }
798 
799 /*
800  * Dump an indirect block. The iteration to dump a full file has to be
801  * written around.
802  */
803 void
804 dbg_dump_iblk(struct fs *sb, const char *comment, char *block, size_t length)
805 {
806 	unsigned int *mem, i, j, size;
807 
808 	if (!dbg_log)
809 		return;
810 
811 	fprintf(dbg_log, "===== START INDIRECT BLOCK DUMP =====\n");
812 	fprintf(dbg_log, "# %d@%lx: %s\n", indent, (unsigned long)block,
813 	    comment);
814 	indent++;
815 
816 	if (sb->fs_magic == FS_UFS1_MAGIC)
817 		size = sizeof(ufs1_daddr_t);
818 	else
819 		size = sizeof(ufs2_daddr_t);
820 
821 	mem = (unsigned int *)block;
822 	for (i = 0; (size_t)i < MIN(howmany(sb->fs_bsize, size), length);
823 	    i += 8) {
824 		fprintf(dbg_log, "%04x: ", i);
825 		for (j = 0; j < 8; j++) {
826 			if ((size_t)(i + j) < length)
827 				fprintf(dbg_log, "%08X ", *mem++);
828 		}
829 		fprintf(dbg_log, "\n");
830 	}
831 
832 	indent--;
833 	fprintf(dbg_log, "===== END INDIRECT BLOCK DUMP =====\n");
834 
835 	return;
836 }
837 
838 #endif /* FS_DEBUG */
839 
840