1 1.67 perseant /* $NetBSD: dumplfs.c,v 1.67 2025/09/14 19:09:11 perseant Exp $ */ 2 1.5 cgd 3 1.1 mycroft /*- 4 1.1 mycroft * Copyright (c) 1991, 1993 5 1.1 mycroft * The Regents of the University of California. All rights reserved. 6 1.1 mycroft * 7 1.1 mycroft * Redistribution and use in source and binary forms, with or without 8 1.1 mycroft * modification, are permitted provided that the following conditions 9 1.1 mycroft * are met: 10 1.1 mycroft * 1. Redistributions of source code must retain the above copyright 11 1.1 mycroft * notice, this list of conditions and the following disclaimer. 12 1.1 mycroft * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 mycroft * notice, this list of conditions and the following disclaimer in the 14 1.1 mycroft * documentation and/or other materials provided with the distribution. 15 1.28 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 mycroft * may be used to endorse or promote products derived from this software 17 1.1 mycroft * without specific prior written permission. 18 1.1 mycroft * 19 1.1 mycroft * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 mycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 mycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 mycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 mycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 mycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 mycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 mycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 mycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 mycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 mycroft * SUCH DAMAGE. 30 1.1 mycroft */ 31 1.1 mycroft 32 1.8 fvdl #include <sys/cdefs.h> 33 1.8 fvdl 34 1.1 mycroft #ifndef lint 35 1.37 lukem __COPYRIGHT("@(#) Copyright (c) 1991, 1993\ 36 1.37 lukem The Regents of the University of California. All rights reserved."); 37 1.1 mycroft #endif /* not lint */ 38 1.1 mycroft 39 1.1 mycroft #ifndef lint 40 1.5 cgd #if 0 41 1.8 fvdl static char sccsid[] = "@(#)dumplfs.c 8.5 (Berkeley) 5/24/95"; 42 1.5 cgd #else 43 1.67 perseant __RCSID("$NetBSD: dumplfs.c,v 1.67 2025/09/14 19:09:11 perseant Exp $"); 44 1.5 cgd #endif 45 1.1 mycroft #endif /* not lint */ 46 1.1 mycroft 47 1.1 mycroft #include <sys/param.h> 48 1.1 mycroft #include <sys/ucred.h> 49 1.1 mycroft #include <sys/mount.h> 50 1.1 mycroft #include <sys/time.h> 51 1.1 mycroft 52 1.1 mycroft #include <ufs/lfs/lfs.h> 53 1.45 dholland #include <ufs/lfs/lfs_accessors.h> 54 1.1 mycroft 55 1.2 mycroft #include <err.h> 56 1.2 mycroft #include <errno.h> 57 1.1 mycroft #include <fcntl.h> 58 1.1 mycroft #include <fstab.h> 59 1.62 riastrad #include <stdbool.h> 60 1.1 mycroft #include <stdlib.h> 61 1.1 mycroft #include <stdio.h> 62 1.1 mycroft #include <string.h> 63 1.2 mycroft #include <unistd.h> 64 1.64 christos #include <util.h> 65 1.1 mycroft #include "extern.h" 66 1.1 mycroft 67 1.19 perseant static void addseg(char *); 68 1.19 perseant static void dump_cleaner_info(struct lfs *, void *); 69 1.54 dholland static void dump_dinode(struct lfs *, union lfs_dinode *); 70 1.20 fvdl static void dump_ifile(int, struct lfs *, int, int, daddr_t); 71 1.19 perseant static int dump_ipage_ifile(struct lfs *, int, char *, int); 72 1.19 perseant static int dump_ipage_segusage(struct lfs *, int, char *, int); 73 1.19 perseant static void dump_segment(int, int, daddr_t, struct lfs *, int); 74 1.19 perseant static int dump_sum(int, struct lfs *, SEGSUM *, int, daddr_t); 75 1.19 perseant static void dump_super(struct lfs *); 76 1.67 perseant static void dump_inoblk(int, struct lfs *, daddr_t, ino_t); 77 1.19 perseant static void usage(void); 78 1.1 mycroft 79 1.36 matt extern uint32_t cksum(void *, size_t); 80 1.8 fvdl 81 1.1 mycroft typedef struct seglist SEGLIST; 82 1.1 mycroft struct seglist { 83 1.1 mycroft SEGLIST *next; 84 1.1 mycroft int num; 85 1.1 mycroft }; 86 1.1 mycroft SEGLIST *seglist; 87 1.1 mycroft 88 1.1 mycroft char *special; 89 1.1 mycroft 90 1.1 mycroft /* Segment Usage formats */ 91 1.1 mycroft #define print_suheader \ 92 1.1 mycroft (void)printf("segnum\tflags\tnbytes\tninos\tnsums\tlastmod\n") 93 1.1 mycroft 94 1.31 perseant static inline void 95 1.31 perseant print_suentry(int i, SEGUSE *sp, struct lfs *fs) 96 1.31 perseant { 97 1.31 perseant time_t t; 98 1.31 perseant char flags[4] = " "; 99 1.31 perseant 100 1.31 perseant if (sp->su_flags & SEGUSE_ACTIVE) 101 1.31 perseant flags[0] = 'A'; 102 1.31 perseant if (sp->su_flags & SEGUSE_DIRTY) 103 1.31 perseant flags[1] = 'D'; 104 1.31 perseant else 105 1.31 perseant flags[1] = 'C'; 106 1.31 perseant if (sp->su_flags & SEGUSE_SUPERBLOCK) 107 1.31 perseant flags[2] = 'S'; 108 1.31 perseant 109 1.48 dholland t = (lfs_sb_getversion(fs) == 1 ? sp->su_olastmod : sp->su_lastmod); 110 1.31 perseant 111 1.31 perseant printf("%d\t%s\t%d\t%d\t%d\t%s", i, flags, 112 1.31 perseant sp->su_nbytes, sp->su_ninos, sp->su_nsums, 113 1.31 perseant ctime(&t)); 114 1.31 perseant } 115 1.1 mycroft 116 1.1 mycroft /* Ifile formats */ 117 1.1 mycroft #define print_iheader \ 118 1.1 mycroft (void)printf("inum\tstatus\tversion\tdaddr\t\tfreeptr\n") 119 1.31 perseant 120 1.31 perseant static inline void 121 1.51 dholland print_ientry(int i, struct lfs *lfsp, IFILE *ip) 122 1.31 perseant { 123 1.51 dholland uint32_t version; 124 1.51 dholland daddr_t daddr; 125 1.51 dholland ino_t nextfree; 126 1.51 dholland 127 1.51 dholland version = lfs_if_getversion(lfsp, ip); 128 1.51 dholland daddr = lfs_if_getdaddr(lfsp, ip); 129 1.51 dholland nextfree = lfs_if_getnextfree(lfsp, ip); 130 1.51 dholland 131 1.51 dholland if (daddr == LFS_UNUSED_DADDR) 132 1.51 dholland printf("%d\tFREE\t%u\t \t\t%ju\n", i, version, 133 1.51 dholland (uintmax_t)nextfree); 134 1.31 perseant else 135 1.51 dholland printf("%d\tINUSE\t%u\t%8jX\t%s\n", 136 1.51 dholland i, version, (intmax_t)daddr, 137 1.65 riastrad nextfree == LFS_ORPHAN_NEXTFREE(lfsp) ? "orphan" : "-"); 138 1.31 perseant } 139 1.31 perseant 140 1.61 dholland /* 141 1.61 dholland * Set the is64 and dobyteswap fields of struct lfs. Note that the 142 1.61 dholland * magic number (and version) fields are necessarily at the same place 143 1.61 dholland * in all superblock versions, so we can read it via u_32 without 144 1.61 dholland * getting confused. 145 1.61 dholland */ 146 1.61 dholland static void 147 1.61 dholland identify(struct lfs *fs) 148 1.61 dholland { 149 1.61 dholland unsigned magic; 150 1.61 dholland 151 1.61 dholland magic = fs->lfs_dlfs_u.u_32.dlfs_magic; 152 1.61 dholland switch (magic) { 153 1.61 dholland case LFS_MAGIC: 154 1.61 dholland fs->lfs_is64 = false; 155 1.61 dholland fs->lfs_dobyteswap = false; 156 1.61 dholland break; 157 1.61 dholland case LFS_MAGIC_SWAPPED: 158 1.61 dholland fs->lfs_is64 = false; 159 1.61 dholland fs->lfs_dobyteswap = true; 160 1.61 dholland break; 161 1.61 dholland case LFS64_MAGIC: 162 1.61 dholland fs->lfs_is64 = true; 163 1.61 dholland fs->lfs_dobyteswap = false; 164 1.61 dholland break; 165 1.61 dholland case LFS64_MAGIC_SWAPPED: 166 1.61 dholland fs->lfs_is64 = true; 167 1.61 dholland fs->lfs_dobyteswap = true; 168 1.61 dholland break; 169 1.61 dholland default: 170 1.61 dholland warnx("Superblock magic number 0x%x not known; " 171 1.61 dholland "assuming 32-bit, native-endian", magic); 172 1.61 dholland fs->lfs_is64 = false; 173 1.61 dholland fs->lfs_dobyteswap = false; 174 1.61 dholland break; 175 1.61 dholland } 176 1.61 dholland } 177 1.61 dholland 178 1.41 christos #define fsbtobyte(fs, b) lfs_fsbtob((fs), (off_t)((b))) 179 1.16 toshii 180 1.25 perseant int datasum_check = 0; 181 1.25 perseant 182 1.1 mycroft int 183 1.19 perseant main(int argc, char **argv) 184 1.1 mycroft { 185 1.1 mycroft struct lfs lfs_sb1, lfs_sb2, *lfs_master; 186 1.67 perseant daddr_t seg_addr, idaddr, sbdaddr, inoaddr; 187 1.19 perseant int ch, do_allsb, do_ientries, do_segentries, fd, segnum; 188 1.38 mlelstv void *sbuf; 189 1.67 perseant char *narg, *s; 190 1.67 perseant ino_t dumpino; 191 1.1 mycroft 192 1.1 mycroft do_allsb = 0; 193 1.1 mycroft do_ientries = 0; 194 1.19 perseant do_segentries = 0; 195 1.67 perseant dumpino = 0; 196 1.14 perseant idaddr = 0x0; 197 1.14 perseant sbdaddr = 0x0; 198 1.67 perseant inoaddr = 0x0; 199 1.67 perseant narg = NULL; 200 1.67 perseant while ((ch = getopt(argc, argv, "ab:diI:n:Ss:")) != -1) 201 1.1 mycroft switch(ch) { 202 1.1 mycroft case 'a': /* Dump all superblocks */ 203 1.1 mycroft do_allsb = 1; 204 1.1 mycroft break; 205 1.14 perseant case 'b': /* Use this superblock */ 206 1.14 perseant sbdaddr = strtol(optarg, NULL, 0); 207 1.14 perseant break; 208 1.25 perseant case 'd': 209 1.25 perseant datasum_check = 1; 210 1.25 perseant break; 211 1.1 mycroft case 'i': /* Dump ifile entries */ 212 1.19 perseant do_ientries = !do_ientries; 213 1.1 mycroft break; 214 1.14 perseant case 'I': /* Use this ifile inode */ 215 1.14 perseant idaddr = strtol(optarg, NULL, 0); 216 1.14 perseant break; 217 1.67 perseant case 'n': 218 1.67 perseant narg = optarg; 219 1.67 perseant break; 220 1.19 perseant case 'S': 221 1.19 perseant do_segentries = !do_segentries; 222 1.19 perseant break; 223 1.1 mycroft case 's': /* Dump out these segments */ 224 1.1 mycroft addseg(optarg); 225 1.1 mycroft break; 226 1.1 mycroft default: 227 1.1 mycroft usage(); 228 1.1 mycroft } 229 1.1 mycroft argc -= optind; 230 1.1 mycroft argv += optind; 231 1.1 mycroft 232 1.1 mycroft if (argc != 1) 233 1.1 mycroft usage(); 234 1.1 mycroft 235 1.1 mycroft special = argv[0]; 236 1.1 mycroft if ((fd = open(special, O_RDONLY, 0)) < 0) 237 1.2 mycroft err(1, "%s", special); 238 1.1 mycroft 239 1.64 christos sbuf = emalloc(LFS_SBPAD); 240 1.14 perseant if (sbdaddr == 0x0) { 241 1.19 perseant /* Read the proto-superblock */ 242 1.49 dholland __CTASSERT(sizeof(struct dlfs) == sizeof(struct dlfs64)); 243 1.38 mlelstv get(fd, LFS_LABELPAD, sbuf, LFS_SBPAD); 244 1.49 dholland memcpy(&lfs_sb1.lfs_dlfs_u, sbuf, sizeof(struct dlfs)); 245 1.61 dholland identify(&lfs_sb1); 246 1.19 perseant 247 1.19 perseant /* If that wasn't the real first sb, get the real first sb */ 248 1.48 dholland if (lfs_sb_getversion(&lfs_sb1) > 1 && 249 1.61 dholland lfs_sb_getsboff(&lfs_sb1, 0) > lfs_btofsb(&lfs_sb1, LFS_LABELPAD)) { 250 1.44 dholland get(fd, lfs_fsbtob(&lfs_sb1, lfs_sb_getsboff(&lfs_sb1, 0)), 251 1.49 dholland &lfs_sb1.lfs_dlfs_u, sizeof(struct dlfs)); 252 1.61 dholland identify(&lfs_sb1); 253 1.61 dholland } 254 1.14 perseant 255 1.14 perseant /* 256 1.14 perseant * Read the second superblock and figure out which check point is 257 1.14 perseant * most up to date. 258 1.14 perseant */ 259 1.14 perseant get(fd, 260 1.44 dholland fsbtobyte(&lfs_sb1, lfs_sb_getsboff(&lfs_sb1, 1)), 261 1.38 mlelstv sbuf, LFS_SBPAD); 262 1.49 dholland memcpy(&lfs_sb2.lfs_dlfs_u, sbuf, sizeof(struct dlfs)); 263 1.61 dholland identify(&lfs_sb2); 264 1.14 perseant 265 1.14 perseant lfs_master = &lfs_sb1; 266 1.48 dholland if (lfs_sb_getversion(&lfs_sb1) > 1) { 267 1.43 dholland if (lfs_sb_getserial(&lfs_sb1) > lfs_sb_getserial(&lfs_sb2)) { 268 1.19 perseant lfs_master = &lfs_sb2; 269 1.44 dholland sbdaddr = lfs_sb_getsboff(&lfs_sb1, 1); 270 1.19 perseant } else 271 1.44 dholland sbdaddr = lfs_sb_getsboff(&lfs_sb1, 0); 272 1.19 perseant } else { 273 1.43 dholland if (lfs_sb_getotstamp(&lfs_sb1) > lfs_sb_getotstamp(&lfs_sb2)) { 274 1.19 perseant lfs_master = &lfs_sb2; 275 1.44 dholland sbdaddr = lfs_sb_getsboff(&lfs_sb1, 1); 276 1.19 perseant } else 277 1.44 dholland sbdaddr = lfs_sb_getsboff(&lfs_sb1, 0); 278 1.19 perseant } 279 1.14 perseant } else { 280 1.14 perseant /* Read the first superblock */ 281 1.38 mlelstv get(fd, dbtob((off_t)sbdaddr), sbuf, LFS_SBPAD); 282 1.49 dholland memcpy(&lfs_sb1.lfs_dlfs_u, sbuf, sizeof(struct dlfs)); 283 1.61 dholland identify(&lfs_sb1); 284 1.14 perseant lfs_master = &lfs_sb1; 285 1.13 perseant } 286 1.1 mycroft 287 1.38 mlelstv free(sbuf); 288 1.38 mlelstv 289 1.67 perseant /* 290 1.67 perseant * If asked to dump an inode block, do that and exit. 291 1.67 perseant */ 292 1.67 perseant if (narg != NULL) { 293 1.67 perseant s = strchr(narg, '@'); 294 1.67 perseant if (s != NULL) { 295 1.67 perseant *s = 0; 296 1.67 perseant dumpino = strtol(narg, NULL, 0); 297 1.67 perseant if (dumpino <= 0) 298 1.67 perseant usage(); 299 1.67 perseant narg = s + 1; 300 1.67 perseant } 301 1.67 perseant inoaddr = strtol(narg, NULL, 0); 302 1.67 perseant if (inoaddr <= 0) 303 1.67 perseant usage(); 304 1.67 perseant 305 1.67 perseant dump_inoblk(fd, lfs_master, inoaddr, dumpino); 306 1.67 perseant exit(0); 307 1.67 perseant } 308 1.67 perseant 309 1.19 perseant /* Compatibility */ 310 1.48 dholland if (lfs_sb_getversion(lfs_master) == 1) { 311 1.44 dholland lfs_sb_setsumsize(lfs_master, LFS_V1_SUMMARY_SIZE); 312 1.44 dholland lfs_sb_setibsize(lfs_master, lfs_sb_getbsize(lfs_master)); 313 1.44 dholland lfs_sb_sets0addr(lfs_master, lfs_sb_getsboff(lfs_master, 0)); 314 1.43 dholland lfs_sb_settstamp(lfs_master, lfs_sb_getotstamp(lfs_master)); 315 1.44 dholland lfs_sb_setfsbtodb(lfs_master, 0); 316 1.19 perseant } 317 1.19 perseant 318 1.61 dholland (void)printf("Master LFS%d superblock at 0x%llx:\n", 319 1.61 dholland lfs_master->lfs_is64 ? 64 : 32, (long long)sbdaddr); 320 1.1 mycroft dump_super(lfs_master); 321 1.1 mycroft 322 1.19 perseant dump_ifile(fd, lfs_master, do_ientries, do_segentries, idaddr); 323 1.1 mycroft 324 1.1 mycroft if (seglist != NULL) 325 1.1 mycroft for (; seglist != NULL; seglist = seglist->next) { 326 1.41 christos seg_addr = lfs_sntod(lfs_master, seglist->num); 327 1.19 perseant dump_segment(fd, seglist->num, seg_addr, lfs_master, 328 1.19 perseant do_allsb); 329 1.1 mycroft } 330 1.1 mycroft else 331 1.41 christos for (segnum = 0, seg_addr = lfs_sntod(lfs_master, 0); 332 1.44 dholland segnum < lfs_sb_getnseg(lfs_master); 333 1.41 christos segnum++, seg_addr = lfs_sntod(lfs_master, segnum)) 334 1.19 perseant dump_segment(fd, segnum, seg_addr, lfs_master, 335 1.19 perseant do_allsb); 336 1.1 mycroft 337 1.1 mycroft (void)close(fd); 338 1.1 mycroft exit(0); 339 1.1 mycroft } 340 1.1 mycroft 341 1.1 mycroft /* 342 1.1 mycroft * We are reading all the blocks of an inode and dumping out the ifile table. 343 1.1 mycroft * This code could be tighter, but this is a first pass at getting the stuff 344 1.1 mycroft * printed out rather than making this code incredibly efficient. 345 1.1 mycroft */ 346 1.1 mycroft static void 347 1.19 perseant dump_ifile(int fd, struct lfs *lfsp, int do_ientries, int do_segentries, daddr_t addr) 348 1.1 mycroft { 349 1.19 perseant char *ipage; 350 1.54 dholland char *dpage; 351 1.54 dholland union lfs_dinode *dip = NULL; 352 1.59 dholland void *dindir, *indir; 353 1.59 dholland unsigned offset; 354 1.59 dholland daddr_t thisblock; 355 1.54 dholland daddr_t pdb; 356 1.4 cgd int block_limit, i, inum, j, nblocks, psize; 357 1.1 mycroft 358 1.43 dholland psize = lfs_sb_getbsize(lfsp); 359 1.14 perseant if (!addr) 360 1.43 dholland addr = lfs_sb_getidaddr(lfsp); 361 1.1 mycroft 362 1.64 christos dpage = emalloc(psize); 363 1.19 perseant get(fd, fsbtobyte(lfsp, addr), dpage, psize); 364 1.1 mycroft 365 1.63 dholland dip = NULL; 366 1.54 dholland for (i = LFS_INOPB(lfsp); i-- > 0; ) { 367 1.54 dholland dip = DINO_IN_BLOCK(lfsp, dpage, i); 368 1.54 dholland if (lfs_dino_getinumber(lfsp, dip) == LFS_IFILE_INUM) 369 1.1 mycroft break; 370 1.54 dholland } 371 1.1 mycroft 372 1.63 dholland /* just in case */ 373 1.63 dholland if (dip == NULL) { 374 1.63 dholland warnx("this volume apparently has zero inodes per block"); 375 1.63 dholland return; 376 1.63 dholland } 377 1.63 dholland 378 1.54 dholland if (lfs_dino_getinumber(lfsp, dip) != LFS_IFILE_INUM) { 379 1.47 dholland warnx("unable to locate ifile inode at disk address 0x%jx", 380 1.47 dholland (uintmax_t)addr); 381 1.35 joerg return; 382 1.35 joerg } 383 1.1 mycroft 384 1.1 mycroft (void)printf("\nIFILE inode\n"); 385 1.54 dholland dump_dinode(lfsp, dip); 386 1.1 mycroft 387 1.1 mycroft (void)printf("\nIFILE contents\n"); 388 1.54 dholland nblocks = lfs_dino_getsize(lfsp, dip) >> lfs_sb_getbshift(lfsp); 389 1.40 dholland block_limit = MIN(nblocks, ULFS_NDADDR); 390 1.1 mycroft 391 1.1 mycroft /* Get the direct block */ 392 1.64 christos ipage = emalloc(psize); 393 1.54 dholland for (inum = 0, i = 0; i < block_limit; i++) { 394 1.54 dholland pdb = lfs_dino_getdb(lfsp, dip, i); 395 1.54 dholland get(fd, fsbtobyte(lfsp, pdb), ipage, psize); 396 1.43 dholland if (i < lfs_sb_getcleansz(lfsp)) { 397 1.1 mycroft dump_cleaner_info(lfsp, ipage); 398 1.19 perseant if (do_segentries) 399 1.19 perseant print_suheader; 400 1.1 mycroft continue; 401 1.1 mycroft } 402 1.1 mycroft 403 1.43 dholland if (i < (lfs_sb_getsegtabsz(lfsp) + lfs_sb_getcleansz(lfsp))) { 404 1.19 perseant if (do_segentries) 405 1.19 perseant inum = dump_ipage_segusage(lfsp, inum, ipage, 406 1.43 dholland lfs_sb_getsepb(lfsp)); 407 1.19 perseant else 408 1.43 dholland inum = (i < lfs_sb_getsegtabsz(lfsp) + lfs_sb_getcleansz(lfsp) - 1); 409 1.10 ross if (!inum) { 410 1.1 mycroft if(!do_ientries) 411 1.1 mycroft goto e0; 412 1.1 mycroft else 413 1.1 mycroft print_iheader; 414 1.10 ross } 415 1.1 mycroft } else 416 1.43 dholland inum = dump_ipage_ifile(lfsp, inum, ipage, lfs_sb_getifpb(lfsp)); 417 1.1 mycroft } 418 1.1 mycroft 419 1.40 dholland if (nblocks <= ULFS_NDADDR) 420 1.1 mycroft goto e0; 421 1.1 mycroft 422 1.1 mycroft /* Dump out blocks off of single indirect block */ 423 1.64 christos indir = emalloc(psize); 424 1.54 dholland get(fd, fsbtobyte(lfsp, lfs_dino_getib(lfsp, dip, 0)), indir, psize); 425 1.43 dholland block_limit = MIN(i + lfs_sb_getnindir(lfsp), nblocks); 426 1.59 dholland for (offset = 0; i < block_limit; i++, offset++) { 427 1.59 dholland thisblock = lfs_iblock_get(lfsp, indir, offset); 428 1.59 dholland if (thisblock == LFS_UNUSED_DADDR) 429 1.1 mycroft break; 430 1.59 dholland get(fd, fsbtobyte(lfsp, thisblock), ipage, psize); 431 1.43 dholland if (i < lfs_sb_getcleansz(lfsp)) { 432 1.1 mycroft dump_cleaner_info(lfsp, ipage); 433 1.1 mycroft continue; 434 1.19 perseant } 435 1.1 mycroft 436 1.43 dholland if (i < lfs_sb_getsegtabsz(lfsp) + lfs_sb_getcleansz(lfsp)) { 437 1.19 perseant if (do_segentries) 438 1.19 perseant inum = dump_ipage_segusage(lfsp, inum, ipage, 439 1.43 dholland lfs_sb_getsepb(lfsp)); 440 1.19 perseant else 441 1.43 dholland inum = (i < lfs_sb_getsegtabsz(lfsp) + lfs_sb_getcleansz(lfsp) - 1); 442 1.11 nathanw if (!inum) { 443 1.1 mycroft if(!do_ientries) 444 1.1 mycroft goto e1; 445 1.1 mycroft else 446 1.1 mycroft print_iheader; 447 1.11 nathanw } 448 1.1 mycroft } else 449 1.43 dholland inum = dump_ipage_ifile(lfsp, inum, ipage, lfs_sb_getifpb(lfsp)); 450 1.1 mycroft } 451 1.1 mycroft 452 1.55 dholland if (nblocks <= ULFS_NDADDR + lfs_sb_getnindir(lfsp)) 453 1.1 mycroft goto e1; 454 1.1 mycroft 455 1.1 mycroft /* Get the double indirect block */ 456 1.64 christos dindir = emalloc(psize); 457 1.54 dholland get(fd, fsbtobyte(lfsp, lfs_dino_getib(lfsp, dip, 1)), dindir, psize); 458 1.59 dholland for (j = 0; j < lfs_sb_getnindir(lfsp); j++) { 459 1.59 dholland thisblock = lfs_iblock_get(lfsp, dindir, j); 460 1.59 dholland if (thisblock == LFS_UNUSED_DADDR) 461 1.1 mycroft break; 462 1.59 dholland get(fd, fsbtobyte(lfsp, thisblock), indir, psize); 463 1.43 dholland block_limit = MIN(i + lfs_sb_getnindir(lfsp), nblocks); 464 1.59 dholland for (offset = 0; i < block_limit; i++, offset++) { 465 1.59 dholland thisblock = lfs_iblock_get(lfsp, indir, offset); 466 1.59 dholland if (thisblock == LFS_UNUSED_DADDR) 467 1.1 mycroft break; 468 1.59 dholland get(fd, fsbtobyte(lfsp, thisblock), ipage, psize); 469 1.43 dholland if (i < lfs_sb_getcleansz(lfsp)) { 470 1.1 mycroft dump_cleaner_info(lfsp, ipage); 471 1.1 mycroft continue; 472 1.19 perseant } 473 1.1 mycroft 474 1.43 dholland if (i < lfs_sb_getsegtabsz(lfsp) + lfs_sb_getcleansz(lfsp)) { 475 1.19 perseant if (do_segentries) 476 1.19 perseant inum = dump_ipage_segusage(lfsp, 477 1.43 dholland inum, ipage, lfs_sb_getsepb(lfsp)); 478 1.19 perseant else 479 1.43 dholland inum = (i < lfs_sb_getsegtabsz(lfsp) + 480 1.43 dholland lfs_sb_getcleansz(lfsp) - 1); 481 1.10 ross if (!inum) { 482 1.1 mycroft if(!do_ientries) 483 1.1 mycroft goto e2; 484 1.1 mycroft else 485 1.1 mycroft print_iheader; 486 1.10 ross } 487 1.1 mycroft } else 488 1.19 perseant inum = dump_ipage_ifile(lfsp, inum, 489 1.43 dholland ipage, lfs_sb_getifpb(lfsp)); 490 1.1 mycroft } 491 1.1 mycroft } 492 1.1 mycroft e2: free(dindir); 493 1.1 mycroft e1: free(indir); 494 1.1 mycroft e0: free(dpage); 495 1.1 mycroft free(ipage); 496 1.1 mycroft } 497 1.1 mycroft 498 1.1 mycroft static int 499 1.19 perseant dump_ipage_ifile(struct lfs *lfsp, int i, char *pp, int tot) 500 1.1 mycroft { 501 1.19 perseant char *ip; 502 1.19 perseant int cnt, max, entsize; 503 1.1 mycroft 504 1.51 dholland if (lfsp->lfs_is64) 505 1.51 dholland entsize = sizeof(IFILE64); 506 1.51 dholland if (lfs_sb_getversion(lfsp) > 1) 507 1.51 dholland entsize = sizeof(IFILE32); 508 1.51 dholland else 509 1.19 perseant entsize = sizeof(IFILE_V1); 510 1.1 mycroft max = i + tot; 511 1.1 mycroft 512 1.19 perseant for (ip = pp, cnt = i; cnt < max; cnt++, ip += entsize) 513 1.51 dholland print_ientry(cnt, lfsp, (IFILE *)ip); 514 1.1 mycroft return (max); 515 1.1 mycroft } 516 1.1 mycroft 517 1.1 mycroft static int 518 1.19 perseant dump_ipage_segusage(struct lfs *lfsp, int i, char *pp, int tot) 519 1.1 mycroft { 520 1.1 mycroft SEGUSE *sp; 521 1.1 mycroft int cnt, max; 522 1.15 perseant struct seglist *slp; 523 1.1 mycroft 524 1.1 mycroft max = i + tot; 525 1.1 mycroft for (sp = (SEGUSE *)pp, cnt = i; 526 1.43 dholland cnt < lfs_sb_getnseg(lfsp) && cnt < max; cnt++) { 527 1.15 perseant if (seglist == NULL) 528 1.19 perseant print_suentry(cnt, sp, lfsp); 529 1.15 perseant else { 530 1.15 perseant for (slp = seglist; slp != NULL; slp = slp->next) 531 1.15 perseant if (cnt == slp->num) { 532 1.19 perseant print_suentry(cnt, sp, lfsp); 533 1.15 perseant break; 534 1.15 perseant } 535 1.15 perseant } 536 1.48 dholland if (lfs_sb_getversion(lfsp) > 1) 537 1.19 perseant ++sp; 538 1.19 perseant else 539 1.19 perseant sp = (SEGUSE *)((SEGUSE_V1 *)sp + 1); 540 1.15 perseant } 541 1.43 dholland if (max >= lfs_sb_getnseg(lfsp)) 542 1.1 mycroft return (0); 543 1.1 mycroft else 544 1.1 mycroft return (max); 545 1.1 mycroft } 546 1.1 mycroft 547 1.1 mycroft static void 548 1.54 dholland dump_dinode(struct lfs *fs, union lfs_dinode *dip) 549 1.1 mycroft { 550 1.1 mycroft int i; 551 1.7 thorpej time_t at, mt, ct; 552 1.7 thorpej 553 1.54 dholland at = lfs_dino_getatime(fs, dip); 554 1.54 dholland mt = lfs_dino_getmtime(fs, dip); 555 1.54 dholland ct = lfs_dino_getctime(fs, dip); 556 1.54 dholland 557 1.54 dholland (void)printf(" %so%o\t%s%d\t%s%d\t%s%d\t%s%ju\n", 558 1.54 dholland "mode ", lfs_dino_getmode(fs, dip), 559 1.54 dholland "nlink ", lfs_dino_getnlink(fs, dip), 560 1.54 dholland "uid ", lfs_dino_getuid(fs, dip), 561 1.54 dholland "gid ", lfs_dino_getgid(fs, dip), 562 1.54 dholland "size ", (uintmax_t)lfs_dino_getsize(fs, dip)); 563 1.54 dholland (void)printf(" %s%s", "atime ", ctime(&at)); 564 1.54 dholland (void)printf(" %s%s", "mtime ", ctime(&mt)); 565 1.54 dholland (void)printf(" %s%s", "ctime ", ctime(&ct)); 566 1.67 perseant (void)printf(" inum %ju\tnblocks %ju\n", 567 1.67 perseant (uintmax_t)lfs_dino_getinumber(fs, dip), 568 1.67 perseant (uintmax_t)lfs_dino_getblocks(fs, dip)); 569 1.19 perseant (void)printf(" Direct Addresses\n"); 570 1.40 dholland for (i = 0; i < ULFS_NDADDR; i++) { 571 1.54 dholland (void)printf("\t0x%jx", (intmax_t)lfs_dino_getdb(fs, dip, i)); 572 1.1 mycroft if ((i % 6) == 5) 573 1.1 mycroft (void)printf("\n"); 574 1.1 mycroft } 575 1.54 dholland (void)printf(" Indirect Addresses\n"); 576 1.40 dholland for (i = 0; i < ULFS_NIADDR; i++) 577 1.54 dholland (void)printf("\t0x%jx", (intmax_t)lfs_dino_getib(fs, dip, i)); 578 1.1 mycroft (void)printf("\n"); 579 1.1 mycroft } 580 1.1 mycroft 581 1.1 mycroft static int 582 1.19 perseant dump_sum(int fd, struct lfs *lfsp, SEGSUM *sp, int segnum, daddr_t addr) 583 1.1 mycroft { 584 1.1 mycroft FINFO *fp; 585 1.58 dholland IINFO *iip, *iip2; 586 1.53 dholland union lfs_blocks fipblocks; 587 1.25 perseant int i, j, acc; 588 1.1 mycroft int ck; 589 1.25 perseant int numbytes, numblocks; 590 1.25 perseant char *datap; 591 1.54 dholland char *diblock; 592 1.54 dholland union lfs_dinode *dip; 593 1.25 perseant size_t el_size; 594 1.25 perseant u_int32_t datasum; 595 1.52 dholland u_int32_t ssflags; 596 1.31 perseant time_t t; 597 1.25 perseant char *buf; 598 1.52 dholland size_t sumstart; 599 1.1 mycroft 600 1.52 dholland sumstart = lfs_ss_getsumstart(lfsp); 601 1.52 dholland if (lfs_ss_getmagic(lfsp, sp) != SS_MAGIC || 602 1.52 dholland lfs_ss_getsumsum(lfsp, sp) != (ck = cksum((char *)sp + sumstart, 603 1.52 dholland lfs_sb_getsumsize(lfsp) - sumstart))) { 604 1.14 perseant /* Don't print "corrupt" if we're just too close to the edge */ 605 1.41 christos if (lfs_dtosn(lfsp, addr + LFS_FSBTODB(lfsp, 1)) == 606 1.41 christos lfs_dtosn(lfsp, addr)) 607 1.20 fvdl (void)printf("dumplfs: %s %d address 0x%llx\n", 608 1.14 perseant "corrupt summary block; segment", segnum, 609 1.20 fvdl (long long)addr); 610 1.34 perseant return -1; 611 1.19 perseant } 612 1.52 dholland if (lfs_sb_getversion(lfsp) > 1 && lfs_ss_getident(lfsp, sp) != lfs_sb_getident(lfsp)) { 613 1.20 fvdl (void)printf("dumplfs: %s %d address 0x%llx\n", 614 1.19 perseant "summary from a former life; segment", segnum, 615 1.21 mrg (long long)addr); 616 1.34 perseant return -1; 617 1.1 mycroft } 618 1.1 mycroft 619 1.20 fvdl (void)printf("Segment Summary Info at 0x%llx\n", (long long)addr); 620 1.52 dholland ssflags = lfs_ss_getflags(lfsp, sp); 621 1.52 dholland (void)printf(" %s0x%jx\t%s%d\t%s%d\t%s%c%c%c%c\n %s0x%x\t%s0x%x", 622 1.52 dholland "next ", (intmax_t)lfs_ss_getnext(lfsp, sp), 623 1.52 dholland "nfinfo ", lfs_ss_getnfinfo(lfsp, sp), 624 1.52 dholland "ninos ", lfs_ss_getninos(lfsp, sp), 625 1.52 dholland "flags ", (ssflags & SS_DIROP) ? 'D' : '-', 626 1.52 dholland (ssflags & SS_CONT) ? 'C' : '-', 627 1.52 dholland (ssflags & SS_CLEAN) ? 'L' : '-', 628 1.52 dholland (ssflags & SS_RFW) ? 'R' : '-', 629 1.52 dholland "sumsum ", lfs_ss_getsumsum(lfsp, sp), 630 1.52 dholland "datasum ", lfs_ss_getdatasum(lfsp, sp)); 631 1.48 dholland if (lfs_sb_getversion(lfsp) == 1) { 632 1.52 dholland t = lfs_ss_getocreate(lfsp, sp); 633 1.31 perseant (void)printf("\tcreate %s\n", ctime(&t)); 634 1.31 perseant } else { 635 1.52 dholland t = lfs_ss_getcreate(lfsp, sp); 636 1.31 perseant (void)printf("\tcreate %s", ctime(&t)); 637 1.52 dholland (void)printf(" roll_id %-8x", lfs_ss_getident(lfsp, sp)); 638 1.52 dholland (void)printf(" serial %lld\n", 639 1.52 dholland (long long)lfs_ss_getserial(lfsp, sp)); 640 1.19 perseant } 641 1.1 mycroft 642 1.1 mycroft /* Dump out inode disk addresses */ 643 1.58 dholland iip = SEGSUM_IINFOSTART(lfsp, sp); 644 1.64 christos diblock = emalloc(lfs_sb_getbsize(lfsp)); 645 1.67 perseant printf(" Inode addresses:\n"); 646 1.8 fvdl numbytes = 0; 647 1.25 perseant numblocks = 0; 648 1.58 dholland for (i = 0; i < lfs_ss_getninos(lfsp, sp); iip = NEXTLOWER_IINFO(lfsp, iip)) { 649 1.25 perseant ++numblocks; 650 1.43 dholland numbytes += lfs_sb_getibsize(lfsp); /* add bytes for inode block */ 651 1.58 dholland printf("\t0x%jx {", (intmax_t)lfs_ii_getblock(lfsp, iip)); 652 1.58 dholland get(fd, fsbtobyte(lfsp, lfs_ii_getblock(lfsp, iip)), diblock, lfs_sb_getibsize(lfsp)); 653 1.52 dholland for (j = 0; i < lfs_ss_getninos(lfsp, sp) && j < LFS_INOPB(lfsp); j++, i++) { 654 1.1 mycroft if (j > 0) 655 1.1 mycroft (void)printf(", "); 656 1.54 dholland dip = DINO_IN_BLOCK(lfsp, diblock, j); 657 1.54 dholland (void)printf("%juv%d", lfs_dino_getinumber(lfsp, dip), 658 1.54 dholland lfs_dino_getgen(lfsp, dip)); 659 1.1 mycroft } 660 1.67 perseant (void)printf("}\n"); 661 1.1 mycroft } 662 1.54 dholland free(diblock); 663 1.1 mycroft 664 1.52 dholland fp = SEGSUM_FINFOBASE(lfsp, sp); 665 1.52 dholland for (i = 0; i < lfs_ss_getnfinfo(lfsp, sp); i++) { 666 1.53 dholland (void)printf(" FINFO for inode: %ju version %u nblocks %u lastlength %u\n", 667 1.53 dholland (uintmax_t)lfs_fi_getino(lfsp, fp), 668 1.53 dholland lfs_fi_getversion(lfsp, fp), 669 1.53 dholland lfs_fi_getnblocks(lfsp, fp), 670 1.53 dholland lfs_fi_getlastlength(lfsp, fp)); 671 1.53 dholland lfs_blocks_fromfinfo(lfsp, &fipblocks, fp); 672 1.53 dholland numblocks += lfs_fi_getnblocks(lfsp, fp); 673 1.53 dholland for (j = 0; j < lfs_fi_getnblocks(lfsp, fp); j++) { 674 1.53 dholland (void)printf("\t%jd", 675 1.53 dholland (intmax_t)lfs_blocks_get(lfsp, &fipblocks, j)); 676 1.1 mycroft if ((j % 8) == 7) 677 1.1 mycroft (void)printf("\n"); 678 1.53 dholland if (j == lfs_fi_getnblocks(lfsp, fp) - 1) 679 1.53 dholland numbytes += lfs_fi_getlastlength(lfsp, fp); 680 1.8 fvdl else 681 1.43 dholland numbytes += lfs_sb_getbsize(lfsp); 682 1.1 mycroft } 683 1.1 mycroft if ((j % 8) != 0) 684 1.1 mycroft (void)printf("\n"); 685 1.53 dholland fp = NEXT_FINFO(lfsp, fp); 686 1.1 mycroft } 687 1.25 perseant 688 1.25 perseant if (datasum_check == 0) 689 1.25 perseant return (numbytes); 690 1.25 perseant 691 1.25 perseant /* 692 1.25 perseant * Now that we know the number of blocks, run back through and 693 1.25 perseant * compute the data checksum. (A bad data checksum is not enough 694 1.66 andvar * to prevent us from continuing, but it does merit a warning.) 695 1.25 perseant */ 696 1.58 dholland iip2 = SEGSUM_IINFOSTART(lfsp, sp); 697 1.60 dholland fp = SEGSUM_FINFOBASE(lfsp, sp); 698 1.48 dholland if (lfs_sb_getversion(lfsp) == 1) { 699 1.25 perseant el_size = sizeof(unsigned long); 700 1.25 perseant } else { 701 1.25 perseant el_size = sizeof(u_int32_t); 702 1.25 perseant } 703 1.64 christos datap = ecalloc(numblocks, el_size); 704 1.64 christos 705 1.25 perseant acc = 0; 706 1.43 dholland addr += lfs_btofsb(lfsp, lfs_sb_getsumsize(lfsp)); 707 1.64 christos buf = emalloc(lfs_sb_getbsize(lfsp)); 708 1.52 dholland for (i = 0; i < lfs_ss_getnfinfo(lfsp, sp); i++) { 709 1.58 dholland while (addr == lfs_ii_getblock(lfsp, iip2)) { 710 1.43 dholland get(fd, fsbtobyte(lfsp, addr), buf, lfs_sb_getibsize(lfsp)); 711 1.25 perseant memcpy(datap + acc * el_size, buf, el_size); 712 1.43 dholland addr += lfs_btofsb(lfsp, lfs_sb_getibsize(lfsp)); 713 1.58 dholland iip2 = NEXTLOWER_IINFO(lfsp, iip2); 714 1.25 perseant ++acc; 715 1.25 perseant } 716 1.53 dholland for (j = 0; j < lfs_fi_getnblocks(lfsp, fp); j++) { 717 1.43 dholland get(fd, fsbtobyte(lfsp, addr), buf, lfs_sb_getfsize(lfsp)); 718 1.25 perseant memcpy(datap + acc * el_size, buf, el_size); 719 1.53 dholland if (j == lfs_fi_getnblocks(lfsp, fp) - 1) 720 1.53 dholland addr += lfs_btofsb(lfsp, lfs_fi_getlastlength(lfsp, fp)); 721 1.25 perseant else 722 1.43 dholland addr += lfs_btofsb(lfsp, lfs_sb_getbsize(lfsp)); 723 1.25 perseant ++acc; 724 1.25 perseant } 725 1.53 dholland fp = NEXT_FINFO(lfsp, fp); 726 1.25 perseant } 727 1.58 dholland while (addr == lfs_ii_getblock(lfsp, iip2)) { 728 1.43 dholland get(fd, fsbtobyte(lfsp, addr), buf, lfs_sb_getibsize(lfsp)); 729 1.25 perseant memcpy(datap + acc * el_size, buf, el_size); 730 1.43 dholland addr += lfs_btofsb(lfsp, lfs_sb_getibsize(lfsp)); 731 1.58 dholland iip2 = NEXTLOWER_IINFO(lfsp, iip2); 732 1.25 perseant ++acc; 733 1.25 perseant } 734 1.25 perseant free(buf); 735 1.25 perseant if (acc != numblocks) 736 1.25 perseant printf("** counted %d blocks but should have been %d\n", 737 1.25 perseant acc, numblocks); 738 1.25 perseant datasum = cksum(datap, numblocks * el_size); 739 1.52 dholland if (datasum != lfs_ss_getdatasum(lfsp, sp)) 740 1.52 dholland printf("** computed datasum 0x%lx does not match given datasum 0x%lx\n", (unsigned long)datasum, (unsigned long)lfs_ss_getdatasum(lfsp, sp)); 741 1.25 perseant free(datap); 742 1.25 perseant 743 1.8 fvdl return (numbytes); 744 1.1 mycroft } 745 1.1 mycroft 746 1.1 mycroft static void 747 1.19 perseant dump_segment(int fd, int segnum, daddr_t addr, struct lfs *lfsp, int dump_sb) 748 1.1 mycroft { 749 1.1 mycroft struct lfs lfs_sb, *sbp; 750 1.1 mycroft SEGSUM *sump; 751 1.52 dholland size_t sumstart; 752 1.19 perseant char *sumblock; 753 1.8 fvdl int did_one, nbytes, sb; 754 1.14 perseant off_t sum_offset; 755 1.14 perseant daddr_t new_addr; 756 1.1 mycroft 757 1.20 fvdl (void)printf("\nSEGMENT %lld (Disk Address 0x%llx)\n", 758 1.41 christos (long long)lfs_dtosn(lfsp, addr), (long long)addr); 759 1.19 perseant sum_offset = fsbtobyte(lfsp, addr); 760 1.64 christos sumblock = emalloc(lfs_sb_getsumsize(lfsp)); 761 1.19 perseant 762 1.48 dholland if (lfs_sb_getversion(lfsp) > 1 && segnum == 0) { 763 1.44 dholland if (lfs_fsbtob(lfsp, lfs_sb_gets0addr(lfsp)) < LFS_LABELPAD) { 764 1.24 perseant /* First segment eats the disklabel */ 765 1.41 christos sum_offset += lfs_fragroundup(lfsp, LFS_LABELPAD) - 766 1.44 dholland lfs_fsbtob(lfsp, lfs_sb_gets0addr(lfsp)); 767 1.41 christos addr += lfs_btofsb(lfsp, lfs_fragroundup(lfsp, LFS_LABELPAD)) - 768 1.44 dholland lfs_sb_gets0addr(lfsp); 769 1.24 perseant printf("Disklabel at 0x0\n"); 770 1.24 perseant } 771 1.19 perseant } 772 1.1 mycroft 773 1.1 mycroft sb = 0; 774 1.1 mycroft did_one = 0; 775 1.1 mycroft do { 776 1.43 dholland get(fd, sum_offset, sumblock, lfs_sb_getsumsize(lfsp)); 777 1.1 mycroft sump = (SEGSUM *)sumblock; 778 1.52 dholland sumstart = lfs_ss_getsumstart(lfsp); 779 1.48 dholland if ((lfs_sb_getversion(lfsp) > 1 && 780 1.52 dholland lfs_ss_getident(lfsp, sump) != lfs_sb_getident(lfsp)) || 781 1.52 dholland lfs_ss_getsumsum(lfsp, sump) != 782 1.52 dholland cksum((char *)sump + sumstart, 783 1.52 dholland lfs_sb_getsumsize(lfsp) - sumstart)) { 784 1.1 mycroft sbp = (struct lfs *)sump; 785 1.49 dholland if ((sb = (sbp->lfs_dlfs_u.u_32.dlfs_magic == LFS_MAGIC))) { 786 1.19 perseant printf("Superblock at 0x%x\n", 787 1.41 christos (unsigned)lfs_btofsb(lfsp, sum_offset)); 788 1.14 perseant if (dump_sb) { 789 1.49 dholland __CTASSERT(sizeof(struct dlfs) == 790 1.49 dholland sizeof(struct dlfs64)); 791 1.49 dholland get(fd, sum_offset, &(lfs_sb.lfs_dlfs_u), 792 1.14 perseant sizeof(struct dlfs)); 793 1.14 perseant dump_super(&lfs_sb); 794 1.14 perseant } 795 1.48 dholland if (lfs_sb_getversion(lfsp) > 1) 796 1.41 christos sum_offset += lfs_fragroundup(lfsp, LFS_SBPAD); 797 1.19 perseant else 798 1.19 perseant sum_offset += LFS_SBPAD; 799 1.1 mycroft } else if (did_one) 800 1.1 mycroft break; 801 1.1 mycroft else { 802 1.20 fvdl printf("Segment at 0x%llx empty or corrupt\n", 803 1.20 fvdl (long long)addr); 804 1.1 mycroft break; 805 1.1 mycroft } 806 1.1 mycroft } else { 807 1.19 perseant nbytes = dump_sum(fd, lfsp, sump, segnum, 808 1.41 christos lfs_btofsb(lfsp, sum_offset)); 809 1.34 perseant if (nbytes >= 0) 810 1.43 dholland sum_offset += lfs_sb_getsumsize(lfsp) + nbytes; 811 1.1 mycroft else 812 1.1 mycroft sum_offset = 0; 813 1.1 mycroft did_one = 1; 814 1.1 mycroft } 815 1.14 perseant /* If the segment ends right on a boundary, it still ends */ 816 1.41 christos new_addr = lfs_btofsb(lfsp, sum_offset); 817 1.19 perseant /* printf("end daddr = 0x%lx\n", (long)new_addr); */ 818 1.41 christos if (lfs_dtosn(lfsp, new_addr) != lfs_dtosn(lfsp, addr)) 819 1.14 perseant break; 820 1.1 mycroft } while (sum_offset); 821 1.1 mycroft 822 1.30 dsl free(sumblock); 823 1.1 mycroft } 824 1.1 mycroft 825 1.1 mycroft static void 826 1.19 perseant dump_super(struct lfs *lfsp) 827 1.1 mycroft { 828 1.43 dholland time_t stamp; 829 1.1 mycroft int i; 830 1.1 mycroft 831 1.46 dholland (void)printf(" %s0x%-8x %s0x%-8x %s%-10ju\n", 832 1.49 dholland "magic ", lfsp->lfs_dlfs_u.u_32.dlfs_magic, 833 1.48 dholland "version ", lfs_sb_getversion(lfsp), 834 1.46 dholland "size ", (uintmax_t)lfs_sb_getsize(lfsp)); 835 1.46 dholland (void)printf(" %s%-10d %s%-10ju %s%-10d\n", 836 1.43 dholland "ssize ", lfs_sb_getssize(lfsp), 837 1.46 dholland "dsize ", (uintmax_t)lfs_sb_getdsize(lfsp), 838 1.43 dholland "bsize ", lfs_sb_getbsize(lfsp)); 839 1.19 perseant (void)printf(" %s%-10d %s%-10d %s%-10d\n", 840 1.43 dholland "fsize ", lfs_sb_getfsize(lfsp), 841 1.43 dholland "frag ", lfs_sb_getfrag(lfsp), 842 1.43 dholland "minfree ", lfs_sb_getminfree(lfsp)); 843 1.19 perseant (void)printf(" %s%-10d %s%-10d %s%-10d\n", 844 1.43 dholland "inopb ", lfs_sb_getinopb(lfsp), 845 1.43 dholland "ifpb ", lfs_sb_getifpb(lfsp), 846 1.43 dholland "nindir ", lfs_sb_getnindir(lfsp)); 847 1.19 perseant (void)printf(" %s%-10d %s%-10d %s%-10d\n", 848 1.43 dholland "nseg ", lfs_sb_getnseg(lfsp), 849 1.43 dholland "sepb ", lfs_sb_getsepb(lfsp), 850 1.43 dholland "cleansz ", lfs_sb_getcleansz(lfsp)); 851 1.19 perseant (void)printf(" %s%-10d %s0x%-8x %s%-10d\n", 852 1.43 dholland "segtabsz ", lfs_sb_getsegtabsz(lfsp), 853 1.43 dholland "segmask ", lfs_sb_getsegmask(lfsp), 854 1.43 dholland "segshift ", lfs_sb_getsegshift(lfsp)); 855 1.43 dholland (void)printf(" %s0x%-8jx %s%-10d %s0x%-8jX\n", 856 1.43 dholland "bmask ", (uintmax_t)lfs_sb_getbmask(lfsp), 857 1.43 dholland "bshift ", lfs_sb_getbshift(lfsp), 858 1.43 dholland "ffmask ", (uintmax_t)lfs_sb_getffmask(lfsp)); 859 1.43 dholland (void)printf(" %s%-10d %s0x%-8jx %s%u\n", 860 1.43 dholland "ffshift ", lfs_sb_getffshift(lfsp), 861 1.43 dholland "fbmask ", (uintmax_t)lfs_sb_getfbmask(lfsp), 862 1.43 dholland "fbshift ", lfs_sb_getfbshift(lfsp)); 863 1.19 perseant 864 1.19 perseant (void)printf(" %s%-10d %s%-10d %s0x%-8x\n", 865 1.43 dholland "sushift ", lfs_sb_getsushift(lfsp), 866 1.43 dholland "fsbtodb ", lfs_sb_getfsbtodb(lfsp), 867 1.43 dholland "cksum ", lfs_sb_getcksum(lfsp)); 868 1.19 perseant (void)printf(" %s%-10d %s%-10d %s%-10d\n", 869 1.43 dholland "nclean ", lfs_sb_getnclean(lfsp), 870 1.43 dholland "dmeta ", lfs_sb_getdmeta(lfsp), 871 1.43 dholland "minfreeseg ", lfs_sb_getminfreeseg(lfsp)); 872 1.19 perseant (void)printf(" %s0x%-8x %s%-9d %s%-10d\n", 873 1.43 dholland "roll_id ", lfs_sb_getident(lfsp), 874 1.43 dholland "interleave ", lfs_sb_getinterleave(lfsp), 875 1.43 dholland "sumsize ", lfs_sb_getsumsize(lfsp)); 876 1.47 dholland (void)printf(" %s%-10jd %s0x%-8jx\n", 877 1.47 dholland "seg0addr ", (intmax_t)lfs_sb_gets0addr(lfsp), 878 1.43 dholland "maxfilesize ", (uintmax_t)lfs_sb_getmaxfilesize(lfsp)); 879 1.19 perseant 880 1.19 perseant 881 1.19 perseant (void)printf(" Superblock disk addresses:\n "); 882 1.19 perseant for (i = 0; i < LFS_MAXNUMSB; i++) { 883 1.47 dholland (void)printf(" 0x%-8jx", (intmax_t)lfs_sb_getsboff(lfsp, i)); 884 1.19 perseant if (i == (LFS_MAXNUMSB >> 1)) 885 1.19 perseant (void)printf("\n "); 886 1.19 perseant } 887 1.19 perseant (void)printf("\n"); 888 1.19 perseant 889 1.19 perseant (void)printf(" Checkpoint Info\n"); 890 1.57 dholland (void)printf(" %s%-10ju %s0x%-8jx\n", 891 1.56 dholland "freehd ", (uintmax_t)lfs_sb_getfreehd(lfsp), 892 1.57 dholland "idaddr ", (intmax_t)lfs_sb_getidaddr(lfsp)); 893 1.46 dholland (void)printf(" %s%-10d %s%-10jd %s%-10jd\n", 894 1.43 dholland "uinodes ", lfs_sb_getuinodes(lfsp), 895 1.46 dholland "bfree ", (intmax_t)lfs_sb_getbfree(lfsp), 896 1.46 dholland "avail ", (intmax_t)lfs_sb_getavail(lfsp)); 897 1.56 dholland (void)printf(" %s%-10ju %s0x%-8jx %s0x%-8jx\n", 898 1.56 dholland "nfiles ", (uintmax_t)lfs_sb_getnfiles(lfsp), 899 1.47 dholland "lastseg ", (uintmax_t)lfs_sb_getlastseg(lfsp), 900 1.47 dholland "nextseg ", (uintmax_t)lfs_sb_getnextseg(lfsp)); 901 1.47 dholland (void)printf(" %s0x%-8jx %s0x%-8jx %s%-10ju\n", 902 1.47 dholland "curseg ", (uintmax_t)lfs_sb_getcurseg(lfsp), 903 1.47 dholland "offset ", (uintmax_t)lfs_sb_getoffset(lfsp), 904 1.43 dholland "serial ", (uintmax_t)lfs_sb_getserial(lfsp)); 905 1.43 dholland stamp = lfs_sb_gettstamp(lfsp); 906 1.43 dholland (void)printf(" tstamp %s", ctime(&stamp)); 907 1.57 dholland 908 1.57 dholland if (!lfsp->lfs_is64) { 909 1.57 dholland (void)printf(" 32-bit only derived or constant fields\n"); 910 1.57 dholland (void)printf(" %s%-10u\n", 911 1.57 dholland "ifile ", lfs_sb_getifile(lfsp)); 912 1.57 dholland } 913 1.1 mycroft } 914 1.1 mycroft 915 1.1 mycroft static void 916 1.19 perseant addseg(char *arg) 917 1.1 mycroft { 918 1.1 mycroft SEGLIST *p; 919 1.1 mycroft 920 1.64 christos p = emalloc(sizeof(*p)); 921 1.1 mycroft p->next = seglist; 922 1.1 mycroft p->num = atoi(arg); 923 1.1 mycroft seglist = p; 924 1.1 mycroft } 925 1.1 mycroft 926 1.1 mycroft static void 927 1.19 perseant dump_cleaner_info(struct lfs *lfsp, void *ipage) 928 1.1 mycroft { 929 1.1 mycroft CLEANERINFO *cip; 930 1.1 mycroft 931 1.1 mycroft cip = (CLEANERINFO *)ipage; 932 1.48 dholland if (lfs_sb_getversion(lfsp) > 1) { 933 1.50 dholland (void)printf("free_head %ju\n", 934 1.50 dholland (uintmax_t)lfs_ci_getfree_head(lfsp, cip)); 935 1.50 dholland (void)printf("free_tail %ju\n", 936 1.50 dholland (uintmax_t)lfs_ci_getfree_tail(lfsp, cip)); 937 1.50 dholland } 938 1.50 dholland (void)printf("clean\t%u\tdirty\t%u\n", 939 1.50 dholland lfs_ci_getclean(lfsp, cip), lfs_ci_getdirty(lfsp, cip)); 940 1.50 dholland (void)printf("bfree\t%jd\tavail\t%jd\n\n", 941 1.50 dholland (intmax_t)lfs_ci_getbfree(lfsp, cip), 942 1.50 dholland (intmax_t)lfs_ci_getavail(lfsp, cip)); 943 1.1 mycroft } 944 1.1 mycroft 945 1.1 mycroft static void 946 1.67 perseant dump_inoblk(int fd, struct lfs *lfsp, daddr_t daddr, ino_t ino) 947 1.67 perseant { 948 1.67 perseant char *buf; 949 1.67 perseant union lfs_dinode *dip; 950 1.67 perseant ino_t dino; 951 1.67 perseant int i; 952 1.67 perseant 953 1.67 perseant buf = emalloc(lfs_sb_getfsize(lfsp)); 954 1.67 perseant get(fd, lfs_fsbtob(lfsp, daddr), buf, lfs_sb_getfsize(lfsp)); 955 1.67 perseant for (i = 0; i < LFS_INOPB(lfsp); ++i) { 956 1.67 perseant dip = DINO_IN_BLOCK(lfsp, buf, i); 957 1.67 perseant dino = lfs_dino_getinumber(lfsp, dip); 958 1.67 perseant if (dino == 0) 959 1.67 perseant continue; 960 1.67 perseant else if (ino == 0 || ino == dino) { 961 1.67 perseant (void)printf("Addr 0x%jx entry %d inode %jd:\n", 962 1.67 perseant (intmax_t)daddr, i, (intmax_t)dino); 963 1.67 perseant dump_dinode(lfsp, dip); 964 1.67 perseant } 965 1.67 perseant } 966 1.67 perseant } 967 1.67 perseant 968 1.67 perseant 969 1.67 perseant static void 970 1.19 perseant usage(void) 971 1.1 mycroft { 972 1.27 wiz (void)fprintf(stderr, "usage: dumplfs [-adiS] [-b blkno] [-I blkno] [-s segno] filesys|device\n"); 973 1.1 mycroft exit(1); 974 1.1 mycroft } 975