1 /* $NetBSD: dumplfs.c,v 1.36 2008/02/16 07:32:22 matt Exp $ */
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\
36 The Regents of the University of California. All rights reserved.");
41 static char sccsid
[] = "@(#)dumplfs.c 8.5 (Berkeley) 5/24/95";
43 __RCSID("$NetBSD: dumplfs.c,v 1.36 2008/02/16 07:32:22 matt Exp $");
47 #include <sys/param.h>
48 #include <sys/ucred.h>
49 #include <sys/mount.h>
52 #include <ufs/ufs/dinode.h>
53 #include <ufs/lfs/lfs.h>
65 static void addseg(char *);
66 static void dump_cleaner_info(struct lfs
*, void *);
67 static void dump_dinode(struct ufs1_dinode
*);
68 static void dump_ifile(int, struct lfs
*, int, int, daddr_t
);
69 static int dump_ipage_ifile(struct lfs
*, int, char *, int);
70 static int dump_ipage_segusage(struct lfs
*, int, char *, int);
71 static void dump_segment(int, int, daddr_t
, struct lfs
*, int);
72 static int dump_sum(int, struct lfs
*, SEGSUM
*, int, daddr_t
);
73 static void dump_super(struct lfs
*);
74 static void usage(void);
76 extern uint32_t cksum(void *, size_t);
78 typedef struct seglist SEGLIST
;
87 /* Segment Usage formats */
88 #define print_suheader \
89 (void)printf("segnum\tflags\tnbytes\tninos\tnsums\tlastmod\n")
92 print_suentry(int i
, SEGUSE
*sp
, struct lfs
*fs
)
97 if (sp
->su_flags
& SEGUSE_ACTIVE
)
99 if (sp
->su_flags
& SEGUSE_DIRTY
)
103 if (sp
->su_flags
& SEGUSE_SUPERBLOCK
)
106 t
= (fs
->lfs_version
== 1 ? sp
->su_olastmod
: sp
->su_lastmod
);
108 printf("%d\t%s\t%d\t%d\t%d\t%s", i
, flags
,
109 sp
->su_nbytes
, sp
->su_ninos
, sp
->su_nsums
,
114 #define print_iheader \
115 (void)printf("inum\tstatus\tversion\tdaddr\t\tfreeptr\n")
118 print_ientry(int i
, IFILE
*ip
)
120 if (ip
->if_daddr
== LFS_UNUSED_DADDR
)
121 printf("%d\tFREE\t%d\t \t\t%llu\n", i
, ip
->if_version
,
122 (unsigned long long)ip
->if_nextfree
);
124 printf("%d\tINUSE\t%d\t%8X\t%s\n",
125 i
, ip
->if_version
, ip
->if_daddr
,
126 (ip
->if_nextfree
== LFS_ORPHAN_NEXTFREE
? "FFFFFFFF" : "-"));
129 #define fsbtobyte(fs, b) fsbtob((fs), (off_t)((b)))
131 int datasum_check
= 0;
134 main(int argc
, char **argv
)
136 struct lfs lfs_sb1
, lfs_sb2
, *lfs_master
;
137 daddr_t seg_addr
, idaddr
, sbdaddr
;
138 int ch
, do_allsb
, do_ientries
, do_segentries
, fd
, segnum
;
145 while ((ch
= getopt(argc
, argv
, "ab:diI:Ss:")) != -1)
147 case 'a': /* Dump all superblocks */
150 case 'b': /* Use this superblock */
151 sbdaddr
= strtol(optarg
, NULL
, 0);
156 case 'i': /* Dump ifile entries */
157 do_ientries
= !do_ientries
;
159 case 'I': /* Use this ifile inode */
160 idaddr
= strtol(optarg
, NULL
, 0);
163 do_segentries
= !do_segentries
;
165 case 's': /* Dump out these segments */
178 if ((fd
= open(special
, O_RDONLY
, 0)) < 0)
179 err(1, "%s", special
);
181 if (sbdaddr
== 0x0) {
182 /* Read the proto-superblock */
183 get(fd
, LFS_LABELPAD
, &(lfs_sb1
.lfs_dlfs
), sizeof(struct dlfs
));
185 /* If that wasn't the real first sb, get the real first sb */
186 if (lfs_sb1
.lfs_version
> 1 &&
187 lfs_sb1
.lfs_sboffs
[0] > btofsb(&lfs_sb1
, LFS_LABELPAD
))
188 get(fd
, fsbtob(&lfs_sb1
, lfs_sb1
.lfs_sboffs
[0]),
189 &(lfs_sb1
.lfs_dlfs
), sizeof(struct dlfs
));
192 * Read the second superblock and figure out which check point is
196 fsbtobyte(&lfs_sb1
, lfs_sb1
.lfs_sboffs
[1]),
197 &(lfs_sb2
.lfs_dlfs
), sizeof(struct dlfs
));
199 lfs_master
= &lfs_sb1
;
200 if (lfs_sb1
.lfs_version
> 1) {
201 if (lfs_sb1
.lfs_serial
> lfs_sb2
.lfs_serial
) {
202 lfs_master
= &lfs_sb2
;
203 sbdaddr
= lfs_sb1
.lfs_sboffs
[1];
205 sbdaddr
= lfs_sb1
.lfs_sboffs
[0];
207 if (lfs_sb1
.lfs_otstamp
> lfs_sb2
.lfs_otstamp
) {
208 lfs_master
= &lfs_sb2
;
209 sbdaddr
= lfs_sb1
.lfs_sboffs
[1];
211 sbdaddr
= lfs_sb1
.lfs_sboffs
[0];
214 /* Read the first superblock */
215 get(fd
, dbtob((off_t
)sbdaddr
), &(lfs_sb1
.lfs_dlfs
),
216 sizeof(struct dlfs
));
217 lfs_master
= &lfs_sb1
;
221 if (lfs_master
->lfs_version
== 1) {
222 lfs_master
->lfs_sumsize
= LFS_V1_SUMMARY_SIZE
;
223 lfs_master
->lfs_ibsize
= lfs_master
->lfs_bsize
;
224 lfs_master
->lfs_start
= lfs_master
->lfs_sboffs
[0];
225 lfs_master
->lfs_tstamp
= lfs_master
->lfs_otstamp
;
226 lfs_master
->lfs_fsbtodb
= 0;
229 (void)printf("Master Superblock at 0x%llx:\n", (long long)sbdaddr
);
230 dump_super(lfs_master
);
232 dump_ifile(fd
, lfs_master
, do_ientries
, do_segentries
, idaddr
);
235 for (; seglist
!= NULL
; seglist
= seglist
->next
) {
236 seg_addr
= sntod(lfs_master
, seglist
->num
);
237 dump_segment(fd
, seglist
->num
, seg_addr
, lfs_master
,
241 for (segnum
= 0, seg_addr
= sntod(lfs_master
, 0);
242 segnum
< lfs_master
->lfs_nseg
;
243 segnum
++, seg_addr
= sntod(lfs_master
, segnum
))
244 dump_segment(fd
, segnum
, seg_addr
, lfs_master
,
252 * We are reading all the blocks of an inode and dumping out the ifile table.
253 * This code could be tighter, but this is a first pass at getting the stuff
254 * printed out rather than making this code incredibly efficient.
257 dump_ifile(int fd
, struct lfs
*lfsp
, int do_ientries
, int do_segentries
, daddr_t addr
)
260 struct ufs1_dinode
*dip
, *dpage
;
262 int32_t *addrp
, *dindir
, *iaddrp
, *indir
;
263 int block_limit
, i
, inum
, j
, nblocks
, psize
;
265 psize
= lfsp
->lfs_bsize
;
267 addr
= lfsp
->lfs_idaddr
;
269 if (!(dpage
= malloc(psize
)))
271 get(fd
, fsbtobyte(lfsp
, addr
), dpage
, psize
);
273 for (dip
= dpage
+ INOPB(lfsp
) - 1; dip
>= dpage
; --dip
)
274 if (dip
->di_inumber
== LFS_IFILE_INUM
)
278 warnx("unable to locate ifile inode at disk address 0x%llx",
283 (void)printf("\nIFILE inode\n");
286 (void)printf("\nIFILE contents\n");
287 nblocks
= dip
->di_size
>> lfsp
->lfs_bshift
;
288 block_limit
= MIN(nblocks
, NDADDR
);
290 /* Get the direct block */
291 if ((ipage
= malloc(psize
)) == NULL
)
293 for (inum
= 0, addrp
= dip
->di_db
, i
= 0; i
< block_limit
;
295 get(fd
, fsbtobyte(lfsp
, *addrp
), ipage
, psize
);
296 if (i
< lfsp
->lfs_cleansz
) {
297 dump_cleaner_info(lfsp
, ipage
);
303 if (i
< (lfsp
->lfs_segtabsz
+ lfsp
->lfs_cleansz
)) {
305 inum
= dump_ipage_segusage(lfsp
, inum
, ipage
,
308 inum
= (i
< lfsp
->lfs_segtabsz
+ lfsp
->lfs_cleansz
- 1);
316 inum
= dump_ipage_ifile(lfsp
, inum
, ipage
, lfsp
->lfs_ifpb
);
319 if (nblocks
<= NDADDR
)
322 /* Dump out blocks off of single indirect block */
323 if (!(indir
= malloc(psize
)))
325 get(fd
, fsbtobyte(lfsp
, dip
->di_ib
[0]), indir
, psize
);
326 block_limit
= MIN(i
+ lfsp
->lfs_nindir
, nblocks
);
327 for (addrp
= indir
; i
< block_limit
; i
++, addrp
++) {
328 if (*addrp
== LFS_UNUSED_DADDR
)
330 get(fd
, fsbtobyte(lfsp
, *addrp
), ipage
, psize
);
331 if (i
< lfsp
->lfs_cleansz
) {
332 dump_cleaner_info(lfsp
, ipage
);
336 if (i
< lfsp
->lfs_segtabsz
+ lfsp
->lfs_cleansz
) {
338 inum
= dump_ipage_segusage(lfsp
, inum
, ipage
,
341 inum
= (i
< lfsp
->lfs_segtabsz
+ lfsp
->lfs_cleansz
- 1);
349 inum
= dump_ipage_ifile(lfsp
, inum
, ipage
, lfsp
->lfs_ifpb
);
352 if (nblocks
<= lfsp
->lfs_nindir
* lfsp
->lfs_ifpb
)
355 /* Get the double indirect block */
356 if (!(dindir
= malloc(psize
)))
358 get(fd
, fsbtobyte(lfsp
, dip
->di_ib
[1]), dindir
, psize
);
359 for (iaddrp
= dindir
, j
= 0; j
< lfsp
->lfs_nindir
; j
++, iaddrp
++) {
360 if (*iaddrp
== LFS_UNUSED_DADDR
)
362 get(fd
, fsbtobyte(lfsp
, *iaddrp
), indir
, psize
);
363 block_limit
= MIN(i
+ lfsp
->lfs_nindir
, nblocks
);
364 for (addrp
= indir
; i
< block_limit
; i
++, addrp
++) {
365 if (*addrp
== LFS_UNUSED_DADDR
)
367 get(fd
, fsbtobyte(lfsp
, *addrp
), ipage
, psize
);
368 if (i
< lfsp
->lfs_cleansz
) {
369 dump_cleaner_info(lfsp
, ipage
);
373 if (i
< lfsp
->lfs_segtabsz
+ lfsp
->lfs_cleansz
) {
375 inum
= dump_ipage_segusage(lfsp
,
376 inum
, ipage
, lfsp
->lfs_sepb
);
378 inum
= (i
< lfsp
->lfs_segtabsz
+
379 lfsp
->lfs_cleansz
- 1);
387 inum
= dump_ipage_ifile(lfsp
, inum
,
388 ipage
, lfsp
->lfs_ifpb
);
398 dump_ipage_ifile(struct lfs
*lfsp
, int i
, char *pp
, int tot
)
401 int cnt
, max
, entsize
;
403 if (lfsp
->lfs_version
== 1)
404 entsize
= sizeof(IFILE_V1
);
406 entsize
= sizeof(IFILE
);
409 for (ip
= pp
, cnt
= i
; cnt
< max
; cnt
++, ip
+= entsize
)
410 print_ientry(cnt
, (IFILE
*)ip
);
415 dump_ipage_segusage(struct lfs
*lfsp
, int i
, char *pp
, int tot
)
422 for (sp
= (SEGUSE
*)pp
, cnt
= i
;
423 cnt
< lfsp
->lfs_nseg
&& cnt
< max
; cnt
++) {
425 print_suentry(cnt
, sp
, lfsp
);
427 for (slp
= seglist
; slp
!= NULL
; slp
= slp
->next
)
428 if (cnt
== slp
->num
) {
429 print_suentry(cnt
, sp
, lfsp
);
433 if (lfsp
->lfs_version
> 1)
436 sp
= (SEGUSE
*)((SEGUSE_V1
*)sp
+ 1);
438 if (max
>= lfsp
->lfs_nseg
)
445 dump_dinode(struct ufs1_dinode
*dip
)
454 (void)printf(" %so%o\t%s%d\t%s%d\t%s%d\t%s%llu\n",
455 "mode ", dip
->di_mode
,
456 "nlink ", dip
->di_nlink
,
459 "size ", (long long)dip
->di_size
);
460 (void)printf(" %s%s %s%s %s%s",
461 "atime ", ctime(&at
),
462 "mtime ", ctime(&mt
),
463 "ctime ", ctime(&ct
));
464 (void)printf(" inum %d\n", dip
->di_inumber
);
465 (void)printf(" Direct Addresses\n");
466 for (i
= 0; i
< NDADDR
; i
++) {
467 (void)printf("\t0x%x", dip
->di_db
[i
]);
471 for (i
= 0; i
< NIADDR
; i
++)
472 (void)printf("\t0x%x", dip
->di_ib
[i
]);
477 dump_sum(int fd
, struct lfs
*lfsp
, SEGSUM
*sp
, int segnum
, daddr_t addr
)
483 int numbytes
, numblocks
;
485 struct ufs1_dinode
*inop
;
491 if (sp
->ss_magic
!= SS_MAGIC
||
492 sp
->ss_sumsum
!= (ck
= cksum(&sp
->ss_datasum
,
493 lfsp
->lfs_sumsize
- sizeof(sp
->ss_sumsum
)))) {
494 /* Don't print "corrupt" if we're just too close to the edge */
495 if (dtosn(lfsp
, addr
+ fsbtodb(lfsp
, 1)) ==
497 (void)printf("dumplfs: %s %d address 0x%llx\n",
498 "corrupt summary block; segment", segnum
,
502 if (lfsp
->lfs_version
> 1 && sp
->ss_ident
!= lfsp
->lfs_ident
) {
503 (void)printf("dumplfs: %s %d address 0x%llx\n",
504 "summary from a former life; segment", segnum
,
509 (void)printf("Segment Summary Info at 0x%llx\n", (long long)addr
);
510 (void)printf(" %s0x%x\t%s%d\t%s%d\t%s%c%c%c%c\n %s0x%x\t%s0x%x",
511 "next ", sp
->ss_next
,
512 "nfinfo ", sp
->ss_nfinfo
,
513 "ninos ", sp
->ss_ninos
,
514 "flags ", (sp
->ss_flags
& SS_DIROP
) ? 'D' : '-',
515 (sp
->ss_flags
& SS_CONT
) ? 'C' : '-',
516 (sp
->ss_flags
& SS_CLEAN
) ? 'L' : '-',
517 (sp
->ss_flags
& SS_RFW
) ? 'R' : '-',
518 "sumsum ", sp
->ss_sumsum
,
519 "datasum ", sp
->ss_datasum
);
520 if (lfsp
->lfs_version
== 1) {
522 (void)printf("\tcreate %s\n", ctime(&t
));
525 (void)printf("\tcreate %s", ctime(&t
));
526 (void)printf(" roll_id %-8x", sp
->ss_ident
);
527 (void)printf(" serial %lld\n", (long long)sp
->ss_serial
);
530 /* Dump out inode disk addresses */
532 dp
+= lfsp
->lfs_sumsize
/ sizeof(int32_t);
533 inop
= malloc(lfsp
->lfs_bsize
);
534 printf(" Inode addresses:");
537 for (dp
--, i
= 0; i
< sp
->ss_ninos
; dp
--) {
539 numbytes
+= lfsp
->lfs_ibsize
; /* add bytes for inode block */
540 printf("\t0x%x {", *dp
);
541 get(fd
, fsbtobyte(lfsp
, *dp
), inop
, lfsp
->lfs_ibsize
);
542 for (j
= 0; i
< sp
->ss_ninos
&& j
< INOPB(lfsp
); j
++, i
++) {
545 (void)printf("%dv%d", inop
[j
].di_inumber
, inop
[j
].di_gen
);
548 if (((i
/INOPB(lfsp
)) % 4) == 3)
555 if (lfsp
->lfs_version
== 1)
556 fp
= (FINFO
*)((SEGSUM_V1
*)sp
+ 1);
558 fp
= (FINFO
*)(sp
+ 1);
559 for (i
= 0; i
< sp
->ss_nfinfo
; i
++) {
560 (void)printf(" FINFO for inode: %d version %d nblocks %d lastlength %d\n",
561 fp
->fi_ino
, fp
->fi_version
, fp
->fi_nblocks
,
563 dp
= &(fp
->fi_blocks
[0]);
564 numblocks
+= fp
->fi_nblocks
;
565 for (j
= 0; j
< fp
->fi_nblocks
; j
++, dp
++) {
566 (void)printf("\t%d", *dp
);
569 if (j
== fp
->fi_nblocks
- 1)
570 numbytes
+= fp
->fi_lastlength
;
572 numbytes
+= lfsp
->lfs_bsize
;
579 if (datasum_check
== 0)
583 * Now that we know the number of blocks, run back through and
584 * compute the data checksum. (A bad data checksum is not enough
585 * to prevent us from continuing, but it odes merit a warning.)
588 idp
+= lfsp
->lfs_sumsize
/ sizeof(int32_t);
590 if (lfsp
->lfs_version
== 1) {
591 fp
= (FINFO
*)((SEGSUM_V1
*)sp
+ 1);
592 el_size
= sizeof(unsigned long);
594 fp
= (FINFO
*)(sp
+ 1);
595 el_size
= sizeof(u_int32_t
);
597 datap
= (char *)malloc(el_size
* numblocks
);
598 memset(datap
, 0, el_size
* numblocks
);
600 addr
+= btofsb(lfsp
, lfsp
->lfs_sumsize
);
601 buf
= malloc(lfsp
->lfs_bsize
);
602 for (i
= 0; i
< sp
->ss_nfinfo
; i
++) {
603 while (addr
== *idp
) {
604 get(fd
, fsbtobyte(lfsp
, addr
), buf
, lfsp
->lfs_ibsize
);
605 memcpy(datap
+ acc
* el_size
, buf
, el_size
);
606 addr
+= btofsb(lfsp
, lfsp
->lfs_ibsize
);
610 for (j
= 0; j
< fp
->fi_nblocks
; j
++) {
611 get(fd
, fsbtobyte(lfsp
, addr
), buf
, lfsp
->lfs_fsize
);
612 memcpy(datap
+ acc
* el_size
, buf
, el_size
);
613 if (j
== fp
->fi_nblocks
- 1)
614 addr
+= btofsb(lfsp
, fp
->fi_lastlength
);
616 addr
+= btofsb(lfsp
, lfsp
->lfs_bsize
);
619 fp
= (FINFO
*)&(fp
->fi_blocks
[fp
->fi_nblocks
]);
621 while (addr
== *idp
) {
622 get(fd
, fsbtobyte(lfsp
, addr
), buf
, lfsp
->lfs_ibsize
);
623 memcpy(datap
+ acc
* el_size
, buf
, el_size
);
624 addr
+= btofsb(lfsp
, lfsp
->lfs_ibsize
);
629 if (acc
!= numblocks
)
630 printf("** counted %d blocks but should have been %d\n",
632 datasum
= cksum(datap
, numblocks
* el_size
);
633 if (datasum
!= sp
->ss_datasum
)
634 printf("** computed datasum 0x%lx does not match given datasum 0x%lx\n", (unsigned long)datasum
, (unsigned long)sp
->ss_datasum
);
641 dump_segment(int fd
, int segnum
, daddr_t addr
, struct lfs
*lfsp
, int dump_sb
)
643 struct lfs lfs_sb
, *sbp
;
646 int did_one
, nbytes
, sb
;
650 (void)printf("\nSEGMENT %lld (Disk Address 0x%llx)\n",
651 (long long)dtosn(lfsp
, addr
), (long long)addr
);
652 sum_offset
= fsbtobyte(lfsp
, addr
);
653 sumblock
= malloc(lfsp
->lfs_sumsize
);
655 if (lfsp
->lfs_version
> 1 && segnum
== 0) {
656 if (fsbtob(lfsp
, lfsp
->lfs_start
) < LFS_LABELPAD
) {
657 /* First segment eats the disklabel */
658 sum_offset
+= fragroundup(lfsp
, LFS_LABELPAD
) -
659 fsbtob(lfsp
, lfsp
->lfs_start
);
660 addr
+= btofsb(lfsp
, fragroundup(lfsp
, LFS_LABELPAD
)) -
662 printf("Disklabel at 0x0\n");
669 get(fd
, sum_offset
, sumblock
, lfsp
->lfs_sumsize
);
670 sump
= (SEGSUM
*)sumblock
;
671 if ((lfsp
->lfs_version
> 1 &&
672 sump
->ss_ident
!= lfsp
->lfs_ident
) ||
673 sump
->ss_sumsum
!= cksum (&sump
->ss_datasum
,
674 lfsp
->lfs_sumsize
- sizeof(sump
->ss_sumsum
))) {
675 sbp
= (struct lfs
*)sump
;
676 if ((sb
= (sbp
->lfs_magic
== LFS_MAGIC
))) {
677 printf("Superblock at 0x%x\n",
678 (unsigned)btofsb(lfsp
, sum_offset
));
680 get(fd
, sum_offset
, &(lfs_sb
.lfs_dlfs
),
681 sizeof(struct dlfs
));
684 if (lfsp
->lfs_version
> 1)
685 sum_offset
+= fragroundup(lfsp
, LFS_SBPAD
);
687 sum_offset
+= LFS_SBPAD
;
691 printf("Segment at 0x%llx empty or corrupt\n",
696 nbytes
= dump_sum(fd
, lfsp
, sump
, segnum
,
697 btofsb(lfsp
, sum_offset
));
699 sum_offset
+= lfsp
->lfs_sumsize
+ nbytes
;
704 /* If the segment ends right on a boundary, it still ends */
705 new_addr
= btofsb(lfsp
, sum_offset
);
706 /* printf("end daddr = 0x%lx\n", (long)new_addr); */
707 if (dtosn(lfsp
, new_addr
) != dtosn(lfsp
, addr
))
709 } while (sum_offset
);
715 dump_super(struct lfs
*lfsp
)
719 (void)printf(" %s0x%-8x %s0x%-8x %s%-10d\n",
720 "magic ", lfsp
->lfs_magic
,
721 "version ", lfsp
->lfs_version
,
722 "size ", lfsp
->lfs_size
);
723 (void)printf(" %s%-10d %s%-10d %s%-10d\n",
724 "ssize ", lfsp
->lfs_ssize
,
725 "dsize ", lfsp
->lfs_dsize
,
726 "bsize ", lfsp
->lfs_bsize
);
727 (void)printf(" %s%-10d %s%-10d %s%-10d\n",
728 "fsize ", lfsp
->lfs_fsize
,
729 "frag ", lfsp
->lfs_frag
,
730 "minfree ", lfsp
->lfs_minfree
);
731 (void)printf(" %s%-10d %s%-10d %s%-10d\n",
732 "inopb ", lfsp
->lfs_inopb
,
733 "ifpb ", lfsp
->lfs_ifpb
,
734 "nindir ", lfsp
->lfs_nindir
);
735 (void)printf(" %s%-10d %s%-10d %s%-10d\n",
736 "nseg ", lfsp
->lfs_nseg
,
737 "sepb ", lfsp
->lfs_sepb
,
738 "cleansz ", lfsp
->lfs_cleansz
);
739 (void)printf(" %s%-10d %s0x%-8x %s%-10d\n",
740 "segtabsz ", lfsp
->lfs_segtabsz
,
741 "segmask ", lfsp
->lfs_segmask
,
742 "segshift ", lfsp
->lfs_segshift
);
743 (void)printf(" %s0x%-8qx %s%-10d %s0x%-8qX\n",
744 "bmask ", (long long)lfsp
->lfs_bmask
,
745 "bshift ", lfsp
->lfs_bshift
,
746 "ffmask ", (long long)lfsp
->lfs_ffmask
);
747 (void)printf(" %s%-10d %s0x%-8qx %s%u\n",
748 "ffshift ", lfsp
->lfs_ffshift
,
749 "fbmask ", (long long)lfsp
->lfs_fbmask
,
750 "fbshift ", lfsp
->lfs_fbshift
);
752 (void)printf(" %s%-10d %s%-10d %s0x%-8x\n",
753 "sushift ", lfsp
->lfs_sushift
,
754 "fsbtodb ", lfsp
->lfs_fsbtodb
,
755 "cksum ", lfsp
->lfs_cksum
);
756 (void)printf(" %s%-10d %s%-10d %s%-10d\n",
757 "nclean ", lfsp
->lfs_nclean
,
758 "dmeta ", lfsp
->lfs_dmeta
,
759 "minfreeseg ", lfsp
->lfs_minfreeseg
);
760 (void)printf(" %s0x%-8x %s%-9d %s%-10d\n",
761 "roll_id ", lfsp
->lfs_ident
,
762 "interleave ", lfsp
->lfs_interleave
,
763 "sumsize ", lfsp
->lfs_sumsize
);
764 (void)printf(" %s%-10d %s0x%-8qx\n",
765 "seg0addr ", lfsp
->lfs_start
,
766 "maxfilesize ", (long long)lfsp
->lfs_maxfilesize
);
769 (void)printf(" Superblock disk addresses:\n ");
770 for (i
= 0; i
< LFS_MAXNUMSB
; i
++) {
771 (void)printf(" 0x%-8x", lfsp
->lfs_sboffs
[i
]);
772 if (i
== (LFS_MAXNUMSB
>> 1))
777 (void)printf(" Checkpoint Info\n");
778 (void)printf(" %s%-10d %s0x%-8x %s%-10d\n",
779 "freehd ", lfsp
->lfs_freehd
,
780 "idaddr ", lfsp
->lfs_idaddr
,
781 "ifile ", lfsp
->lfs_ifile
);
782 (void)printf(" %s%-10d %s%-10d %s%-10d\n",
783 "uinodes ", lfsp
->lfs_uinodes
,
784 "bfree ", lfsp
->lfs_bfree
,
785 "avail ", lfsp
->lfs_avail
);
786 (void)printf(" %s%-10d %s0x%-8x %s0x%-8x\n",
787 "nfiles ", lfsp
->lfs_nfiles
,
788 "lastseg ", lfsp
->lfs_lastseg
,
789 "nextseg ", lfsp
->lfs_nextseg
);
790 (void)printf(" %s0x%-8x %s0x%-8x %s%-10lld\n",
791 "curseg ", lfsp
->lfs_curseg
,
792 "offset ", lfsp
->lfs_offset
,
793 "serial ", (long long)lfsp
->lfs_serial
);
794 (void)printf(" tstamp %s", ctime((time_t *)&lfsp
->lfs_tstamp
));
802 if ((p
= malloc(sizeof(SEGLIST
))) == NULL
)
810 dump_cleaner_info(struct lfs
*lfsp
, void *ipage
)
814 cip
= (CLEANERINFO
*)ipage
;
815 if (lfsp
->lfs_version
> 1) {
816 (void)printf("free_head %d\n", cip
->free_head
);
817 (void)printf("free_tail %d\n", cip
->free_tail
);
819 (void)printf("clean\t%d\tdirty\t%d\n",
820 cip
->clean
, cip
->dirty
);
821 (void)printf("bfree\t%d\tavail\t%d\n\n",
822 cip
->bfree
, cip
->avail
);
828 (void)fprintf(stderr
, "usage: dumplfs [-adiS] [-b blkno] [-I blkno] [-s segno] filesys|device\n");