utilities.c revision 1558
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1980, 1986, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes 341558Srgrimes#ifndef lint 351558Srgrimesstatic char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; 361558Srgrimes#endif /* not lint */ 371558Srgrimes 381558Srgrimes#include <sys/param.h> 391558Srgrimes#include <sys/time.h> 401558Srgrimes#include <ufs/ufs/dinode.h> 411558Srgrimes#include <ufs/ufs/dir.h> 421558Srgrimes#include <ufs/ffs/fs.h> 431558Srgrimes#include <stdio.h> 441558Srgrimes#include <stdlib.h> 451558Srgrimes#include <string.h> 461558Srgrimes#include <ctype.h> 471558Srgrimes#include "fsck.h" 481558Srgrimes 491558Srgrimeslong diskreads, totalreads; /* Disk cache statistics */ 501558Srgrimes 511558Srgrimesftypeok(dp) 521558Srgrimes struct dinode *dp; 531558Srgrimes{ 541558Srgrimes switch (dp->di_mode & IFMT) { 551558Srgrimes 561558Srgrimes case IFDIR: 571558Srgrimes case IFREG: 581558Srgrimes case IFBLK: 591558Srgrimes case IFCHR: 601558Srgrimes case IFLNK: 611558Srgrimes case IFSOCK: 621558Srgrimes case IFIFO: 631558Srgrimes return (1); 641558Srgrimes 651558Srgrimes default: 661558Srgrimes if (debug) 671558Srgrimes printf("bad file type 0%o\n", dp->di_mode); 681558Srgrimes return (0); 691558Srgrimes } 701558Srgrimes} 711558Srgrimes 721558Srgrimesreply(question) 731558Srgrimes char *question; 741558Srgrimes{ 751558Srgrimes int persevere; 761558Srgrimes char c; 771558Srgrimes 781558Srgrimes if (preen) 791558Srgrimes pfatal("INTERNAL ERROR: GOT TO reply()"); 801558Srgrimes persevere = !strcmp(question, "CONTINUE"); 811558Srgrimes printf("\n"); 821558Srgrimes if (!persevere && (nflag || fswritefd < 0)) { 831558Srgrimes printf("%s? no\n\n", question); 841558Srgrimes return (0); 851558Srgrimes } 861558Srgrimes if (yflag || (persevere && nflag)) { 871558Srgrimes printf("%s? yes\n\n", question); 881558Srgrimes return (1); 891558Srgrimes } 901558Srgrimes do { 911558Srgrimes printf("%s? [yn] ", question); 921558Srgrimes (void) fflush(stdout); 931558Srgrimes c = getc(stdin); 941558Srgrimes while (c != '\n' && getc(stdin) != '\n') 951558Srgrimes if (feof(stdin)) 961558Srgrimes return (0); 971558Srgrimes } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); 981558Srgrimes printf("\n"); 991558Srgrimes if (c == 'y' || c == 'Y') 1001558Srgrimes return (1); 1011558Srgrimes return (0); 1021558Srgrimes} 1031558Srgrimes 1041558Srgrimes/* 1051558Srgrimes * Malloc buffers and set up cache. 1061558Srgrimes */ 1071558Srgrimesbufinit() 1081558Srgrimes{ 1091558Srgrimes register struct bufarea *bp; 1101558Srgrimes long bufcnt, i; 1111558Srgrimes char *bufp; 1121558Srgrimes 1131558Srgrimes pbp = pdirbp = (struct bufarea *)0; 1141558Srgrimes bufp = malloc((unsigned int)sblock.fs_bsize); 1151558Srgrimes if (bufp == 0) 1161558Srgrimes errexit("cannot allocate buffer pool\n"); 1171558Srgrimes cgblk.b_un.b_buf = bufp; 1181558Srgrimes initbarea(&cgblk); 1191558Srgrimes bufhead.b_next = bufhead.b_prev = &bufhead; 1201558Srgrimes bufcnt = MAXBUFSPACE / sblock.fs_bsize; 1211558Srgrimes if (bufcnt < MINBUFS) 1221558Srgrimes bufcnt = MINBUFS; 1231558Srgrimes for (i = 0; i < bufcnt; i++) { 1241558Srgrimes bp = (struct bufarea *)malloc(sizeof(struct bufarea)); 1251558Srgrimes bufp = malloc((unsigned int)sblock.fs_bsize); 1261558Srgrimes if (bp == NULL || bufp == NULL) { 1271558Srgrimes if (i >= MINBUFS) 1281558Srgrimes break; 1291558Srgrimes errexit("cannot allocate buffer pool\n"); 1301558Srgrimes } 1311558Srgrimes bp->b_un.b_buf = bufp; 1321558Srgrimes bp->b_prev = &bufhead; 1331558Srgrimes bp->b_next = bufhead.b_next; 1341558Srgrimes bufhead.b_next->b_prev = bp; 1351558Srgrimes bufhead.b_next = bp; 1361558Srgrimes initbarea(bp); 1371558Srgrimes } 1381558Srgrimes bufhead.b_size = i; /* save number of buffers */ 1391558Srgrimes} 1401558Srgrimes 1411558Srgrimes/* 1421558Srgrimes * Manage a cache of directory blocks. 1431558Srgrimes */ 1441558Srgrimesstruct bufarea * 1451558Srgrimesgetdatablk(blkno, size) 1461558Srgrimes daddr_t blkno; 1471558Srgrimes long size; 1481558Srgrimes{ 1491558Srgrimes register struct bufarea *bp; 1501558Srgrimes 1511558Srgrimes for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next) 1521558Srgrimes if (bp->b_bno == fsbtodb(&sblock, blkno)) 1531558Srgrimes goto foundit; 1541558Srgrimes for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev) 1551558Srgrimes if ((bp->b_flags & B_INUSE) == 0) 1561558Srgrimes break; 1571558Srgrimes if (bp == &bufhead) 1581558Srgrimes errexit("deadlocked buffer pool\n"); 1591558Srgrimes getblk(bp, blkno, size); 1601558Srgrimes /* fall through */ 1611558Srgrimesfoundit: 1621558Srgrimes totalreads++; 1631558Srgrimes bp->b_prev->b_next = bp->b_next; 1641558Srgrimes bp->b_next->b_prev = bp->b_prev; 1651558Srgrimes bp->b_prev = &bufhead; 1661558Srgrimes bp->b_next = bufhead.b_next; 1671558Srgrimes bufhead.b_next->b_prev = bp; 1681558Srgrimes bufhead.b_next = bp; 1691558Srgrimes bp->b_flags |= B_INUSE; 1701558Srgrimes return (bp); 1711558Srgrimes} 1721558Srgrimes 1731558Srgrimesvoid 1741558Srgrimesgetblk(bp, blk, size) 1751558Srgrimes register struct bufarea *bp; 1761558Srgrimes daddr_t blk; 1771558Srgrimes long size; 1781558Srgrimes{ 1791558Srgrimes daddr_t dblk; 1801558Srgrimes 1811558Srgrimes dblk = fsbtodb(&sblock, blk); 1821558Srgrimes if (bp->b_bno != dblk) { 1831558Srgrimes flush(fswritefd, bp); 1841558Srgrimes diskreads++; 1851558Srgrimes bp->b_errs = bread(fsreadfd, bp->b_un.b_buf, dblk, size); 1861558Srgrimes bp->b_bno = dblk; 1871558Srgrimes bp->b_size = size; 1881558Srgrimes } 1891558Srgrimes} 1901558Srgrimes 1911558Srgrimesflush(fd, bp) 1921558Srgrimes int fd; 1931558Srgrimes register struct bufarea *bp; 1941558Srgrimes{ 1951558Srgrimes register int i, j; 1961558Srgrimes 1971558Srgrimes if (!bp->b_dirty) 1981558Srgrimes return; 1991558Srgrimes if (bp->b_errs != 0) 2001558Srgrimes pfatal("WRITING %sZERO'ED BLOCK %d TO DISK\n", 2011558Srgrimes (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ", 2021558Srgrimes bp->b_bno); 2031558Srgrimes bp->b_dirty = 0; 2041558Srgrimes bp->b_errs = 0; 2051558Srgrimes bwrite(fd, bp->b_un.b_buf, bp->b_bno, (long)bp->b_size); 2061558Srgrimes if (bp != &sblk) 2071558Srgrimes return; 2081558Srgrimes for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 2091558Srgrimes bwrite(fswritefd, (char *)sblock.fs_csp[j], 2101558Srgrimes fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 2111558Srgrimes sblock.fs_cssize - i < sblock.fs_bsize ? 2121558Srgrimes sblock.fs_cssize - i : sblock.fs_bsize); 2131558Srgrimes } 2141558Srgrimes} 2151558Srgrimes 2161558Srgrimesrwerror(mesg, blk) 2171558Srgrimes char *mesg; 2181558Srgrimes daddr_t blk; 2191558Srgrimes{ 2201558Srgrimes 2211558Srgrimes if (preen == 0) 2221558Srgrimes printf("\n"); 2231558Srgrimes pfatal("CANNOT %s: BLK %ld", mesg, blk); 2241558Srgrimes if (reply("CONTINUE") == 0) 2251558Srgrimes errexit("Program terminated\n"); 2261558Srgrimes} 2271558Srgrimes 2281558Srgrimesckfini() 2291558Srgrimes{ 2301558Srgrimes register struct bufarea *bp, *nbp; 2311558Srgrimes int cnt = 0; 2321558Srgrimes 2331558Srgrimes if (fswritefd < 0) { 2341558Srgrimes (void)close(fsreadfd); 2351558Srgrimes return; 2361558Srgrimes } 2371558Srgrimes flush(fswritefd, &sblk); 2381558Srgrimes if (havesb && sblk.b_bno != SBOFF / dev_bsize && 2391558Srgrimes !preen && reply("UPDATE STANDARD SUPERBLOCK")) { 2401558Srgrimes sblk.b_bno = SBOFF / dev_bsize; 2411558Srgrimes sbdirty(); 2421558Srgrimes flush(fswritefd, &sblk); 2431558Srgrimes } 2441558Srgrimes flush(fswritefd, &cgblk); 2451558Srgrimes free(cgblk.b_un.b_buf); 2461558Srgrimes for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) { 2471558Srgrimes cnt++; 2481558Srgrimes flush(fswritefd, bp); 2491558Srgrimes nbp = bp->b_prev; 2501558Srgrimes free(bp->b_un.b_buf); 2511558Srgrimes free((char *)bp); 2521558Srgrimes } 2531558Srgrimes if (bufhead.b_size != cnt) 2541558Srgrimes errexit("Panic: lost %d buffers\n", bufhead.b_size - cnt); 2551558Srgrimes pbp = pdirbp = (struct bufarea *)0; 2561558Srgrimes if (debug) 2571558Srgrimes printf("cache missed %ld of %ld (%d%%)\n", diskreads, 2581558Srgrimes totalreads, (int)(diskreads * 100 / totalreads)); 2591558Srgrimes (void)close(fsreadfd); 2601558Srgrimes (void)close(fswritefd); 2611558Srgrimes} 2621558Srgrimes 2631558Srgrimesbread(fd, buf, blk, size) 2641558Srgrimes int fd; 2651558Srgrimes char *buf; 2661558Srgrimes daddr_t blk; 2671558Srgrimes long size; 2681558Srgrimes{ 2691558Srgrimes char *cp; 2701558Srgrimes int i, errs; 2711558Srgrimes off_t offset; 2721558Srgrimes 2731558Srgrimes offset = blk; 2741558Srgrimes offset *= dev_bsize; 2751558Srgrimes if (lseek(fd, offset, 0) < 0) 2761558Srgrimes rwerror("SEEK", blk); 2771558Srgrimes else if (read(fd, buf, (int)size) == size) 2781558Srgrimes return (0); 2791558Srgrimes rwerror("READ", blk); 2801558Srgrimes if (lseek(fd, offset, 0) < 0) 2811558Srgrimes rwerror("SEEK", blk); 2821558Srgrimes errs = 0; 2831558Srgrimes bzero(buf, (size_t)size); 2841558Srgrimes printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:"); 2851558Srgrimes for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) { 2861558Srgrimes if (read(fd, cp, (int)secsize) != secsize) { 2871558Srgrimes (void)lseek(fd, offset + i + secsize, 0); 2881558Srgrimes if (secsize != dev_bsize && dev_bsize != 1) 2891558Srgrimes printf(" %ld (%ld),", 2901558Srgrimes (blk * dev_bsize + i) / secsize, 2911558Srgrimes blk + i / dev_bsize); 2921558Srgrimes else 2931558Srgrimes printf(" %ld,", blk + i / dev_bsize); 2941558Srgrimes errs++; 2951558Srgrimes } 2961558Srgrimes } 2971558Srgrimes printf("\n"); 2981558Srgrimes return (errs); 2991558Srgrimes} 3001558Srgrimes 3011558Srgrimesbwrite(fd, buf, blk, size) 3021558Srgrimes int fd; 3031558Srgrimes char *buf; 3041558Srgrimes daddr_t blk; 3051558Srgrimes long size; 3061558Srgrimes{ 3071558Srgrimes int i; 3081558Srgrimes char *cp; 3091558Srgrimes off_t offset; 3101558Srgrimes 3111558Srgrimes if (fd < 0) 3121558Srgrimes return; 3131558Srgrimes offset = blk; 3141558Srgrimes offset *= dev_bsize; 3151558Srgrimes if (lseek(fd, offset, 0) < 0) 3161558Srgrimes rwerror("SEEK", blk); 3171558Srgrimes else if (write(fd, buf, (int)size) == size) { 3181558Srgrimes fsmodified = 1; 3191558Srgrimes return; 3201558Srgrimes } 3211558Srgrimes rwerror("WRITE", blk); 3221558Srgrimes if (lseek(fd, offset, 0) < 0) 3231558Srgrimes rwerror("SEEK", blk); 3241558Srgrimes printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:"); 3251558Srgrimes for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize) 3261558Srgrimes if (write(fd, cp, (int)dev_bsize) != dev_bsize) { 3271558Srgrimes (void)lseek(fd, offset + i + dev_bsize, 0); 3281558Srgrimes printf(" %ld,", blk + i / dev_bsize); 3291558Srgrimes } 3301558Srgrimes printf("\n"); 3311558Srgrimes return; 3321558Srgrimes} 3331558Srgrimes 3341558Srgrimes/* 3351558Srgrimes * allocate a data block with the specified number of fragments 3361558Srgrimes */ 3371558Srgrimesallocblk(frags) 3381558Srgrimes long frags; 3391558Srgrimes{ 3401558Srgrimes register int i, j, k; 3411558Srgrimes 3421558Srgrimes if (frags <= 0 || frags > sblock.fs_frag) 3431558Srgrimes return (0); 3441558Srgrimes for (i = 0; i < maxfsblock - sblock.fs_frag; i += sblock.fs_frag) { 3451558Srgrimes for (j = 0; j <= sblock.fs_frag - frags; j++) { 3461558Srgrimes if (testbmap(i + j)) 3471558Srgrimes continue; 3481558Srgrimes for (k = 1; k < frags; k++) 3491558Srgrimes if (testbmap(i + j + k)) 3501558Srgrimes break; 3511558Srgrimes if (k < frags) { 3521558Srgrimes j += k; 3531558Srgrimes continue; 3541558Srgrimes } 3551558Srgrimes for (k = 0; k < frags; k++) 3561558Srgrimes setbmap(i + j + k); 3571558Srgrimes n_blks += frags; 3581558Srgrimes return (i + j); 3591558Srgrimes } 3601558Srgrimes } 3611558Srgrimes return (0); 3621558Srgrimes} 3631558Srgrimes 3641558Srgrimes/* 3651558Srgrimes * Free a previously allocated block 3661558Srgrimes */ 3671558Srgrimesfreeblk(blkno, frags) 3681558Srgrimes daddr_t blkno; 3691558Srgrimes long frags; 3701558Srgrimes{ 3711558Srgrimes struct inodesc idesc; 3721558Srgrimes 3731558Srgrimes idesc.id_blkno = blkno; 3741558Srgrimes idesc.id_numfrags = frags; 3751558Srgrimes (void)pass4check(&idesc); 3761558Srgrimes} 3771558Srgrimes 3781558Srgrimes/* 3791558Srgrimes * Find a pathname 3801558Srgrimes */ 3811558Srgrimesgetpathname(namebuf, curdir, ino) 3821558Srgrimes char *namebuf; 3831558Srgrimes ino_t curdir, ino; 3841558Srgrimes{ 3851558Srgrimes int len; 3861558Srgrimes register char *cp; 3871558Srgrimes struct inodesc idesc; 3881558Srgrimes static int busy = 0; 3891558Srgrimes extern int findname(); 3901558Srgrimes 3911558Srgrimes if (curdir == ino && ino == ROOTINO) { 3921558Srgrimes (void)strcpy(namebuf, "/"); 3931558Srgrimes return; 3941558Srgrimes } 3951558Srgrimes if (busy || 3961558Srgrimes (statemap[curdir] != DSTATE && statemap[curdir] != DFOUND)) { 3971558Srgrimes (void)strcpy(namebuf, "?"); 3981558Srgrimes return; 3991558Srgrimes } 4001558Srgrimes busy = 1; 4011558Srgrimes bzero((char *)&idesc, sizeof(struct inodesc)); 4021558Srgrimes idesc.id_type = DATA; 4031558Srgrimes idesc.id_fix = IGNORE; 4041558Srgrimes cp = &namebuf[MAXPATHLEN - 1]; 4051558Srgrimes *cp = '\0'; 4061558Srgrimes if (curdir != ino) { 4071558Srgrimes idesc.id_parent = curdir; 4081558Srgrimes goto namelookup; 4091558Srgrimes } 4101558Srgrimes while (ino != ROOTINO) { 4111558Srgrimes idesc.id_number = ino; 4121558Srgrimes idesc.id_func = findino; 4131558Srgrimes idesc.id_name = ".."; 4141558Srgrimes if ((ckinode(ginode(ino), &idesc) & FOUND) == 0) 4151558Srgrimes break; 4161558Srgrimes namelookup: 4171558Srgrimes idesc.id_number = idesc.id_parent; 4181558Srgrimes idesc.id_parent = ino; 4191558Srgrimes idesc.id_func = findname; 4201558Srgrimes idesc.id_name = namebuf; 4211558Srgrimes if ((ckinode(ginode(idesc.id_number), &idesc)&FOUND) == 0) 4221558Srgrimes break; 4231558Srgrimes len = strlen(namebuf); 4241558Srgrimes cp -= len; 4251558Srgrimes bcopy(namebuf, cp, (size_t)len); 4261558Srgrimes *--cp = '/'; 4271558Srgrimes if (cp < &namebuf[MAXNAMLEN]) 4281558Srgrimes break; 4291558Srgrimes ino = idesc.id_number; 4301558Srgrimes } 4311558Srgrimes busy = 0; 4321558Srgrimes if (ino != ROOTINO) 4331558Srgrimes *--cp = '?'; 4341558Srgrimes bcopy(cp, namebuf, (size_t)(&namebuf[MAXPATHLEN] - cp)); 4351558Srgrimes} 4361558Srgrimes 4371558Srgrimesvoid 4381558Srgrimescatch() 4391558Srgrimes{ 4401558Srgrimes if (!doinglevel2) 4411558Srgrimes ckfini(); 4421558Srgrimes exit(12); 4431558Srgrimes} 4441558Srgrimes 4451558Srgrimes/* 4461558Srgrimes * When preening, allow a single quit to signal 4471558Srgrimes * a special exit after filesystem checks complete 4481558Srgrimes * so that reboot sequence may be interrupted. 4491558Srgrimes */ 4501558Srgrimesvoid 4511558Srgrimescatchquit() 4521558Srgrimes{ 4531558Srgrimes extern returntosingle; 4541558Srgrimes 4551558Srgrimes printf("returning to single-user after filesystem check\n"); 4561558Srgrimes returntosingle = 1; 4571558Srgrimes (void)signal(SIGQUIT, SIG_DFL); 4581558Srgrimes} 4591558Srgrimes 4601558Srgrimes/* 4611558Srgrimes * Ignore a single quit signal; wait and flush just in case. 4621558Srgrimes * Used by child processes in preen. 4631558Srgrimes */ 4641558Srgrimesvoid 4651558Srgrimesvoidquit() 4661558Srgrimes{ 4671558Srgrimes 4681558Srgrimes sleep(1); 4691558Srgrimes (void)signal(SIGQUIT, SIG_IGN); 4701558Srgrimes (void)signal(SIGQUIT, SIG_DFL); 4711558Srgrimes} 4721558Srgrimes 4731558Srgrimes/* 4741558Srgrimes * determine whether an inode should be fixed. 4751558Srgrimes */ 4761558Srgrimesdofix(idesc, msg) 4771558Srgrimes register struct inodesc *idesc; 4781558Srgrimes char *msg; 4791558Srgrimes{ 4801558Srgrimes 4811558Srgrimes switch (idesc->id_fix) { 4821558Srgrimes 4831558Srgrimes case DONTKNOW: 4841558Srgrimes if (idesc->id_type == DATA) 4851558Srgrimes direrror(idesc->id_number, msg); 4861558Srgrimes else 4871558Srgrimes pwarn(msg); 4881558Srgrimes if (preen) { 4891558Srgrimes printf(" (SALVAGED)\n"); 4901558Srgrimes idesc->id_fix = FIX; 4911558Srgrimes return (ALTERED); 4921558Srgrimes } 4931558Srgrimes if (reply("SALVAGE") == 0) { 4941558Srgrimes idesc->id_fix = NOFIX; 4951558Srgrimes return (0); 4961558Srgrimes } 4971558Srgrimes idesc->id_fix = FIX; 4981558Srgrimes return (ALTERED); 4991558Srgrimes 5001558Srgrimes case FIX: 5011558Srgrimes return (ALTERED); 5021558Srgrimes 5031558Srgrimes case NOFIX: 5041558Srgrimes case IGNORE: 5051558Srgrimes return (0); 5061558Srgrimes 5071558Srgrimes default: 5081558Srgrimes errexit("UNKNOWN INODESC FIX MODE %d\n", idesc->id_fix); 5091558Srgrimes } 5101558Srgrimes /* NOTREACHED */ 5111558Srgrimes} 5121558Srgrimes 5131558Srgrimes/* VARARGS1 */ 5141558Srgrimeserrexit(s1, s2, s3, s4) 5151558Srgrimes char *s1; 5161558Srgrimes{ 5171558Srgrimes printf(s1, s2, s3, s4); 5181558Srgrimes exit(8); 5191558Srgrimes} 5201558Srgrimes 5211558Srgrimes/* 5221558Srgrimes * An unexpected inconsistency occured. 5231558Srgrimes * Die if preening, otherwise just print message and continue. 5241558Srgrimes */ 5251558Srgrimes/* VARARGS1 */ 5261558Srgrimespfatal(s, a1, a2, a3) 5271558Srgrimes char *s; 5281558Srgrimes{ 5291558Srgrimes 5301558Srgrimes if (preen) { 5311558Srgrimes printf("%s: ", cdevname); 5321558Srgrimes printf(s, a1, a2, a3); 5331558Srgrimes printf("\n"); 5341558Srgrimes printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n", 5351558Srgrimes cdevname); 5361558Srgrimes exit(8); 5371558Srgrimes } 5381558Srgrimes printf(s, a1, a2, a3); 5391558Srgrimes} 5401558Srgrimes 5411558Srgrimes/* 5421558Srgrimes * Pwarn just prints a message when not preening, 5431558Srgrimes * or a warning (preceded by filename) when preening. 5441558Srgrimes */ 5451558Srgrimes/* VARARGS1 */ 5461558Srgrimespwarn(s, a1, a2, a3, a4, a5, a6) 5471558Srgrimes char *s; 5481558Srgrimes{ 5491558Srgrimes 5501558Srgrimes if (preen) 5511558Srgrimes printf("%s: ", cdevname); 5521558Srgrimes printf(s, a1, a2, a3, a4, a5, a6); 5531558Srgrimes} 5541558Srgrimes 5551558Srgrimes#ifndef lint 5561558Srgrimes/* 5571558Srgrimes * Stub for routines from kernel. 5581558Srgrimes */ 5591558Srgrimespanic(s) 5601558Srgrimes char *s; 5611558Srgrimes{ 5621558Srgrimes 5631558Srgrimes pfatal("INTERNAL INCONSISTENCY:"); 5641558Srgrimes errexit(s); 5651558Srgrimes} 5661558Srgrimes#endif 567