1 /* 2 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. 3 */ 4 5 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 6 /* All Rights Reserved */ 7 8 /* 9 * Copyright (c) 1980, 1986, 1990 The Regents of the University of California. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms are permitted 13 * provided that: (1) source distributions retain this entire copyright 14 * notice and comment, and (2) distributions including binaries display 15 * the following acknowledgement: ``This product includes software 16 * developed by the University of California, Berkeley and its contributors'' 17 * in the documentation or other materials provided with the distribution 18 * and in all advertising materials mentioning features or use of this 19 * software. Neither the name of the University nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 25 */ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <unistd.h> 30 #include <stdarg.h> 31 #include <libadm.h> 32 #include <note.h> 33 #include <sys/param.h> 34 #include <sys/types.h> 35 #include <sys/mntent.h> 36 #include <sys/filio.h> 37 #include <sys/fs/ufs_fs.h> 38 #include <sys/vnode.h> 39 #include <sys/fs/ufs_acl.h> 40 #include <sys/fs/ufs_inode.h> 41 #include <sys/fs/ufs_log.h> 42 #define _KERNEL 43 #include <sys/fs/ufs_fsdir.h> 44 #undef _KERNEL 45 #include <sys/mnttab.h> 46 #include <sys/types.h> 47 #include <sys/stat.h> 48 #include <fcntl.h> 49 #include <signal.h> 50 #include <string.h> 51 #include <ctype.h> 52 #include <sys/vfstab.h> 53 #include <sys/lockfs.h> 54 #include <errno.h> 55 #include <sys/cmn_err.h> 56 #include <sys/dkio.h> 57 #include <sys/vtoc.h> 58 #include <sys/efi_partition.h> 59 #include <fslib.h> 60 #include <inttypes.h> 61 #include "fsck.h" 62 63 caddr_t mount_point = NULL; 64 65 static int64_t diskreads, totalreads; /* Disk cache statistics */ 66 67 static int log_checksum(int32_t *, int32_t *, int); 68 static void vdirerror(fsck_ino_t, caddr_t, va_list); 69 static struct mnttab *search_mnttab(caddr_t, caddr_t, caddr_t, size_t); 70 static struct vfstab *search_vfstab(caddr_t, caddr_t, caddr_t, size_t); 71 static void vpwarn(caddr_t, va_list); 72 static int getaline(FILE *, caddr_t, int); 73 static struct bufarea *alloc_bufarea(void); 74 static void rwerror(caddr_t, diskaddr_t, int rval); 75 static void debugclean(void); 76 static void report_io_prob(caddr_t, diskaddr_t, size_t, ssize_t); 77 static void freelogblk(daddr32_t); 78 static void verrexit(caddr_t, va_list); 79 static void vpfatal(caddr_t, va_list); 80 static diskaddr_t get_device_size(int, caddr_t); 81 static diskaddr_t brute_force_get_device_size(int); 82 static void cg_constants(int, daddr32_t *, daddr32_t *, daddr32_t *, 83 daddr32_t *, daddr32_t *, daddr32_t *); 84 85 int 86 ftypeok(struct dinode *dp) 87 { 88 switch (dp->di_mode & IFMT) { 89 90 case IFDIR: 91 case IFREG: 92 case IFBLK: 93 case IFCHR: 94 case IFLNK: 95 case IFSOCK: 96 case IFIFO: 97 case IFSHAD: 98 case IFATTRDIR: 99 return (1); 100 101 default: 102 if (debug) 103 (void) printf("bad file type 0%o\n", dp->di_mode); 104 return (0); 105 } 106 } 107 108 int 109 acltypeok(struct dinode *dp) 110 { 111 if (CHECK_ACL_ALLOWED(dp->di_mode & IFMT)) 112 return (1); 113 114 if (debug) 115 (void) printf("bad file type for acl I=%d: 0%o\n", 116 dp->di_shadow, dp->di_mode); 117 return (0); 118 } 119 120 NOTE(PRINTFLIKE(1)) 121 int 122 reply(caddr_t fmt, ...) 123 { 124 va_list ap; 125 char line[80]; 126 127 if (preen) 128 pfatal("INTERNAL ERROR: GOT TO reply() in preen mode"); 129 130 if (mflag) { 131 /* 132 * We don't know what's going on, so don't potentially 133 * make things worse by having errexit() write stuff 134 * out to disk. 135 */ 136 (void) printf( 137 "\n%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", 138 devname); 139 exit(EXERRFATAL); 140 } 141 142 va_start(ap, fmt); 143 (void) putchar('\n'); 144 (void) vprintf(fmt, ap); 145 (void) putchar('?'); 146 (void) putchar(' '); 147 va_end(ap); 148 149 if (nflag || fswritefd < 0) { 150 (void) printf(" no\n\n"); 151 return (0); 152 } 153 if (yflag) { 154 (void) printf(" yes\n\n"); 155 return (1); 156 } 157 (void) fflush(stdout); 158 if (getaline(stdin, line, sizeof (line)) == EOF) 159 errexit("\n"); 160 (void) printf("\n"); 161 if (line[0] == 'y' || line[0] == 'Y') { 162 return (1); 163 } else { 164 return (0); 165 } 166 } 167 168 int 169 getaline(FILE *fp, caddr_t loc, int maxlen) 170 { 171 int n; 172 caddr_t p, lastloc; 173 174 p = loc; 175 lastloc = &p[maxlen-1]; 176 while ((n = getc(fp)) != '\n') { 177 if (n == EOF) 178 return (EOF); 179 if (!isspace(n) && p < lastloc) 180 *p++ = (char)n; 181 } 182 *p = '\0'; 183 /* LINTED pointer difference won't overflow */ 184 return (p - loc); 185 } 186 187 /* 188 * Malloc buffers and set up cache. 189 */ 190 void 191 bufinit(void) 192 { 193 struct bufarea *bp; 194 int bufcnt, i; 195 caddr_t bufp; 196 197 bufp = malloc((size_t)sblock.fs_bsize); 198 if (bufp == NULL) 199 goto nomem; 200 initbarea(&cgblk); 201 cgblk.b_un.b_buf = bufp; 202 bufhead.b_next = bufhead.b_prev = &bufhead; 203 bufcnt = MAXBUFSPACE / sblock.fs_bsize; 204 if (bufcnt < MINBUFS) 205 bufcnt = MINBUFS; 206 for (i = 0; i < bufcnt; i++) { 207 bp = (struct bufarea *)malloc(sizeof (struct bufarea)); 208 if (bp == NULL) { 209 if (i >= MINBUFS) 210 goto noalloc; 211 goto nomem; 212 } 213 214 bufp = malloc((size_t)sblock.fs_bsize); 215 if (bufp == NULL) { 216 free((void *)bp); 217 if (i >= MINBUFS) 218 goto noalloc; 219 goto nomem; 220 } 221 initbarea(bp); 222 bp->b_un.b_buf = bufp; 223 bp->b_prev = &bufhead; 224 bp->b_next = bufhead.b_next; 225 bufhead.b_next->b_prev = bp; 226 bufhead.b_next = bp; 227 } 228 noalloc: 229 bufhead.b_size = i; /* save number of buffers */ 230 pbp = pdirbp = NULL; 231 return; 232 233 nomem: 234 errexit("cannot allocate buffer pool\n"); 235 /* NOTREACHED */ 236 } 237 238 /* 239 * Undo a bufinit(). 240 */ 241 void 242 unbufinit(void) 243 { 244 int cnt; 245 struct bufarea *bp, *nbp; 246 247 cnt = 0; 248 for (bp = bufhead.b_prev; bp != NULL && bp != &bufhead; bp = nbp) { 249 cnt++; 250 flush(fswritefd, bp); 251 nbp = bp->b_prev; 252 /* 253 * We're discarding the entire chain, so this isn't 254 * technically necessary. However, it doesn't hurt 255 * and lint's data flow analysis is much happier 256 * (this prevents it from thinking there's a chance 257 * of our using memory elsewhere after it's been released). 258 */ 259 nbp->b_next = bp->b_next; 260 bp->b_next->b_prev = nbp; 261 free((void *)bp->b_un.b_buf); 262 free((void *)bp); 263 } 264 265 if (bufhead.b_size != cnt) 266 errexit("Panic: cache lost %d buffers\n", 267 bufhead.b_size - cnt); 268 } 269 270 /* 271 * Manage a cache of directory blocks. 272 */ 273 struct bufarea * 274 getdatablk(daddr32_t blkno, size_t size) 275 { 276 struct bufarea *bp; 277 278 for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next) 279 if (bp->b_bno == fsbtodb(&sblock, blkno)) { 280 goto foundit; 281 } 282 for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev) 283 if ((bp->b_flags & B_INUSE) == 0) 284 break; 285 if (bp == &bufhead) { 286 bp = alloc_bufarea(); 287 if (bp == NULL) { 288 errexit("deadlocked buffer pool\n"); 289 /* NOTREACHED */ 290 } 291 } 292 /* 293 * We're at the same logical level as getblk(), so if there 294 * are any errors, we'll let our caller handle them. 295 */ 296 diskreads++; 297 (void) getblk(bp, blkno, size); 298 299 foundit: 300 totalreads++; 301 bp->b_cnt++; 302 /* 303 * Move the buffer to head of linked list if it isn't 304 * already there. 305 */ 306 if (bufhead.b_next != bp) { 307 bp->b_prev->b_next = bp->b_next; 308 bp->b_next->b_prev = bp->b_prev; 309 bp->b_prev = &bufhead; 310 bp->b_next = bufhead.b_next; 311 bufhead.b_next->b_prev = bp; 312 bufhead.b_next = bp; 313 } 314 bp->b_flags |= B_INUSE; 315 return (bp); 316 } 317 318 void 319 brelse(struct bufarea *bp) 320 { 321 bp->b_cnt--; 322 if (bp->b_cnt == 0) { 323 bp->b_flags &= ~B_INUSE; 324 } 325 } 326 327 struct bufarea * 328 getblk(struct bufarea *bp, daddr32_t blk, size_t size) 329 { 330 diskaddr_t dblk; 331 332 dblk = fsbtodb(&sblock, blk); 333 if (bp->b_bno == dblk) 334 return (bp); 335 flush(fswritefd, bp); 336 bp->b_errs = fsck_bread(fsreadfd, bp->b_un.b_buf, dblk, size); 337 bp->b_bno = dblk; 338 bp->b_size = size; 339 return (bp); 340 } 341 342 void 343 flush(int fd, struct bufarea *bp) 344 { 345 int i, j; 346 caddr_t sip; 347 long size; 348 349 if (!bp->b_dirty) 350 return; 351 352 /* 353 * It's not our buf, so if there are errors, let whoever 354 * acquired it deal with the actual problem. 355 */ 356 if (bp->b_errs != 0) 357 pfatal("WRITING ZERO'ED BLOCK %lld TO DISK\n", bp->b_bno); 358 bp->b_dirty = 0; 359 bp->b_errs = 0; 360 bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size); 361 if (bp != &sblk) { 362 return; 363 } 364 365 /* 366 * We're flushing the superblock, so make sure all the 367 * ancillary bits go out as well. 368 */ 369 sip = (caddr_t)sblock.fs_u.fs_csp; 370 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 371 size = sblock.fs_cssize - i < sblock.fs_bsize ? 372 sblock.fs_cssize - i : sblock.fs_bsize; 373 bwrite(fswritefd, sip, 374 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 375 size); 376 sip += size; 377 } 378 } 379 380 static void 381 rwerror(caddr_t mesg, diskaddr_t blk, int rval) 382 { 383 int olderr = errno; 384 385 if (!preen) 386 (void) printf("\n"); 387 388 if (rval == -1) 389 pfatal("CANNOT %s: DISK BLOCK %lld: %s", 390 mesg, blk, strerror(olderr)); 391 else 392 pfatal("CANNOT %s: DISK BLOCK %lld", mesg, blk); 393 394 if (reply("CONTINUE") == 0) { 395 exitstat = EXERRFATAL; 396 errexit("Program terminated\n"); 397 } 398 } 399 400 void 401 ckfini(void) 402 { 403 int64_t percentage; 404 405 if (fswritefd < 0) 406 return; 407 408 flush(fswritefd, &sblk); 409 /* 410 * Were we using a backup superblock? 411 */ 412 if (havesb && sblk.b_bno != SBOFF / dev_bsize) { 413 if (preen || reply("UPDATE STANDARD SUPERBLOCK") == 1) { 414 sblk.b_bno = SBOFF / dev_bsize; 415 sbdirty(); 416 flush(fswritefd, &sblk); 417 } 418 } 419 flush(fswritefd, &cgblk); 420 if (cgblk.b_un.b_buf != NULL) { 421 free((void *)cgblk.b_un.b_buf); 422 cgblk.b_un.b_buf = NULL; 423 } 424 unbufinit(); 425 pbp = NULL; 426 pdirbp = NULL; 427 if (debug) { 428 /* 429 * Note that we only count cache-related reads. 430 * Anything that called fsck_bread() or getblk() 431 * directly are explicitly not cached, so they're not 432 * included here. 433 */ 434 if (totalreads != 0) 435 percentage = diskreads * 100 / totalreads; 436 else 437 percentage = 0; 438 439 (void) printf("cache missed %lld of %lld reads (%lld%%)\n", 440 (longlong_t)diskreads, (longlong_t)totalreads, 441 (longlong_t)percentage); 442 } 443 444 (void) close(fsreadfd); 445 (void) close(fswritefd); 446 fsreadfd = -1; 447 fswritefd = -1; 448 } 449 450 int 451 fsck_bread(int fd, caddr_t buf, diskaddr_t blk, size_t size) 452 { 453 caddr_t cp; 454 int i; 455 int errs; 456 offset_t offset = ldbtob(blk); 457 offset_t addr; 458 459 /* 460 * In our universe, nothing exists before the superblock, so 461 * just pretend it's always zeros. This is the complement of 462 * bwrite()'s ignoring write requests into that space. 463 */ 464 if (blk < SBLOCK) { 465 if (debug) 466 (void) printf( 467 "WARNING: fsck_bread() passed blkno < %d (%lld)\n", 468 SBLOCK, (longlong_t)blk); 469 (void) memset(buf, 0, (size_t)size); 470 return (1); 471 } 472 473 if (llseek(fd, offset, SEEK_SET) < 0) { 474 rwerror("SEEK", blk, -1); 475 } 476 477 if ((i = read(fd, buf, size)) == size) { 478 return (0); 479 } 480 rwerror("READ", blk, i); 481 if (llseek(fd, offset, SEEK_SET) < 0) { 482 rwerror("SEEK", blk, -1); 483 } 484 errs = 0; 485 (void) memset(buf, 0, (size_t)size); 486 pwarn("THE FOLLOWING SECTORS COULD NOT BE READ:"); 487 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) { 488 addr = ldbtob(blk + i); 489 if (llseek(fd, addr, SEEK_SET) < 0 || 490 read(fd, cp, (int)secsize) < 0) { 491 iscorrupt = 1; 492 (void) printf(" %llu", blk + (u_longlong_t)i); 493 errs++; 494 } 495 } 496 (void) printf("\n"); 497 return (errs); 498 } 499 500 void 501 bwrite(int fd, caddr_t buf, diskaddr_t blk, int64_t size) 502 { 503 int i; 504 int n; 505 caddr_t cp; 506 offset_t offset = ldbtob(blk); 507 offset_t addr; 508 509 if (fd < 0) 510 return; 511 if (blk < SBLOCK) { 512 if (debug) 513 (void) printf( 514 "WARNING: Attempt to write illegal blkno %lld on %s\n", 515 (longlong_t)blk, devname); 516 return; 517 } 518 if (llseek(fd, offset, SEEK_SET) < 0) { 519 rwerror("SEEK", blk, -1); 520 } 521 if ((i = write(fd, buf, (int)size)) == size) { 522 fsmodified = 1; 523 return; 524 } 525 rwerror("WRITE", blk, i); 526 if (llseek(fd, offset, SEEK_SET) < 0) { 527 rwerror("SEEK", blk, -1); 528 } 529 pwarn("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:"); 530 for (cp = buf, i = 0; i < btodb(size); i++, cp += DEV_BSIZE) { 531 n = 0; 532 addr = ldbtob(blk + i); 533 if (llseek(fd, addr, SEEK_SET) < 0 || 534 (n = write(fd, cp, DEV_BSIZE)) < 0) { 535 iscorrupt = 1; 536 (void) printf(" %llu", blk + (u_longlong_t)i); 537 } else if (n > 0) { 538 fsmodified = 1; 539 } 540 541 } 542 (void) printf("\n"); 543 } 544 545 /* 546 * Allocates the specified number of contiguous fragments. 547 */ 548 daddr32_t 549 allocblk(int wantedfrags) 550 { 551 int block, leadfrag, tailfrag; 552 daddr32_t selected; 553 size_t size; 554 struct bufarea *bp; 555 556 /* 557 * It's arguable whether we should just fail, or instead 558 * error out here. Since we should only ever be asked for 559 * a single fragment or an entire block (i.e., sblock.fs_frag), 560 * we'll fail out because anything else means somebody 561 * changed code without considering all of the ramifications. 562 */ 563 if (wantedfrags <= 0 || wantedfrags > sblock.fs_frag) { 564 exitstat = EXERRFATAL; 565 errexit("allocblk() asked for %d frags. " 566 "Legal range is 1 to %d", 567 wantedfrags, sblock.fs_frag); 568 } 569 570 /* 571 * For each filesystem block, look at every possible starting 572 * offset within the block such that we can get the number of 573 * contiguous fragments that we need. This is a drastically 574 * simplified version of the kernel's mapsearch() and alloc*(). 575 * It's also correspondingly slower. 576 */ 577 for (block = 0; block < maxfsblock - sblock.fs_frag; 578 block += sblock.fs_frag) { 579 for (leadfrag = 0; leadfrag <= sblock.fs_frag - wantedfrags; 580 leadfrag++) { 581 /* 582 * Is first fragment of candidate run available? 583 */ 584 if (testbmap(block + leadfrag)) 585 continue; 586 /* 587 * Are the rest of them available? 588 */ 589 for (tailfrag = 1; tailfrag < wantedfrags; tailfrag++) 590 if (testbmap(block + leadfrag + tailfrag)) 591 break; 592 if (tailfrag < wantedfrags) { 593 /* 594 * No, skip the known-unusable run. 595 */ 596 leadfrag += tailfrag; 597 continue; 598 } 599 /* 600 * Found what we need, so claim them. 601 */ 602 for (tailfrag = 0; tailfrag < wantedfrags; tailfrag++) 603 setbmap(block + leadfrag + tailfrag); 604 n_blks += wantedfrags; 605 size = wantedfrags * sblock.fs_fsize; 606 selected = block + leadfrag; 607 bp = getdatablk(selected, size); 608 (void) memset((void *)bp->b_un.b_buf, 0, size); 609 dirty(bp); 610 brelse(bp); 611 if (debug) 612 (void) printf( 613 "allocblk: selected %d (in block %d), frags %d, size %d\n", 614 selected, selected % sblock.fs_bsize, 615 wantedfrags, (int)size); 616 return (selected); 617 } 618 } 619 return (0); 620 } 621 622 /* 623 * Free a previously allocated block 624 */ 625 void 626 freeblk(fsck_ino_t ino, daddr32_t blkno, int frags) 627 { 628 struct inodesc idesc; 629 630 if (debug) 631 (void) printf("debug: freeing %d fragments starting at %d\n", 632 frags, blkno); 633 634 init_inodesc(&idesc); 635 636 idesc.id_number = ino; 637 idesc.id_blkno = blkno; 638 idesc.id_numfrags = frags; 639 idesc.id_truncto = -1; 640 641 /* 642 * Nothing in the return status has any relevance to how 643 * we're using pass4check(), so just ignore it. 644 */ 645 (void) pass4check(&idesc); 646 } 647 648 /* 649 * Fill NAMEBUF with a path starting in CURDIR for INO. Assumes 650 * that the given buffer is at least MAXPATHLEN + 1 characters. 651 */ 652 void 653 getpathname(caddr_t namebuf, fsck_ino_t curdir, fsck_ino_t ino) 654 { 655 int len; 656 caddr_t cp; 657 struct dinode *dp; 658 struct inodesc idesc; 659 struct inoinfo *inp; 660 661 if (debug) 662 (void) printf("debug: getpathname(curdir %d, ino %d)\n", 663 curdir, ino); 664 665 if ((curdir == 0) || (!INO_IS_DVALID(curdir))) { 666 (void) strcpy(namebuf, "?"); 667 return; 668 } 669 670 if ((curdir == UFSROOTINO) && (ino == UFSROOTINO)) { 671 (void) strcpy(namebuf, "/"); 672 return; 673 } 674 675 init_inodesc(&idesc); 676 idesc.id_type = DATA; 677 cp = &namebuf[MAXPATHLEN - 1]; 678 *cp = '\0'; 679 680 /* 681 * In the case of extended attributes, our 682 * parent won't necessarily be a directory, so just 683 * return what we've found with a prefix indicating 684 * that it's an XATTR. Presumably our caller will 685 * know what's going on and do something useful, like 686 * work out the path of the parent and then combine 687 * the two names. 688 * 689 * Can't use strcpy(), etc, because we've probably 690 * already got some name information in the buffer and 691 * the usual trailing \0 would lose it. 692 */ 693 dp = ginode(curdir); 694 if ((dp->di_mode & IFMT) == IFATTRDIR) { 695 idesc.id_number = curdir; 696 idesc.id_parent = ino; 697 idesc.id_func = findname; 698 idesc.id_name = namebuf; 699 idesc.id_fix = NOFIX; 700 if ((ckinode(dp, &idesc, CKI_TRAVERSE) & FOUND) == 0) { 701 *cp-- = '?'; 702 } 703 704 len = sizeof (XATTR_DIR_NAME) - 1; 705 cp -= len; 706 (void) memmove(cp, XATTR_DIR_NAME, len); 707 goto attrname; 708 } 709 710 /* 711 * If curdir == ino, need to get a handle on .. so we 712 * can search it for ino's name. Otherwise, just search 713 * the given directory for ino. Repeat until out of space 714 * or a full path has been built. 715 */ 716 if (curdir != ino) { 717 idesc.id_parent = curdir; 718 goto namelookup; 719 } 720 while (ino != UFSROOTINO && ino != 0) { 721 idesc.id_number = ino; 722 idesc.id_func = findino; 723 idesc.id_name = ".."; 724 idesc.id_fix = NOFIX; 725 if ((ckinode(ginode(ino), &idesc, CKI_TRAVERSE) & FOUND) == 0) { 726 inp = getinoinfo(ino); 727 if ((inp == NULL) || (inp->i_parent == 0)) { 728 break; 729 } 730 idesc.id_parent = inp->i_parent; 731 } 732 733 /* 734 * To get this far, id_parent must have the inode 735 * number for `..' in it. By definition, that's got 736 * to be a directory, so search it for the inode of 737 * interest. 738 */ 739 namelookup: 740 idesc.id_number = idesc.id_parent; 741 idesc.id_parent = ino; 742 idesc.id_func = findname; 743 idesc.id_name = namebuf; 744 idesc.id_fix = NOFIX; 745 if ((ckinode(ginode(idesc.id_number), 746 &idesc, CKI_TRAVERSE) & FOUND) == 0) { 747 break; 748 } 749 /* 750 * Prepend to what we've accumulated so far. If 751 * there's not enough room for even one more path element 752 * (of the worst-case length), then bail out. 753 */ 754 len = strlen(namebuf); 755 cp -= len; 756 if (cp < &namebuf[MAXNAMLEN]) 757 break; 758 (void) memmove(cp, namebuf, len); 759 *--cp = '/'; 760 761 /* 762 * Corner case for a looped-to-itself directory. 763 */ 764 if (ino == idesc.id_number) 765 break; 766 767 /* 768 * Climb one level of the hierarchy. In other words, 769 * the current .. becomes the inode to search for and 770 * its parent becomes the directory to search in. 771 */ 772 ino = idesc.id_number; 773 } 774 775 /* 776 * If we hit a discontinuity in the hierarchy, indicate it by 777 * prefixing the path so far with `?'. Otherwise, the first 778 * character will be `/' as a side-effect of the *--cp above. 779 * 780 * The special case is to handle the situation where we're 781 * trying to look something up in UFSROOTINO, but didn't find 782 * it. 783 */ 784 if (ino != UFSROOTINO || cp == &namebuf[MAXPATHLEN - 1]) { 785 if (cp > namebuf) 786 cp--; 787 *cp = '?'; 788 } 789 790 /* 791 * The invariants being used for buffer integrity are: 792 * - namebuf[] is terminated with \0 before anything else 793 * - cp is always <= the last element of namebuf[] 794 * - the new path element is always stored at the 795 * beginning of namebuf[], and is no more than MAXNAMLEN-1 796 * characters 797 * - cp is is decremented by the number of characters in 798 * the new path element 799 * - if, after the above accounting for the new element's 800 * size, there is no longer enough room at the beginning of 801 * namebuf[] for a full-sized path element and a slash, 802 * terminate the loop. cp is in the range 803 * &namebuf[0]..&namebuf[MAXNAMLEN - 1] 804 */ 805 attrname: 806 /* LINTED per the above discussion */ 807 (void) memmove(namebuf, cp, &namebuf[MAXPATHLEN] - cp); 808 } 809 810 /* ARGSUSED */ 811 void 812 catch(int dummy) 813 { 814 ckfini(); 815 exit(EXSIGNAL); 816 } 817 818 /* 819 * When preening, allow a single quit to signal 820 * a special exit after filesystem checks complete 821 * so that reboot sequence may be interrupted. 822 */ 823 /* ARGSUSED */ 824 void 825 catchquit(int dummy) 826 { 827 (void) printf("returning to single-user after filesystem check\n"); 828 interrupted = 1; 829 (void) signal(SIGQUIT, SIG_DFL); 830 } 831 832 833 /* 834 * determine whether an inode should be fixed. 835 */ 836 NOTE(PRINTFLIKE(2)) 837 int 838 dofix(struct inodesc *idesc, caddr_t msg, ...) 839 { 840 int rval = 0; 841 va_list ap; 842 843 va_start(ap, msg); 844 845 switch (idesc->id_fix) { 846 847 case DONTKNOW: 848 if (idesc->id_type == DATA) 849 vdirerror(idesc->id_number, msg, ap); 850 else 851 vpwarn(msg, ap); 852 if (preen) { 853 idesc->id_fix = FIX; 854 rval = ALTERED; 855 break; 856 } 857 if (reply("SALVAGE") == 0) { 858 idesc->id_fix = NOFIX; 859 break; 860 } 861 idesc->id_fix = FIX; 862 rval = ALTERED; 863 break; 864 865 case FIX: 866 rval = ALTERED; 867 break; 868 869 case NOFIX: 870 break; 871 872 default: 873 errexit("UNKNOWN INODESC FIX MODE %d\n", (int)idesc->id_fix); 874 } 875 876 va_end(ap); 877 return (rval); 878 } 879 880 NOTE(PRINTFLIKE(1)) 881 void 882 errexit(caddr_t fmt, ...) 883 { 884 va_list ap; 885 886 va_start(ap, fmt); 887 verrexit(fmt, ap); 888 /* NOTREACHED */ 889 } 890 891 NOTE(PRINTFLIKE(1)) 892 static void 893 verrexit(caddr_t fmt, va_list ap) 894 { 895 static int recursing = 0; 896 897 if (!recursing) { 898 recursing = 1; 899 if (errorlocked || iscorrupt) { 900 if (havesb && fswritefd >= 0) { 901 sblock.fs_clean = FSBAD; 902 sblock.fs_state = FSOKAY - (long)sblock.fs_time; 903 sblock.fs_state = -sblock.fs_state; 904 sbdirty(); 905 write_altsb(fswritefd); 906 flush(fswritefd, &sblk); 907 } 908 } 909 ckfini(); 910 recursing = 0; 911 } 912 (void) vprintf(fmt, ap); 913 if (fmt[strlen(fmt) - 1] != '\n') 914 (void) putchar('\n'); 915 exit((exitstat != 0) ? exitstat : EXERRFATAL); 916 } 917 918 /* 919 * An unexpected inconsistency occured. 920 * Die if preening, otherwise just print message and continue. 921 */ 922 NOTE(PRINTFLIKE(1)) 923 void 924 pfatal(caddr_t fmt, ...) 925 { 926 va_list ap; 927 928 va_start(ap, fmt); 929 vpfatal(fmt, ap); 930 va_end(ap); 931 } 932 933 NOTE(PRINTFLIKE(1)) 934 static void 935 vpfatal(caddr_t fmt, va_list ap) 936 { 937 if (preen) { 938 if (*fmt != '\0') { 939 (void) printf("%s: ", devname); 940 (void) vprintf(fmt, ap); 941 (void) printf("\n"); 942 } 943 (void) printf( 944 "%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", 945 devname); 946 if (havesb && fswritefd >= 0) { 947 sblock.fs_clean = FSBAD; 948 sblock.fs_state = -(FSOKAY - (long)sblock.fs_time); 949 sbdirty(); 950 flush(fswritefd, &sblk); 951 } 952 /* 953 * We're exiting, it doesn't really matter that our 954 * caller doesn't get to call va_end(). 955 */ 956 if (exitstat == 0) 957 exitstat = EXFNDERRS; 958 exit(exitstat); 959 } 960 if (*fmt != '\0') { 961 (void) vprintf(fmt, ap); 962 } 963 } 964 965 /* 966 * Pwarn just prints a message when not preening, 967 * or a warning (preceded by filename) when preening. 968 */ 969 NOTE(PRINTFLIKE(1)) 970 void 971 pwarn(caddr_t fmt, ...) 972 { 973 va_list ap; 974 975 va_start(ap, fmt); 976 vpwarn(fmt, ap); 977 va_end(ap); 978 } 979 980 NOTE(PRINTFLIKE(1)) 981 static void 982 vpwarn(caddr_t fmt, va_list ap) 983 { 984 if (*fmt != '\0') { 985 if (preen) 986 (void) printf("%s: ", devname); 987 (void) vprintf(fmt, ap); 988 } 989 } 990 991 /* 992 * Like sprintf(), except the buffer is dynamically allocated 993 * and returned, instead of being passed in. A pointer to the 994 * buffer is stored in *RET, and FMT is the usual format string. 995 * The number of characters in *RET (excluding the trailing \0, 996 * to be consistent with the other *printf() routines) is returned. 997 * 998 * Solaris doesn't have asprintf(3C) yet, unfortunately. 999 */ 1000 NOTE(PRINTFLIKE(2)) 1001 int 1002 fsck_asprintf(caddr_t *ret, caddr_t fmt, ...) 1003 { 1004 int len; 1005 caddr_t buffer; 1006 va_list ap; 1007 1008 va_start(ap, fmt); 1009 len = vsnprintf(NULL, 0, fmt, ap); 1010 va_end(ap); 1011 1012 buffer = malloc((len + 1) * sizeof (char)); 1013 if (buffer == NULL) { 1014 errexit("Out of memory in asprintf\n"); 1015 /* NOTREACHED */ 1016 } 1017 1018 va_start(ap, fmt); 1019 (void) vsnprintf(buffer, len + 1, fmt, ap); 1020 va_end(ap); 1021 1022 *ret = buffer; 1023 return (len); 1024 } 1025 1026 /* 1027 * So we can take advantage of kernel routines in ufs_subr.c. 1028 */ 1029 /* PRINTFLIKE2 */ 1030 void 1031 cmn_err(int level, caddr_t fmt, ...) 1032 { 1033 va_list ap; 1034 1035 va_start(ap, fmt); 1036 if (level == CE_PANIC) { 1037 (void) printf("INTERNAL INCONSISTENCY:"); 1038 verrexit(fmt, ap); 1039 } else { 1040 (void) vprintf(fmt, ap); 1041 } 1042 va_end(ap); 1043 } 1044 1045 /* 1046 * Check to see if unraw version of name is already mounted. 1047 * Updates devstr with the device name if devstr is not NULL 1048 * and str_size is positive. 1049 */ 1050 int 1051 mounted(caddr_t name, caddr_t devstr, size_t str_size) 1052 { 1053 int found; 1054 struct mnttab *mntent; 1055 1056 mntent = search_mnttab(NULL, unrawname(name), devstr, str_size); 1057 if (mntent == NULL) 1058 return (M_NOMNT); 1059 1060 /* 1061 * It's mounted. With or without write access? 1062 */ 1063 if (hasmntopt(mntent, MNTOPT_RO) != 0) 1064 found = M_RO; /* mounted as RO */ 1065 else 1066 found = M_RW; /* mounted as R/W */ 1067 1068 if (mount_point == NULL) { 1069 mount_point = strdup(mntent->mnt_mountp); 1070 if (mount_point == NULL) { 1071 errexit("fsck: memory allocation failure: %s", 1072 strerror(errno)); 1073 /* NOTREACHED */ 1074 } 1075 1076 if (devstr != NULL && str_size > 0) 1077 (void) strlcpy(devstr, mntent->mnt_special, str_size); 1078 } 1079 1080 return (found); 1081 } 1082 1083 /* 1084 * Check to see if name corresponds to an entry in vfstab, and that the entry 1085 * does not have option ro. 1086 */ 1087 int 1088 writable(caddr_t name) 1089 { 1090 int rw = 1; 1091 struct vfstab vfsbuf, vfskey; 1092 FILE *vfstab; 1093 1094 vfstab = fopen(VFSTAB, "r"); 1095 if (vfstab == NULL) { 1096 (void) printf("can't open %s\n", VFSTAB); 1097 return (1); 1098 } 1099 (void) memset((void *)&vfskey, 0, sizeof (vfskey)); 1100 vfsnull(&vfskey); 1101 vfskey.vfs_special = unrawname(name); 1102 vfskey.vfs_fstype = MNTTYPE_UFS; 1103 if ((getvfsany(vfstab, &vfsbuf, &vfskey) == 0) && 1104 (hasvfsopt(&vfsbuf, MNTOPT_RO))) { 1105 rw = 0; 1106 } 1107 (void) fclose(vfstab); 1108 return (rw); 1109 } 1110 1111 /* 1112 * debugclean 1113 */ 1114 static void 1115 debugclean(void) 1116 { 1117 if (!debug) 1118 return; 1119 1120 if ((iscorrupt == 0) && (isdirty == 0)) 1121 return; 1122 1123 if ((sblock.fs_clean == FSSTABLE) || (sblock.fs_clean == FSCLEAN) || 1124 (sblock.fs_clean == FSLOG && islog && islogok) || 1125 ((FSOKAY == (sblock.fs_state + sblock.fs_time)) && !errorlocked)) 1126 return; 1127 1128 (void) printf("WARNING: inconsistencies detected on %s filesystem %s\n", 1129 sblock.fs_clean == FSSTABLE ? "stable" : 1130 sblock.fs_clean == FSLOG ? "logging" : 1131 sblock.fs_clean == FSFIX ? "being fixed" : "clean", 1132 devname); 1133 } 1134 1135 /* 1136 * updateclean 1137 * Carefully and transparently update the clean flag. 1138 * 1139 * `iscorrupt' has to be in its final state before this is called. 1140 */ 1141 int 1142 updateclean(void) 1143 { 1144 int freedlog = 0; 1145 struct bufarea cleanbuf; 1146 size_t size; 1147 ssize_t io_res; 1148 diskaddr_t bno; 1149 char fsclean; 1150 int fsreclaim; 1151 char fsflags; 1152 int flags_ok = 1; 1153 daddr32_t fslogbno; 1154 offset_t sblkoff; 1155 time_t t; 1156 1157 /* 1158 * debug stuff 1159 */ 1160 debugclean(); 1161 1162 /* 1163 * set fsclean to its appropriate value 1164 */ 1165 fslogbno = sblock.fs_logbno; 1166 fsclean = sblock.fs_clean; 1167 fsreclaim = sblock.fs_reclaim; 1168 fsflags = sblock.fs_flags; 1169 if (FSOKAY != (sblock.fs_state + sblock.fs_time) && !errorlocked) { 1170 fsclean = FSACTIVE; 1171 } 1172 /* 1173 * If ufs log is not okay, note that we need to clear it. 1174 */ 1175 examinelog(NULL); 1176 if (fslogbno && !(islog && islogok)) { 1177 fsclean = FSACTIVE; 1178 fslogbno = 0; 1179 } 1180 1181 /* 1182 * if necessary, update fs_clean and fs_state 1183 */ 1184 switch (fsclean) { 1185 1186 case FSACTIVE: 1187 if (!iscorrupt) { 1188 fsclean = FSSTABLE; 1189 fsreclaim = 0; 1190 } 1191 break; 1192 1193 case FSCLEAN: 1194 case FSSTABLE: 1195 if (iscorrupt) { 1196 fsclean = FSACTIVE; 1197 } else { 1198 fsreclaim = 0; 1199 } 1200 break; 1201 1202 case FSLOG: 1203 if (iscorrupt) { 1204 fsclean = FSACTIVE; 1205 } else if (!islog || fslogbno == 0) { 1206 fsclean = FSSTABLE; 1207 fsreclaim = 0; 1208 } else if (fflag) { 1209 fsreclaim = 0; 1210 } 1211 break; 1212 1213 case FSFIX: 1214 fsclean = FSBAD; 1215 if (errorlocked && !iscorrupt) { 1216 fsclean = islog ? FSLOG : FSCLEAN; 1217 } 1218 break; 1219 1220 default: 1221 if (iscorrupt) { 1222 fsclean = FSACTIVE; 1223 } else { 1224 fsclean = FSSTABLE; 1225 fsreclaim = 0; 1226 } 1227 } 1228 1229 if (largefile_count > 0) 1230 fsflags |= FSLARGEFILES; 1231 else 1232 fsflags &= ~FSLARGEFILES; 1233 1234 /* 1235 * There can be two discrepencies here. A) The superblock 1236 * shows no largefiles but we found some while scanning. 1237 * B) The superblock indicates the presence of largefiles, 1238 * but none are present. Note that if preening, the superblock 1239 * is silently corrected. 1240 */ 1241 if ((fsflags == FSLARGEFILES && sblock.fs_flags != FSLARGEFILES) || 1242 (fsflags != FSLARGEFILES && sblock.fs_flags == FSLARGEFILES)) 1243 flags_ok = 0; 1244 1245 if (debug) 1246 (void) printf( 1247 "** largefile count=%d, fs.fs_flags=%x, flags_ok %d\n", 1248 largefile_count, sblock.fs_flags, flags_ok); 1249 1250 /* 1251 * If fs is unchanged, do nothing. 1252 */ 1253 if ((!isdirty) && (flags_ok) && 1254 (fslogbno == sblock.fs_logbno) && 1255 (sblock.fs_clean == fsclean) && 1256 (sblock.fs_reclaim == fsreclaim) && 1257 (FSOKAY == (sblock.fs_state + sblock.fs_time))) { 1258 if (errorlocked) { 1259 if (!do_errorlock(LOCKFS_ULOCK)) 1260 pwarn( 1261 "updateclean(unchanged): unlock(LOCKFS_ULOCK) failed\n"); 1262 } 1263 return (freedlog); 1264 } 1265 1266 /* 1267 * if user allows, update superblock state 1268 */ 1269 if (debug) { 1270 (void) printf( 1271 "superblock: flags 0x%x logbno %d clean %d reclaim %d state 0x%x\n", 1272 sblock.fs_flags, sblock.fs_logbno, 1273 sblock.fs_clean, sblock.fs_reclaim, 1274 sblock.fs_state + sblock.fs_time); 1275 (void) printf( 1276 "calculated: flags 0x%x logbno %d clean %d reclaim %d state 0x%x\n", 1277 fsflags, fslogbno, fsclean, fsreclaim, FSOKAY); 1278 } 1279 if (!isdirty && !preen && !rerun && 1280 (reply("FILE SYSTEM STATE IN SUPERBLOCK IS WRONG; FIX") == 0)) 1281 return (freedlog); 1282 1283 (void) time(&t); 1284 sblock.fs_time = (time32_t)t; 1285 if (debug) 1286 printclean(); 1287 1288 if (sblock.fs_logbno != fslogbno) { 1289 examinelog(&freelogblk); 1290 freedlog++; 1291 } 1292 1293 sblock.fs_logbno = fslogbno; 1294 sblock.fs_clean = fsclean; 1295 sblock.fs_state = FSOKAY - (long)sblock.fs_time; 1296 sblock.fs_reclaim = fsreclaim; 1297 sblock.fs_flags = fsflags; 1298 1299 /* 1300 * if superblock can't be written, return 1301 */ 1302 if (fswritefd < 0) 1303 return (freedlog); 1304 1305 /* 1306 * Read private copy of superblock, update clean flag, and write it. 1307 */ 1308 bno = sblk.b_bno; 1309 size = sblk.b_size; 1310 1311 sblkoff = ldbtob(bno); 1312 1313 if ((cleanbuf.b_un.b_buf = malloc(size)) == NULL) 1314 errexit("out of memory"); 1315 if (llseek(fsreadfd, sblkoff, SEEK_SET) == -1) { 1316 (void) printf("COULD NOT SEEK TO SUPERBLOCK AT %lld: %s\n", 1317 (longlong_t)bno, strerror(errno)); 1318 goto out; 1319 } 1320 1321 if ((io_res = read(fsreadfd, cleanbuf.b_un.b_buf, size)) != size) { 1322 report_io_prob("READ FROM", bno, size, io_res); 1323 goto out; 1324 } 1325 1326 cleanbuf.b_un.b_fs->fs_logbno = sblock.fs_logbno; 1327 cleanbuf.b_un.b_fs->fs_clean = sblock.fs_clean; 1328 cleanbuf.b_un.b_fs->fs_state = sblock.fs_state; 1329 cleanbuf.b_un.b_fs->fs_time = sblock.fs_time; 1330 cleanbuf.b_un.b_fs->fs_reclaim = sblock.fs_reclaim; 1331 cleanbuf.b_un.b_fs->fs_flags = sblock.fs_flags; 1332 1333 if (llseek(fswritefd, sblkoff, SEEK_SET) == -1) { 1334 (void) printf("COULD NOT SEEK TO SUPERBLOCK AT %lld: %s\n", 1335 (longlong_t)bno, strerror(errno)); 1336 goto out; 1337 } 1338 1339 if ((io_res = write(fswritefd, cleanbuf.b_un.b_buf, size)) != size) { 1340 report_io_prob("WRITE TO", bno, size, io_res); 1341 goto out; 1342 } 1343 1344 /* 1345 * 1208040 1346 * If we had to use -b to grab an alternate superblock, then we 1347 * likely had to do so because of unacceptable differences between 1348 * the main and alternate superblocks. So, we had better update 1349 * the alternate superblock as well, or we'll just fail again 1350 * the next time we attempt to run fsck! 1351 */ 1352 if (bflag != 0) { 1353 write_altsb(fswritefd); 1354 } 1355 1356 if (errorlocked) { 1357 if (!do_errorlock(LOCKFS_ULOCK)) 1358 pwarn( 1359 "updateclean(changed): unlock(LOCKFS_ULOCK) failed\n"); 1360 } 1361 1362 out: 1363 if (cleanbuf.b_un.b_buf != NULL) { 1364 free((void *)cleanbuf.b_un.b_buf); 1365 } 1366 1367 return (freedlog); 1368 } 1369 1370 static void 1371 report_io_prob(caddr_t what, diskaddr_t bno, size_t expected, ssize_t failure) 1372 { 1373 if (failure < 0) 1374 (void) printf("COULD NOT %s SUPERBLOCK AT %d: %s\n", 1375 what, (int)bno, strerror(errno)); 1376 else if (failure == 0) 1377 (void) printf("COULD NOT %s SUPERBLOCK AT %d: EOF\n", 1378 what, (int)bno); 1379 else 1380 (void) printf("SHORT %s SUPERBLOCK AT %d: %u out of %u bytes\n", 1381 what, (int)bno, (unsigned)failure, (unsigned)expected); 1382 } 1383 1384 /* 1385 * print out clean info 1386 */ 1387 void 1388 printclean(void) 1389 { 1390 caddr_t s; 1391 1392 if (FSOKAY != (sblock.fs_state + sblock.fs_time) && !errorlocked) 1393 s = "unknown"; 1394 else 1395 switch (sblock.fs_clean) { 1396 1397 case FSACTIVE: 1398 s = "active"; 1399 break; 1400 1401 case FSCLEAN: 1402 s = "clean"; 1403 break; 1404 1405 case FSSTABLE: 1406 s = "stable"; 1407 break; 1408 1409 case FSLOG: 1410 s = "logging"; 1411 break; 1412 1413 case FSBAD: 1414 s = "is bad"; 1415 break; 1416 1417 case FSFIX: 1418 s = "being fixed"; 1419 break; 1420 1421 default: 1422 s = "unknown"; 1423 } 1424 1425 if (preen) 1426 pwarn("is %s.\n", s); 1427 else 1428 (void) printf("** %s is %s.\n", devname, s); 1429 } 1430 1431 int 1432 is_errorlocked(caddr_t fs) 1433 { 1434 int retval; 1435 struct stat64 statb; 1436 caddr_t mountp; 1437 struct mnttab *mntent; 1438 1439 retval = 0; 1440 1441 if (!fs) 1442 return (0); 1443 1444 if (stat64(fs, &statb) < 0) 1445 return (0); 1446 1447 if (S_ISDIR(statb.st_mode)) { 1448 mountp = fs; 1449 } else if (S_ISBLK(statb.st_mode) || S_ISCHR(statb.st_mode)) { 1450 mntent = search_mnttab(NULL, fs, NULL, 0); 1451 if (mntent == NULL) 1452 return (0); 1453 mountp = mntent->mnt_mountp; 1454 if (mountp == NULL) /* theoretically a can't-happen */ 1455 return (0); 1456 } else { 1457 return (0); 1458 } 1459 1460 /* 1461 * From here on, must `goto out' to avoid memory leakage. 1462 */ 1463 1464 if (elock_combuf == NULL) 1465 elock_combuf = 1466 (caddr_t)calloc(LOCKFS_MAXCOMMENTLEN, sizeof (char)); 1467 else 1468 elock_combuf = 1469 (caddr_t)realloc(elock_combuf, LOCKFS_MAXCOMMENTLEN); 1470 1471 if (elock_combuf == NULL) 1472 goto out; 1473 1474 (void) memset((void *)elock_combuf, 0, LOCKFS_MAXCOMMENTLEN); 1475 1476 if (elock_mountp != NULL) { 1477 free(elock_mountp); 1478 } 1479 1480 elock_mountp = strdup(mountp); 1481 if (elock_mountp == NULL) 1482 goto out; 1483 1484 if (mountfd < 0) { 1485 if ((mountfd = open64(mountp, O_RDONLY)) == -1) 1486 goto out; 1487 } 1488 1489 if (lfp == NULL) { 1490 lfp = (struct lockfs *)malloc(sizeof (struct lockfs)); 1491 if (lfp == NULL) 1492 goto out; 1493 (void) memset((void *)lfp, 0, sizeof (struct lockfs)); 1494 } 1495 1496 lfp->lf_comlen = LOCKFS_MAXCOMMENTLEN; 1497 lfp->lf_comment = elock_combuf; 1498 1499 if (ioctl(mountfd, _FIOLFSS, lfp) == -1) 1500 goto out; 1501 1502 /* 1503 * lint believes that the ioctl() (or any other function 1504 * taking lfp as an arg) could free lfp. This is not the 1505 * case, however. 1506 */ 1507 retval = LOCKFS_IS_ELOCK(lfp); 1508 1509 out: 1510 return (retval); 1511 } 1512 1513 /* 1514 * Given a name which is known to be a directory, see if it appears 1515 * in the vfstab. If so, return the entry's block (special) device 1516 * field via devstr. 1517 */ 1518 int 1519 check_vfstab(caddr_t name, caddr_t devstr, size_t str_size) 1520 { 1521 return (NULL != search_vfstab(name, NULL, devstr, str_size)); 1522 } 1523 1524 /* 1525 * Given a name which is known to be a directory, see if it appears 1526 * in the mnttab. If so, return the entry's block (special) device 1527 * field via devstr. 1528 */ 1529 int 1530 check_mnttab(caddr_t name, caddr_t devstr, size_t str_size) 1531 { 1532 return (NULL != search_mnttab(name, NULL, devstr, str_size)); 1533 } 1534 1535 /* 1536 * Search for mount point and/or special device in the given file. 1537 * The first matching entry is returned. 1538 * 1539 * If an entry is found and str_size is greater than zero, then 1540 * up to size_str bytes of the special device name from the entry 1541 * are copied to devstr. 1542 */ 1543 1544 #define SEARCH_TAB_BODY(st_type, st_file, st_mount, st_special, \ 1545 st_nuller, st_init, st_searcher) \ 1546 { \ 1547 FILE *fp; \ 1548 struct st_type *retval = NULL; \ 1549 struct st_type key; \ 1550 static struct st_type buffer; \ 1551 \ 1552 /* LINTED ``assigned value never used'' */ \ 1553 st_nuller(&key); \ 1554 key.st_mount = mountp; \ 1555 key.st_special = special; \ 1556 st_init; \ 1557 \ 1558 if ((fp = fopen(st_file, "r")) == NULL) \ 1559 return (NULL); \ 1560 \ 1561 if (st_searcher(fp, &buffer, &key) == 0) { \ 1562 retval = &buffer; \ 1563 if (devstr != NULL && str_size > 0 && \ 1564 buffer.st_special != NULL) { \ 1565 (void) strlcpy(devstr, buffer.st_special, \ 1566 str_size); \ 1567 } \ 1568 } \ 1569 (void) fclose(fp); \ 1570 return (retval); \ 1571 } 1572 1573 static struct vfstab * 1574 search_vfstab(caddr_t mountp, caddr_t special, caddr_t devstr, size_t str_size) 1575 SEARCH_TAB_BODY(vfstab, VFSTAB, vfs_mountp, vfs_special, vfsnull, 1576 (retval = retval), getvfsany) 1577 1578 static struct mnttab * 1579 search_mnttab(caddr_t mountp, caddr_t special, caddr_t devstr, size_t str_size) 1580 SEARCH_TAB_BODY(mnttab, MNTTAB, mnt_mountp, mnt_special, mntnull, 1581 (key.mnt_fstype = MNTTYPE_UFS), getmntany) 1582 1583 int 1584 do_errorlock(int lock_type) 1585 { 1586 caddr_t buf; 1587 time_t now; 1588 struct tm *local; 1589 int rc; 1590 1591 if (elock_combuf == NULL) 1592 errexit("do_errorlock(%s, %d): unallocated elock_combuf\n", 1593 elock_mountp ? elock_mountp : "<null>", 1594 lock_type); 1595 1596 if ((buf = (caddr_t)calloc(LOCKFS_MAXCOMMENTLEN, sizeof (char))) == 1597 NULL) { 1598 errexit("Couldn't alloc memory for temp. lock status buffer\n"); 1599 } 1600 if (lfp == NULL) { 1601 errexit("do_errorlock(%s, %d): lockfs status unallocated\n", 1602 elock_mountp, lock_type); 1603 } 1604 1605 (void) memmove((void *)buf, (void *)elock_combuf, 1606 LOCKFS_MAXCOMMENTLEN-1); 1607 1608 switch (lock_type) { 1609 case LOCKFS_ELOCK: 1610 /* 1611 * Note that if it is error-locked, we won't get an 1612 * error back if we try to error-lock it again. 1613 */ 1614 if (time(&now) != (time_t)-1) { 1615 if ((local = localtime(&now)) != NULL) 1616 (void) snprintf(buf, LOCKFS_MAXCOMMENTLEN, 1617 "%s [pid:%d fsck start:%02d/%02d/%02d %02d:%02d:%02d", 1618 elock_combuf, (int)pid, 1619 local->tm_mon + 1, local->tm_mday, 1620 (local->tm_year % 100), local->tm_hour, 1621 local->tm_min, local->tm_sec); 1622 else 1623 (void) snprintf(buf, LOCKFS_MAXCOMMENTLEN, 1624 "%s [fsck pid %d", elock_combuf, pid); 1625 1626 } else { 1627 (void) snprintf(buf, LOCKFS_MAXCOMMENTLEN, 1628 "%s [fsck pid %d", elock_combuf, pid); 1629 } 1630 break; 1631 1632 case LOCKFS_ULOCK: 1633 if (time(&now) != (time_t)-1) { 1634 if ((local = localtime(&now)) != NULL) { 1635 (void) snprintf(buf, LOCKFS_MAXCOMMENTLEN, 1636 "%s, done:%02d/%02d/%02d %02d:%02d:%02d]", 1637 elock_combuf, 1638 local->tm_mon + 1, local->tm_mday, 1639 (local->tm_year % 100), local->tm_hour, 1640 local->tm_min, local->tm_sec); 1641 } else { 1642 (void) snprintf(buf, LOCKFS_MAXCOMMENTLEN, 1643 "%s]", elock_combuf); 1644 } 1645 } else { 1646 (void) snprintf(buf, LOCKFS_MAXCOMMENTLEN, 1647 "%s]", elock_combuf); 1648 } 1649 if ((rc = ioctl(mountfd, _FIOLFSS, lfp)) == -1) { 1650 pwarn("do_errorlock: unlock failed: %s\n", 1651 strerror(errno)); 1652 goto out; 1653 } 1654 break; 1655 1656 default: 1657 break; 1658 } 1659 1660 (void) memmove((void *)elock_combuf, (void *)buf, 1661 LOCKFS_MAXCOMMENTLEN - 1); 1662 1663 lfp->lf_lock = lock_type; 1664 lfp->lf_comlen = LOCKFS_MAXCOMMENTLEN; 1665 lfp->lf_comment = elock_combuf; 1666 lfp->lf_flags = 0; 1667 errno = 0; 1668 1669 if ((rc = ioctl(mountfd, _FIOLFS, lfp)) == -1) { 1670 if (errno == EINVAL) { 1671 pwarn("Another fsck active?\n"); 1672 iscorrupt = 0; /* don't go away mad, just go away */ 1673 } else { 1674 pwarn("do_errorlock(lock_type:%d, %s) failed: %s\n", 1675 lock_type, elock_combuf, strerror(errno)); 1676 } 1677 } 1678 out: 1679 if (buf != NULL) { 1680 free((void *)buf); 1681 } 1682 1683 return (rc != -1); 1684 } 1685 1686 /* 1687 * Shadow inode support. To register a shadow with a client is to note 1688 * that an inode (the client) refers to the shadow. 1689 */ 1690 1691 static struct shadowclients * 1692 newshadowclient(struct shadowclients *prev) 1693 { 1694 struct shadowclients *rc; 1695 1696 rc = (struct shadowclients *)malloc(sizeof (*rc)); 1697 if (rc == NULL) 1698 errexit("newshadowclient: cannot malloc shadow client"); 1699 rc->next = prev; 1700 rc->nclients = 0; 1701 1702 rc->client = (fsck_ino_t *)malloc(sizeof (fsck_ino_t) * 1703 maxshadowclients); 1704 if (rc->client == NULL) 1705 errexit("newshadowclient: cannot malloc client array"); 1706 return (rc); 1707 } 1708 1709 void 1710 registershadowclient(fsck_ino_t shadow, fsck_ino_t client, 1711 struct shadowclientinfo **info) 1712 { 1713 struct shadowclientinfo *sci; 1714 struct shadowclients *scc; 1715 1716 /* 1717 * Already have a record for this shadow? 1718 */ 1719 for (sci = *info; sci != NULL; sci = sci->next) 1720 if (sci->shadow == shadow) 1721 break; 1722 if (sci == NULL) { 1723 /* 1724 * It's a new shadow, add it to the list 1725 */ 1726 sci = (struct shadowclientinfo *)malloc(sizeof (*sci)); 1727 if (sci == NULL) 1728 errexit("registershadowclient: cannot malloc"); 1729 sci->next = *info; 1730 *info = sci; 1731 sci->shadow = shadow; 1732 sci->totalClients = 0; 1733 sci->clients = newshadowclient(NULL); 1734 } 1735 1736 sci->totalClients++; 1737 scc = sci->clients; 1738 if (scc->nclients >= maxshadowclients) { 1739 scc = newshadowclient(sci->clients); 1740 sci->clients = scc; 1741 } 1742 1743 scc->client[scc->nclients++] = client; 1744 } 1745 1746 /* 1747 * Locate and discard a shadow. 1748 */ 1749 void 1750 clearshadow(fsck_ino_t shadow, struct shadowclientinfo **info) 1751 { 1752 struct shadowclientinfo *sci, *prev; 1753 1754 /* 1755 * Do we have a record for this shadow? 1756 */ 1757 prev = NULL; 1758 for (sci = *info; sci != NULL; sci = sci->next) { 1759 if (sci->shadow == shadow) 1760 break; 1761 prev = sci; 1762 } 1763 1764 if (sci != NULL) { 1765 /* 1766 * First, pull it off the list, since we know there 1767 * shouldn't be any future references to this one. 1768 */ 1769 if (prev == NULL) 1770 *info = sci->next; 1771 else 1772 prev->next = sci->next; 1773 deshadow(sci, clearattrref); 1774 } 1775 } 1776 1777 /* 1778 * Discard all memory used to track clients of a shadow. 1779 */ 1780 void 1781 deshadow(struct shadowclientinfo *sci, void (*cb)(fsck_ino_t)) 1782 { 1783 struct shadowclients *clients, *discard; 1784 int idx; 1785 1786 clients = sci->clients; 1787 while (clients != NULL) { 1788 discard = clients; 1789 clients = clients->next; 1790 if (discard->client != NULL) { 1791 if (cb != NULL) { 1792 for (idx = 0; idx < discard->nclients; idx++) 1793 (*cb)(discard->client[idx]); 1794 } 1795 free((void *)discard->client); 1796 } 1797 free((void *)discard); 1798 } 1799 1800 free((void *)sci); 1801 } 1802 1803 /* 1804 * Allocate more buffer as need arises but allocate one at a time. 1805 * This is done to make sure that fsck does not exit with error if it 1806 * needs more buffer to complete its task. 1807 */ 1808 static struct bufarea * 1809 alloc_bufarea(void) 1810 { 1811 struct bufarea *newbp; 1812 caddr_t bufp; 1813 1814 bufp = malloc((unsigned int)sblock.fs_bsize); 1815 if (bufp == NULL) 1816 return (NULL); 1817 1818 newbp = (struct bufarea *)malloc(sizeof (struct bufarea)); 1819 if (newbp == NULL) { 1820 free((void *)bufp); 1821 return (NULL); 1822 } 1823 1824 initbarea(newbp); 1825 newbp->b_un.b_buf = bufp; 1826 newbp->b_prev = &bufhead; 1827 newbp->b_next = bufhead.b_next; 1828 bufhead.b_next->b_prev = newbp; 1829 bufhead.b_next = newbp; 1830 bufhead.b_size++; 1831 return (newbp); 1832 } 1833 1834 /* 1835 * We length-limit in both unrawname() and rawname() to avoid 1836 * overflowing our arrays or those of our naive, trusting callers. 1837 */ 1838 1839 caddr_t 1840 unrawname(caddr_t name) 1841 { 1842 caddr_t dp; 1843 static char fullname[MAXPATHLEN + 1]; 1844 1845 if ((dp = getfullblkname(name)) == NULL) 1846 return (""); 1847 1848 (void) strlcpy(fullname, dp, sizeof (fullname)); 1849 /* 1850 * Not reporting under debug, as the allocation isn't 1851 * reported by getfullblkname. The idea is that we 1852 * produce balanced alloc/free instances. 1853 */ 1854 free(dp); 1855 1856 return (fullname); 1857 } 1858 1859 caddr_t 1860 rawname(caddr_t name) 1861 { 1862 caddr_t dp; 1863 static char fullname[MAXPATHLEN + 1]; 1864 1865 if ((dp = getfullrawname(name)) == NULL) 1866 return (""); 1867 1868 (void) strlcpy(fullname, dp, sizeof (fullname)); 1869 /* 1870 * Not reporting under debug, as the allocation isn't 1871 * reported by getfullblkname. The idea is that we 1872 * produce balanced alloc/free instances. 1873 */ 1874 free(dp); 1875 1876 return (fullname); 1877 } 1878 1879 /* 1880 * Make sure that a cg header looks at least moderately reasonable. 1881 * We want to be able to trust the contents enough to be able to use 1882 * the standard accessor macros. So, besides looking at the obvious 1883 * such as the magic number, we verify that the offset field values 1884 * are properly aligned and not too big or small. 1885 * 1886 * Returns a NULL pointer if the cg is sane enough for our needs, else 1887 * a dynamically-allocated string describing all of its faults. 1888 */ 1889 #define Append_Error(full, full_len, addition, addition_len) \ 1890 if (full == NULL) { \ 1891 full = addition; \ 1892 full_len = addition_len; \ 1893 } else { \ 1894 /* lint doesn't think realloc() understands NULLs */ \ 1895 full = realloc(full, full_len + addition_len + 1); \ 1896 if (full == NULL) { \ 1897 errexit("Out of memory in cg_sanity"); \ 1898 /* NOTREACHED */ \ 1899 } \ 1900 (void) strcpy(full + full_len, addition); \ 1901 full_len += addition_len; \ 1902 free(addition); \ 1903 } 1904 1905 caddr_t 1906 cg_sanity(struct cg *cgp, int cgno) 1907 { 1908 caddr_t full_err; 1909 caddr_t this_err = NULL; 1910 int full_len, this_len; 1911 daddr32_t ndblk; 1912 daddr32_t exp_btotoff, exp_boff, exp_iusedoff; 1913 daddr32_t exp_freeoff, exp_nextfreeoff; 1914 1915 cg_constants(cgno, &exp_btotoff, &exp_boff, &exp_iusedoff, 1916 &exp_freeoff, &exp_nextfreeoff, &ndblk); 1917 1918 full_err = NULL; 1919 full_len = 0; 1920 1921 if (!cg_chkmagic(cgp)) { 1922 this_len = fsck_asprintf(&this_err, 1923 "BAD CG MAGIC NUMBER (0x%x should be 0x%x)\n", 1924 cgp->cg_magic, CG_MAGIC); 1925 Append_Error(full_err, full_len, this_err, this_len); 1926 } 1927 1928 if (cgp->cg_cgx != cgno) { 1929 this_len = fsck_asprintf(&this_err, 1930 "WRONG CG NUMBER (%d should be %d)\n", 1931 cgp->cg_cgx, cgno); 1932 Append_Error(full_err, full_len, this_err, this_len); 1933 } 1934 1935 if ((cgp->cg_btotoff & 3) != 0) { 1936 this_len = fsck_asprintf(&this_err, 1937 "BLOCK TOTALS OFFSET %d NOT FOUR-BYTE ALIGNED\n", 1938 cgp->cg_btotoff); 1939 Append_Error(full_err, full_len, this_err, this_len); 1940 } 1941 1942 if ((cgp->cg_boff & 1) != 0) { 1943 this_len = fsck_asprintf(&this_err, 1944 "FREE BLOCK POSITIONS TABLE OFFSET %d NOT TWO-BYTE ALIGNED\n", 1945 cgp->cg_boff); 1946 Append_Error(full_err, full_len, this_err, this_len); 1947 } 1948 1949 if ((cgp->cg_ncyl < 1) || (cgp->cg_ncyl > sblock.fs_cpg)) { 1950 if (cgp->cg_ncyl < 1) { 1951 this_len = fsck_asprintf(&this_err, 1952 "IMPOSSIBLE NUMBER OF CYLINDERS IN GROUP (%d is less than 1)\n", 1953 cgp->cg_ncyl); 1954 } else { 1955 this_len = fsck_asprintf(&this_err, 1956 "IMPOSSIBLE NUMBER OF CYLINDERS IN GROUP (%d is greater than %d)\n", 1957 cgp->cg_ncyl, sblock.fs_cpg); 1958 } 1959 Append_Error(full_err, full_len, this_err, this_len); 1960 } 1961 1962 if (cgp->cg_niblk != sblock.fs_ipg) { 1963 this_len = fsck_asprintf(&this_err, 1964 "INCORRECT NUMBER OF INODES IN GROUP (%d should be %d)\n", 1965 cgp->cg_niblk, sblock.fs_ipg); 1966 Append_Error(full_err, full_len, this_err, this_len); 1967 } 1968 1969 if (cgp->cg_ndblk != ndblk) { 1970 this_len = fsck_asprintf(&this_err, 1971 "INCORRECT NUMBER OF DATA BLOCKS IN GROUP (%d should be %d)\n", 1972 cgp->cg_ndblk, ndblk); 1973 Append_Error(full_err, full_len, this_err, this_len); 1974 } 1975 1976 if ((cgp->cg_rotor < 0) || (cgp->cg_rotor >= ndblk)) { 1977 this_len = fsck_asprintf(&this_err, 1978 "IMPOSSIBLE BLOCK ALLOCATION ROTOR POSITION " 1979 "(%d should be at least 0 and less than %d)\n", 1980 cgp->cg_rotor, ndblk); 1981 Append_Error(full_err, full_len, this_err, this_len); 1982 } 1983 1984 if ((cgp->cg_frotor < 0) || (cgp->cg_frotor >= ndblk)) { 1985 this_len = fsck_asprintf(&this_err, 1986 "IMPOSSIBLE FRAGMENT ALLOCATION ROTOR POSITION " 1987 "(%d should be at least 0 and less than %d)\n", 1988 cgp->cg_frotor, ndblk); 1989 Append_Error(full_err, full_len, this_err, this_len); 1990 } 1991 1992 if ((cgp->cg_irotor < 0) || (cgp->cg_irotor >= sblock.fs_ipg)) { 1993 this_len = fsck_asprintf(&this_err, 1994 "IMPOSSIBLE INODE ALLOCATION ROTOR POSITION " 1995 "(%d should be at least 0 and less than %d)\n", 1996 cgp->cg_irotor, sblock.fs_ipg); 1997 Append_Error(full_err, full_len, this_err, this_len); 1998 } 1999 2000 if (cgp->cg_btotoff != exp_btotoff) { 2001 this_len = fsck_asprintf(&this_err, 2002 "INCORRECT BLOCK TOTALS OFFSET (%d should be %d)\n", 2003 cgp->cg_btotoff, exp_btotoff); 2004 Append_Error(full_err, full_len, this_err, this_len); 2005 } 2006 2007 if (cgp->cg_boff != exp_boff) { 2008 this_len = fsck_asprintf(&this_err, 2009 "BAD FREE BLOCK POSITIONS TABLE OFFSET (%d should %d)\n", 2010 cgp->cg_boff, exp_boff); 2011 Append_Error(full_err, full_len, this_err, this_len); 2012 } 2013 2014 if (cgp->cg_iusedoff != exp_iusedoff) { 2015 this_len = fsck_asprintf(&this_err, 2016 "INCORRECT USED INODE MAP OFFSET (%d should be %d)\n", 2017 cgp->cg_iusedoff, exp_iusedoff); 2018 Append_Error(full_err, full_len, this_err, this_len); 2019 } 2020 2021 if (cgp->cg_freeoff != exp_freeoff) { 2022 this_len = fsck_asprintf(&this_err, 2023 "INCORRECT FREE FRAGMENT MAP OFFSET (%d should be %d)\n", 2024 cgp->cg_freeoff, exp_freeoff); 2025 Append_Error(full_err, full_len, this_err, this_len); 2026 } 2027 2028 if (cgp->cg_nextfreeoff != exp_nextfreeoff) { 2029 this_len = fsck_asprintf(&this_err, 2030 "END OF HEADER POSITION INCORRECT (%d should be %d)\n", 2031 cgp->cg_nextfreeoff, exp_nextfreeoff); 2032 Append_Error(full_err, full_len, this_err, this_len); 2033 } 2034 2035 return (full_err); 2036 } 2037 2038 #undef Append_Error 2039 2040 /* 2041 * This is taken from mkfs, and is what is used to come up with the 2042 * original values for a struct cg. This implies that, since these 2043 * are all constants, recalculating them now should give us the same 2044 * thing as what's on disk. 2045 */ 2046 static void 2047 cg_constants(int cgno, daddr32_t *btotoff, daddr32_t *boff, 2048 daddr32_t *iusedoff, daddr32_t *freeoff, daddr32_t *nextfreeoff, 2049 daddr32_t *ndblk) 2050 { 2051 daddr32_t cbase, dmax; 2052 struct cg *cgp; 2053 2054 (void) getblk(&cgblk, (diskaddr_t)cgtod(&sblock, cgno), 2055 (size_t)sblock.fs_cgsize); 2056 cgp = cgblk.b_un.b_cg; 2057 2058 cbase = cgbase(&sblock, cgno); 2059 dmax = cbase + sblock.fs_fpg; 2060 if (dmax > sblock.fs_size) 2061 dmax = sblock.fs_size; 2062 2063 /* LINTED pointer difference won't overflow */ 2064 *btotoff = &cgp->cg_space[0] - (uchar_t *)(&cgp->cg_link); 2065 *boff = *btotoff + sblock.fs_cpg * sizeof (daddr32_t); 2066 *iusedoff = *boff + sblock.fs_cpg * sblock.fs_nrpos * sizeof (int16_t); 2067 *freeoff = *iusedoff + howmany(sblock.fs_ipg, NBBY); 2068 *nextfreeoff = *freeoff + 2069 howmany(sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock), NBBY); 2070 *ndblk = dmax - cbase; 2071 } 2072 2073 /* 2074 * Corrects all fields in the cg that can be done with the available 2075 * redundant data. 2076 */ 2077 void 2078 fix_cg(struct cg *cgp, int cgno) 2079 { 2080 daddr32_t exp_btotoff, exp_boff, exp_iusedoff; 2081 daddr32_t exp_freeoff, exp_nextfreeoff; 2082 daddr32_t ndblk; 2083 2084 cg_constants(cgno, &exp_btotoff, &exp_boff, &exp_iusedoff, 2085 &exp_freeoff, &exp_nextfreeoff, &ndblk); 2086 2087 if (cgp->cg_cgx != cgno) { 2088 cgp->cg_cgx = cgno; 2089 } 2090 2091 if ((cgp->cg_ncyl < 1) || (cgp->cg_ncyl > sblock.fs_cpg)) { 2092 if (cgno == (sblock.fs_ncg - 1)) { 2093 cgp->cg_ncyl = sblock.fs_ncyl - 2094 (sblock.fs_cpg * cgno); 2095 } else { 2096 cgp->cg_ncyl = sblock.fs_cpg; 2097 } 2098 } 2099 2100 if (cgp->cg_niblk != sblock.fs_ipg) { 2101 /* 2102 * This is not used by the kernel, so it's pretty 2103 * harmless if it's wrong. 2104 */ 2105 cgp->cg_niblk = sblock.fs_ipg; 2106 } 2107 2108 if (cgp->cg_ndblk != ndblk) { 2109 cgp->cg_ndblk = ndblk; 2110 } 2111 2112 /* 2113 * For the rotors, any position's valid, so pick the one we know 2114 * will always exist. 2115 */ 2116 if ((cgp->cg_rotor < 0) || (cgp->cg_rotor >= cgp->cg_ndblk)) { 2117 cgp->cg_rotor = 0; 2118 } 2119 2120 if ((cgp->cg_frotor < 0) || (cgp->cg_frotor >= cgp->cg_ndblk)) { 2121 cgp->cg_frotor = 0; 2122 } 2123 2124 if ((cgp->cg_irotor < 0) || (cgp->cg_irotor >= sblock.fs_ipg)) { 2125 cgp->cg_irotor = 0; 2126 } 2127 2128 /* 2129 * For btotoff and boff, if they're misaligned they won't 2130 * match the expected values, so we're catching both cases 2131 * here. Of course, if any of these are off, it seems likely 2132 * that the tables really won't be where we calculate they 2133 * should be anyway. 2134 */ 2135 if (cgp->cg_btotoff != exp_btotoff) { 2136 cgp->cg_btotoff = exp_btotoff; 2137 } 2138 2139 if (cgp->cg_boff != exp_boff) { 2140 cgp->cg_boff = exp_boff; 2141 } 2142 2143 if (cgp->cg_iusedoff != exp_iusedoff) { 2144 cgp->cg_iusedoff = exp_iusedoff; 2145 } 2146 2147 if (cgp->cg_freeoff != exp_freeoff) { 2148 cgp->cg_freeoff = exp_freeoff; 2149 } 2150 2151 if (cgp->cg_nextfreeoff != exp_nextfreeoff) { 2152 cgp->cg_nextfreeoff = exp_nextfreeoff; 2153 } 2154 2155 /* 2156 * Reset the magic, as we've recreated this cg, also 2157 * update the cg_time, as we're writing out the cg 2158 */ 2159 cgp->cg_magic = CG_MAGIC; 2160 cgp->cg_time = time(NULL); 2161 2162 /* 2163 * We know there was at least one correctable problem, 2164 * or else we wouldn't have been called. So instead of 2165 * marking the buffer dirty N times above, just do it 2166 * once here. 2167 */ 2168 cgdirty(); 2169 } 2170 2171 void 2172 examinelog(void (*cb)(daddr32_t)) 2173 { 2174 struct bufarea *bp; 2175 extent_block_t *ebp; 2176 extent_t *ep; 2177 daddr32_t nfno, fno; 2178 int i; 2179 int j; 2180 2181 /* 2182 * Since ufs stores fs_logbno as blocks and MTBufs stores it as frags 2183 * we need to translate accordingly using logbtodb() 2184 */ 2185 2186 if (logbtodb(&sblock, sblock.fs_logbno) < SBLOCK) { 2187 if (debug) { 2188 (void) printf("fs_logbno < SBLOCK: %ld < %ld\n" \ 2189 "Aborting log examination\n", \ 2190 logbtodb(&sblock, sblock.fs_logbno), SBLOCK); 2191 } 2192 return; 2193 } 2194 2195 /* 2196 * Read errors will return zeros, which will cause us 2197 * to do nothing harmful, so don't need to handle it. 2198 */ 2199 bp = getdatablk(logbtofrag(&sblock, sblock.fs_logbno), 2200 (size_t)sblock.fs_bsize); 2201 ebp = (void *)bp->b_un.b_buf; 2202 2203 /* 2204 * Does it look like a log allocation table? 2205 */ 2206 /* LINTED pointer cast is aligned */ 2207 if (!log_checksum(&ebp->chksum, (int32_t *)bp->b_un.b_buf, 2208 sblock.fs_bsize)) 2209 return; 2210 if (ebp->type != LUFS_EXTENTS || ebp->nextents == 0) 2211 return; 2212 2213 ep = &ebp->extents[0]; 2214 for (i = 0; i < ebp->nextents; ++i, ++ep) { 2215 fno = logbtofrag(&sblock, ep->pbno); 2216 nfno = dbtofsb(&sblock, ep->nbno); 2217 for (j = 0; j < nfno; ++j, ++fno) { 2218 /* 2219 * Invoke the callback first, so that pass1 can 2220 * mark the log blocks in-use. Then, if any 2221 * subsequent pass over the log shows us that a 2222 * block got freed (say, it was also claimed by 2223 * an inode that we cleared), we can safely declare 2224 * the log bad. 2225 */ 2226 if (cb != NULL) 2227 (*cb)(fno); 2228 if (!testbmap(fno)) 2229 islogok = 0; 2230 } 2231 } 2232 brelse(bp); 2233 2234 if (cb != NULL) { 2235 fno = logbtofrag(&sblock, sblock.fs_logbno); 2236 for (j = 0; j < sblock.fs_frag; ++j, ++fno) 2237 (*cb)(fno); 2238 } 2239 } 2240 2241 static void 2242 freelogblk(daddr32_t frag) 2243 { 2244 freeblk(sblock.fs_logbno, frag, 1); 2245 } 2246 2247 caddr_t 2248 file_id(fsck_ino_t inum, mode_t mode) 2249 { 2250 static char name[MAXPATHLEN + 1]; 2251 2252 if (lfdir == inum) { 2253 return (lfname); 2254 } 2255 2256 if ((mode & IFMT) == IFDIR) { 2257 (void) strcpy(name, "DIR"); 2258 } else if ((mode & IFMT) == IFATTRDIR) { 2259 (void) strcpy(name, "ATTR DIR"); 2260 } else if ((mode & IFMT) == IFSHAD) { 2261 (void) strcpy(name, "ACL"); 2262 } else { 2263 (void) strcpy(name, "FILE"); 2264 } 2265 2266 return (name); 2267 } 2268 2269 /* 2270 * Simple initializer for inodesc structures, so users of only a few 2271 * fields don't have to worry about getting the right defaults for 2272 * everything out. 2273 */ 2274 void 2275 init_inodesc(struct inodesc *idesc) 2276 { 2277 /* 2278 * Most fields should be zero, just hit the special cases. 2279 */ 2280 (void) memset((void *)idesc, 0, sizeof (struct inodesc)); 2281 idesc->id_fix = DONTKNOW; 2282 idesc->id_lbn = -1; 2283 idesc->id_truncto = -1; 2284 idesc->id_firsthole = -1; 2285 } 2286 2287 /* 2288 * Compare routine for tsearch(C) to use on ino_t instances. 2289 */ 2290 int 2291 ino_t_cmp(const void *left, const void *right) 2292 { 2293 const fsck_ino_t lino = (const fsck_ino_t)left; 2294 const fsck_ino_t rino = (const fsck_ino_t)right; 2295 2296 return (lino - rino); 2297 } 2298 2299 int 2300 cgisdirty(void) 2301 { 2302 return (cgblk.b_dirty); 2303 } 2304 2305 void 2306 cgflush(void) 2307 { 2308 flush(fswritefd, &cgblk); 2309 } 2310 2311 void 2312 dirty(struct bufarea *bp) 2313 { 2314 if (fswritefd < 0) { 2315 /* 2316 * No one should call dirty() in read only mode. 2317 * But if one does, it's not fatal issue. Just warn him. 2318 */ 2319 pwarn("WON'T SET DIRTY FLAG IN READ_ONLY MODE\n"); 2320 } else { 2321 (bp)->b_dirty = 1; 2322 isdirty = 1; 2323 } 2324 } 2325 2326 void 2327 initbarea(struct bufarea *bp) 2328 { 2329 (bp)->b_dirty = 0; 2330 (bp)->b_bno = (diskaddr_t)-1LL; 2331 (bp)->b_flags = 0; 2332 (bp)->b_cnt = 0; 2333 (bp)->b_errs = 0; 2334 } 2335 2336 /* 2337 * Partition-sizing routines adapted from ../newfs/newfs.c. 2338 * Needed because calcsb() needs to use mkfs to work out what the 2339 * superblock should be, and mkfs insists on being told how many 2340 * sectors to use. 2341 * 2342 * Error handling assumes we're never called while preening. 2343 * 2344 * XXX This should be extracted into a ../ufslib.{c,h}, 2345 * in the same spirit to ../../fslib.{c,h}. Once that is 2346 * done, both fsck and newfs should be modified to link 2347 * against it. 2348 */ 2349 2350 static int label_type; 2351 2352 #define LABEL_TYPE_VTOC 1 2353 #define LABEL_TYPE_EFI 2 2354 #define LABEL_TYPE_OTHER 3 2355 2356 #define MB (1024 * 1024) 2357 #define SECTORS_PER_TERABYTE (1LL << 31) 2358 #define FS_SIZE_UPPER_LIMIT 0x100000000000LL 2359 2360 diskaddr_t 2361 getdisksize(caddr_t disk, int fd) 2362 { 2363 int rpm; 2364 struct dk_geom g; 2365 struct dk_cinfo ci; 2366 diskaddr_t actual_size; 2367 2368 /* 2369 * get_device_size() determines the actual size of the 2370 * device, and also the disk's attributes, such as geometry. 2371 */ 2372 actual_size = get_device_size(fd, disk); 2373 2374 if (label_type == LABEL_TYPE_VTOC) { 2375 if (ioctl(fd, DKIOCGGEOM, &g)) { 2376 pwarn("%s: Unable to read Disk geometry", disk); 2377 return (0); 2378 } 2379 if (sblock.fs_nsect == 0) 2380 sblock.fs_nsect = g.dkg_nsect; 2381 if (sblock.fs_ntrak == 0) 2382 sblock.fs_ntrak = g.dkg_nhead; 2383 if (sblock.fs_rps == 0) { 2384 rpm = ((int)g.dkg_rpm <= 0) ? 3600: g.dkg_rpm; 2385 sblock.fs_rps = rpm / 60; 2386 } 2387 } 2388 2389 if (sblock.fs_bsize == 0) 2390 sblock.fs_bsize = MAXBSIZE; 2391 2392 /* 2393 * Adjust maxcontig by the device's maxtransfer. If maxtransfer 2394 * information is not available, default to the min of a MB and 2395 * maxphys. 2396 */ 2397 if (sblock.fs_maxcontig == -1 && ioctl(fd, DKIOCINFO, &ci) == 0) { 2398 sblock.fs_maxcontig = ci.dki_maxtransfer * DEV_BSIZE; 2399 if (sblock.fs_maxcontig < 0) { 2400 int gotit, maxphys; 2401 2402 gotit = fsgetmaxphys(&maxphys, NULL); 2403 2404 /* 2405 * If we cannot get the maxphys value, default 2406 * to ufs_maxmaxphys (MB). 2407 */ 2408 if (gotit) { 2409 sblock.fs_maxcontig = MIN(maxphys, MB); 2410 } else { 2411 sblock.fs_maxcontig = MB; 2412 } 2413 } 2414 sblock.fs_maxcontig /= sblock.fs_bsize; 2415 } 2416 2417 return (actual_size); 2418 } 2419 2420 /* 2421 * Figure out how big the partition we're dealing with is. 2422 */ 2423 static diskaddr_t 2424 get_device_size(int fd, caddr_t name) 2425 { 2426 struct extvtoc vtoc; 2427 struct dk_gpt *efi_vtoc; 2428 diskaddr_t slicesize = 0; 2429 2430 int index = read_extvtoc(fd, &vtoc); 2431 2432 if (index >= 0) { 2433 label_type = LABEL_TYPE_VTOC; 2434 } else { 2435 if (index == VT_ENOTSUP || index == VT_ERROR) { 2436 /* it might be an EFI label */ 2437 index = efi_alloc_and_read(fd, &efi_vtoc); 2438 if (index >= 0) 2439 label_type = LABEL_TYPE_EFI; 2440 } 2441 } 2442 2443 if (index < 0) { 2444 /* 2445 * Since both attempts to read the label failed, we're 2446 * going to fall back to a brute force approach to 2447 * determining the device's size: see how far out we can 2448 * perform reads on the device. 2449 */ 2450 2451 slicesize = brute_force_get_device_size(fd); 2452 if (slicesize == 0) { 2453 switch (index) { 2454 case VT_ERROR: 2455 pwarn("%s: %s\n", name, strerror(errno)); 2456 break; 2457 case VT_EIO: 2458 pwarn("%s: I/O error accessing VTOC", name); 2459 break; 2460 case VT_EINVAL: 2461 pwarn("%s: Invalid field in VTOC", name); 2462 break; 2463 default: 2464 pwarn("%s: unknown error %d accessing VTOC", 2465 name, index); 2466 break; 2467 } 2468 return (0); 2469 } else { 2470 label_type = LABEL_TYPE_OTHER; 2471 } 2472 } 2473 2474 if (label_type == LABEL_TYPE_EFI) { 2475 slicesize = efi_vtoc->efi_parts[index].p_size; 2476 efi_free(efi_vtoc); 2477 } else if (label_type == LABEL_TYPE_VTOC) { 2478 slicesize = vtoc.v_part[index].p_size; 2479 } 2480 2481 return (slicesize); 2482 } 2483 2484 /* 2485 * brute_force_get_device_size 2486 * 2487 * Determine the size of the device by seeing how far we can 2488 * read. Doing an llseek( , , SEEK_END) would probably work 2489 * in most cases, but we've seen at least one third-party driver 2490 * which doesn't correctly support the SEEK_END option when the 2491 * the device is greater than a terabyte. 2492 */ 2493 2494 static diskaddr_t 2495 brute_force_get_device_size(int fd) 2496 { 2497 diskaddr_t min_fail = 0; 2498 diskaddr_t max_succeed = 0; 2499 diskaddr_t cur_db_off; 2500 char buf[DEV_BSIZE]; 2501 2502 /* 2503 * First, see if we can read the device at all, just to 2504 * eliminate errors that have nothing to do with the 2505 * device's size. 2506 */ 2507 2508 if (((llseek(fd, (offset_t)0, SEEK_SET)) == -1) || 2509 ((read(fd, buf, DEV_BSIZE)) == -1)) 2510 return (0); /* can't determine size */ 2511 2512 /* 2513 * Now, go sequentially through the multiples of 4TB 2514 * to find the first read that fails (this isn't strictly 2515 * the most efficient way to find the actual size if the 2516 * size really could be anything between 0 and 2**64 bytes. 2517 * We expect the sizes to be less than 16 TB for some time, 2518 * so why do a bunch of reads that are larger than that? 2519 * However, this algorithm *will* work for sizes of greater 2520 * than 16 TB. We're just not optimizing for those sizes.) 2521 */ 2522 2523 /* 2524 * XXX lint uses 32-bit arithmetic for doing flow analysis. 2525 * We're using > 32-bit constants here. Therefore, its flow 2526 * analysis is wrong. For the time being, ignore complaints 2527 * from it about the body of the for() being unreached. 2528 */ 2529 for (cur_db_off = SECTORS_PER_TERABYTE * 4; 2530 (min_fail == 0) && (cur_db_off < FS_SIZE_UPPER_LIMIT); 2531 cur_db_off += 4 * SECTORS_PER_TERABYTE) { 2532 if ((llseek(fd, (offset_t)(cur_db_off * DEV_BSIZE), 2533 SEEK_SET) == -1) || 2534 (read(fd, buf, DEV_BSIZE) != DEV_BSIZE)) 2535 min_fail = cur_db_off; 2536 else 2537 max_succeed = cur_db_off; 2538 } 2539 2540 /* 2541 * XXX Same lint flow analysis problem as above. 2542 */ 2543 if (min_fail == 0) 2544 return (0); 2545 2546 /* 2547 * We now know that the size of the device is less than 2548 * min_fail and greater than or equal to max_succeed. Now 2549 * keep splitting the difference until the actual size in 2550 * sectors in known. We also know that the difference 2551 * between max_succeed and min_fail at this time is 2552 * 4 * SECTORS_PER_TERABYTE, which is a power of two, which 2553 * simplifies the math below. 2554 */ 2555 2556 while (min_fail - max_succeed > 1) { 2557 cur_db_off = max_succeed + (min_fail - max_succeed)/2; 2558 if (((llseek(fd, (offset_t)(cur_db_off * DEV_BSIZE), 2559 SEEK_SET)) == -1) || 2560 ((read(fd, buf, DEV_BSIZE)) != DEV_BSIZE)) 2561 min_fail = cur_db_off; 2562 else 2563 max_succeed = cur_db_off; 2564 } 2565 2566 /* the size is the last successfully read sector offset plus one */ 2567 return (max_succeed + 1); 2568 } 2569 2570 static void 2571 vfileerror(fsck_ino_t cwd, fsck_ino_t ino, caddr_t fmt, va_list ap) 2572 { 2573 struct dinode *dp; 2574 char pathbuf[MAXPATHLEN + 1]; 2575 2576 vpwarn(fmt, ap); 2577 (void) putchar(' '); 2578 pinode(ino); 2579 (void) printf("\n"); 2580 getpathname(pathbuf, cwd, ino); 2581 if (ino < UFSROOTINO || ino > maxino) { 2582 pfatal("NAME=%s\n", pathbuf); 2583 return; 2584 } 2585 dp = ginode(ino); 2586 if (ftypeok(dp)) 2587 pfatal("%s=%s\n", file_id(ino, dp->di_mode), pathbuf); 2588 else 2589 pfatal("NAME=%s\n", pathbuf); 2590 } 2591 2592 void 2593 direrror(fsck_ino_t ino, caddr_t fmt, ...) 2594 { 2595 va_list ap; 2596 2597 va_start(ap, fmt); 2598 vfileerror(ino, ino, fmt, ap); 2599 va_end(ap); 2600 } 2601 2602 static void 2603 vdirerror(fsck_ino_t ino, caddr_t fmt, va_list ap) 2604 { 2605 vfileerror(ino, ino, fmt, ap); 2606 } 2607 2608 void 2609 fileerror(fsck_ino_t cwd, fsck_ino_t ino, caddr_t fmt, ...) 2610 { 2611 va_list ap; 2612 2613 va_start(ap, fmt); 2614 vfileerror(cwd, ino, fmt, ap); 2615 va_end(ap); 2616 } 2617 2618 /* 2619 * Adds the given inode to the orphaned-directories list, limbo_dirs. 2620 * Assumes that the caller has set INCLEAR in the inode's statemap[] 2621 * entry. 2622 * 2623 * With INCLEAR set, the inode will get ignored by passes 2 and 3, 2624 * meaning it's effectively an orphan. It needs to be noted now, so 2625 * it will be remembered in pass 4. 2626 */ 2627 2628 void 2629 add_orphan_dir(fsck_ino_t ino) 2630 { 2631 if (tsearch((void *)ino, &limbo_dirs, ino_t_cmp) == NULL) 2632 errexit("add_orphan_dir: out of memory"); 2633 } 2634 2635 /* 2636 * Remove an inode from the orphaned-directories list, presumably 2637 * because it's been cleared. 2638 */ 2639 void 2640 remove_orphan_dir(fsck_ino_t ino) 2641 { 2642 (void) tdelete((void *)ino, &limbo_dirs, ino_t_cmp); 2643 } 2644 2645 /* 2646 * log_setsum() and log_checksum() are equivalent to lufs.c:setsum() 2647 * and lufs.c:checksum(). 2648 */ 2649 static void 2650 log_setsum(int32_t *sp, int32_t *lp, int nb) 2651 { 2652 int32_t csum = 0; 2653 2654 *sp = 0; 2655 nb /= sizeof (int32_t); 2656 while (nb--) 2657 csum += *lp++; 2658 *sp = csum; 2659 } 2660 2661 static int 2662 log_checksum(int32_t *sp, int32_t *lp, int nb) 2663 { 2664 int32_t ssum = *sp; 2665 2666 log_setsum(sp, lp, nb); 2667 if (ssum != *sp) { 2668 *sp = ssum; 2669 return (0); 2670 } 2671 return (1); 2672 } 2673