diff options
Diffstat (limited to 'sbin/fsck_ffs')
-rw-r--r-- | sbin/fsck_ffs/dir.c | 13 | ||||
-rw-r--r-- | sbin/fsck_ffs/fsck.h | 4 | ||||
-rw-r--r-- | sbin/fsck_ffs/inode.c | 16 | ||||
-rw-r--r-- | sbin/fsck_ffs/main.c | 19 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass1.c | 20 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass2.c | 35 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass5.c | 66 | ||||
-rw-r--r-- | sbin/fsck_ffs/setup.c | 12 | ||||
-rw-r--r-- | sbin/fsck_ffs/utilities.c | 30 |
9 files changed, 160 insertions, 55 deletions
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c index c1a06d0173b..4e5b32746bb 100644 --- a/sbin/fsck_ffs/dir.c +++ b/sbin/fsck_ffs/dir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dir.c,v 1.7 1997/10/06 20:22:31 deraadt Exp $ */ +/* $OpenBSD: dir.c,v 1.8 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: dir.c,v 1.20 1996/09/27 22:45:11 christos Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94"; #else -static char rcsid[] = "$OpenBSD: dir.c,v 1.7 1997/10/06 20:22:31 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: dir.c,v 1.8 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -333,12 +333,13 @@ adjust(idesc, lcnt) pinode(idesc->id_number); printf(" COUNT %d SHOULD BE %d", dp->di_nlink, dp->di_nlink - lcnt); - if (preen) { + if (preen || usedsoftdep) { if (lcnt < 0) { printf("\n"); pfatal("LINK COUNT INCREASING"); } - printf(" (ADJUSTED)\n"); + if (preen) + printf(" (ADJUSTED)\n"); } if (preen || reply("ADJUST") == 1) { dp->di_nlink -= lcnt; @@ -424,13 +425,15 @@ linkup(orphan, parentdir) lostdir = (dp->di_mode & IFMT) == IFDIR; pwarn("UNREF %s ", lostdir ? "DIR" : "FILE"); pinode(orphan); - if (preen && dp->di_size == 0) + if ((preen || usedsoftdep) && dp->di_size == 0) return (0); if (preen) printf(" (RECONNECTED)\n"); else if (reply("RECONNECT") == 0) return (0); + if (parentdir != 0) + lncntp[parentdir]++; if (lfdir == 0) { dp = ginode(ROOTINO); idesc.id_name = lfname; diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index 1583fcd1905..9f1146b6a79 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fsck.h,v 1.7 1999/03/01 07:45:17 d Exp $ */ +/* $OpenBSD: fsck.h,v 1.8 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: fsck.h,v 1.13 1996/10/11 20:15:46 thorpej Exp $ */ /* @@ -176,7 +176,9 @@ int cvtlevel; /* convert to newer file system format */ int doinglevel1; /* converting to new cylinder group format */ int doinglevel2; /* converting to new inode format */ int newinofmt; /* filesystem has new inode format */ +char usedsoftdep; /* just fix soft dependency inconsistencies */ int preen; /* just fix normal inconsistencies */ +char resolved; /* cleared if unresolved changes => not clean */ char havesb; /* superblock has been read */ char skipclean; /* skip clean file systems if preening */ int fsmodified; /* 1 => write done to file system */ diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c index ef613b4ed52..063ffc20bb4 100644 --- a/sbin/fsck_ffs/inode.c +++ b/sbin/fsck_ffs/inode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: inode.c,v 1.14 1999/08/06 20:41:06 deraadt Exp $ */ +/* $OpenBSD: inode.c,v 1.15 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: inode.c,v 1.23 1996/10/11 20:15:47 thorpej Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; #else -static char rcsid[] = "$OpenBSD: inode.c,v 1.14 1999/08/06 20:41:06 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: inode.c,v 1.15 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -573,6 +573,8 @@ allocino(request, type) { register ino_t ino; register struct dinode *dp; + struct cg *cgp = &cgrp; + int cg; time_t t; if (request == 0) @@ -584,9 +586,17 @@ allocino(request, type) break; if (ino == maxino) return (0); + cg = ino_to_cg(&sblock, ino); + getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize); + if (!cg_chkmagic(cgp)) + pfatal("CG %d: BAD MAGIC NUMBER\n", cg); + setbit(cg_inosused(cgp), ino % sblock.fs_ipg); + cgp->cg_cs.cs_nifree--; + switch (type & IFMT) { case IFDIR: statemap[ino] = DSTATE; + cgp->cg_cs.cs_ndir++; break; case IFREG: case IFLNK: @@ -595,6 +605,7 @@ allocino(request, type) default: return (0); } + cgdirty(); dp = ginode(ino); dp->di_db[0] = allocblk((long)1); if (dp->di_db[0] == 0) { @@ -602,6 +613,7 @@ allocino(request, type) return (0); } dp->di_mode = type; + dp->di_flags = 0; (void)time(&t); dp->di_atime = t; dp->di_mtime = dp->di_ctime = dp->di_atime; diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index de81f967257..443048b7ff7 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.17 2000/12/29 15:02:58 angelos Exp $ */ +/* $OpenBSD: main.c,v 1.18 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: main.c,v 1.22 1996/10/11 20:15:48 thorpej Exp $ */ /* @@ -44,7 +44,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; #else -static char rcsid[] = "$OpenBSD: main.c,v 1.17 2000/12/29 15:02:58 angelos Exp $"; +static char rcsid[] = "$OpenBSD: main.c,v 1.18 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -208,6 +208,13 @@ checkfilesys(filesys, mntpt, auxdata, child) return (0); } info_filesys = filesys; + + /* + * Cleared if any questions answered no. Used to decide if + * the superblock should be marked clean. + */ + resolved = 1; + /* * 1: scan inodes tallying blocks used */ @@ -223,7 +230,7 @@ checkfilesys(filesys, mntpt, auxdata, child) * 1b: locate first references to duplicates, if any */ if (duplist) { - if (preen) + if (preen || usedsoftdep) pfatal("INTERNAL ERROR: dups with -p"); printf("** Phase 1b - Rescan For More DUPS\n"); pass1b(); @@ -306,7 +313,9 @@ checkfilesys(filesys, mntpt, auxdata, child) bwrite(fswritefd, (char *)&sblock, fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE); } - ckfini(!rerun); /* Don't mark fs clean if fsck needs to be re-run */ + if (rerun) + resolved = 0; + ckfini(resolved); /* Don't mark fs clean if fsck needs to be re-run */ free(blockmap); free(statemap); free((char *)lncntp); @@ -314,7 +323,7 @@ checkfilesys(filesys, mntpt, auxdata, child) return (0); if (!preen) printf("\n***** FILE SYSTEM WAS MODIFIED *****\n"); - if (rerun) + if (rerun || !resolved) printf("\n***** PLEASE RERUN FSCK *****\n"); if (hotroot()) { struct statfs stfs_buf; diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c index 27faa9ee01a..3b8eae09457 100644 --- a/sbin/fsck_ffs/pass1.c +++ b/sbin/fsck_ffs/pass1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass1.c,v 1.7 1999/03/01 07:45:17 d Exp $ */ +/* $OpenBSD: pass1.c,v 1.8 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: pass1.c,v 1.16 1996/09/27 22:45:15 christos Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$OpenBSD: pass1.c,v 1.7 1999/03/01 07:45:17 d Exp $"; +static char rcsid[] = "$OpenBSD: pass1.c,v 1.8 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -230,8 +230,10 @@ checkinode(inumber, idesc) zlnp = (struct zlncnt *)malloc(sizeof *zlnp); if (zlnp == NULL) { pfatal("LINK COUNT TABLE OVERFLOW"); - if (reply("CONTINUE") == 0) + if (reply("CONTINUE") == 0) { + ckfini(0); errexit("%s", ""); + } } else { zlnp->zlncnt = inumber; zlnp->next = zlnhead; @@ -300,8 +302,10 @@ pass1check(idesc) idesc->id_number); if (preen) printf(" (SKIPPING)\n"); - else if (reply("CONTINUE") == 0) + else if (reply("CONTINUE") == 0) { + ckfini(0); errexit("%s", ""); + } return (STOP); } } @@ -318,15 +322,19 @@ pass1check(idesc) idesc->id_number); if (preen) printf(" (SKIPPING)\n"); - else if (reply("CONTINUE") == 0) + else if (reply("CONTINUE") == 0) { + ckfini(0); errexit("%s", ""); + } return (STOP); } new = (struct dups *)malloc(sizeof(struct dups)); if (new == NULL) { pfatal("DUP TABLE OVERFLOW."); - if (reply("CONTINUE") == 0) + if (reply("CONTINUE") == 0) { + ckfini(0); errexit("%s", ""); + } return (STOP); } new->dup = blkno; diff --git a/sbin/fsck_ffs/pass2.c b/sbin/fsck_ffs/pass2.c index de08a8c5fd3..69fced5af54 100644 --- a/sbin/fsck_ffs/pass2.c +++ b/sbin/fsck_ffs/pass2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass2.c,v 1.7 1999/03/01 07:45:18 d Exp $ */ +/* $OpenBSD: pass2.c,v 1.8 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: pass2.c,v 1.17 1996/09/27 22:45:15 christos Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94"; #else -static char rcsid[] = "$OpenBSD: pass2.c,v 1.7 1999/03/01 07:45:18 d Exp $"; +static char rcsid[] = "$OpenBSD: pass2.c,v 1.8 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -96,8 +96,10 @@ pass2() case USTATE: pfatal("ROOT INODE UNALLOCATED"); - if (reply("ALLOCATE") == 0) + if (reply("ALLOCATE") == 0) { + ckfini(0); errexit("%s", ""); + } if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) errexit("CANNOT ALLOCATE ROOT INODE\n"); break; @@ -110,8 +112,10 @@ pass2() errexit("CANNOT ALLOCATE ROOT INODE\n"); break; } - if (reply("CONTINUE") == 0) + if (reply("CONTINUE") == 0) { + ckfini(0); errexit("%s", ""); + } break; case FSTATE: @@ -123,8 +127,10 @@ pass2() errexit("CANNOT ALLOCATE ROOT INODE\n"); break; } - if (reply("FIX") == 0) + if (reply("FIX") == 0) { + ckfini(0); errexit("%s", ""); + } dp = ginode(ROOTINO); dp->di_mode &= ~IFMT; dp->di_mode |= IFDIR; @@ -170,8 +176,14 @@ pass2() } } else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) { getpathname(pathbuf, inp->i_number, inp->i_number); - pwarn("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d", - pathbuf, inp->i_isize, DIRBLKSIZ); + if (usedsoftdep) + pfatal("%s %s: LENGTH %d NOT MULTIPLE of %d", + "DIRECTORY", pathbuf, inp->i_isize, + DIRBLKSIZ); + else + pwarn("%s %s: LENGTH %d NOT MULTIPLE OF %d", + "DIRECTORY", pathbuf, inp->i_isize, + DIRBLKSIZ); if (preen) printf(" (ADJUSTED)\n"); inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ); @@ -425,7 +437,7 @@ again: break; if (statemap[dirp->d_ino] == FCLEAR) errmsg = "DUP/BAD"; - else if (!preen) + else if (!preen && !usedsoftdep) errmsg = "ZERO LENGTH DIRECTORY"; else { n = 1; @@ -450,8 +462,11 @@ again: pwarn("%s %s %s\n", pathbuf, "IS AN EXTRANEOUS HARD LINK TO DIRECTORY", namebuf); - if (preen) - printf(" (IGNORED)\n"); + if (preen) { + printf (" (REMOVED)\n"); + n = 1; + break; + } else if ((n = reply("REMOVE")) == 1) break; } diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index 08b510c2d6b..7ddd982f018 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pass5.c,v 1.7 1999/03/01 07:45:18 d Exp $ */ +/* $OpenBSD: pass5.c,v 1.8 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: pass5.c,v 1.16 1996/09/27 22:45:18 christos Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)pass5.c 8.6 (Berkeley) 11/30/94"; #else -static char rcsid[] = "$OpenBSD: pass5.c,v 1.7 1999/03/01 07:45:18 d Exp $"; +static char rcsid[] = "$OpenBSD: pass5.c,v 1.8 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -68,11 +68,12 @@ void pass5() { int c, blk, frags, basesize, sumsize, mapsize, savednrpos=0; + int inomapsize, blkmapsize; register struct fs *fs = &sblock; register struct cg *cg = &cgrp; daddr_t dbase, dmax; - register daddr_t d; - register long i, j; + daddr_t d; + long i, j, k; struct csum *cs; struct csum cstotal; struct inodesc idesc[3]; @@ -130,6 +131,8 @@ pass5() sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]); mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - (u_char *)&ocg->cg_iused[0]; + blkmapsize = howmany(fs->fs_fpg, NBBY); + inomapsize = &ocg->cg_magic - (u_char *)&ocg->cg_iused[0]; ocg->cg_magic = CG_MAGIC; savednrpos = fs->fs_nrpos; fs->fs_nrpos = 8; @@ -144,12 +147,12 @@ pass5() fs->fs_cpg * fs->fs_nrpos * sizeof(int16_t); newcg->cg_freeoff = newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); - if (fs->fs_contigsumsize <= 0) { - newcg->cg_nextfreeoff = newcg->cg_freeoff + - howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); - } else { - newcg->cg_clustersumoff = newcg->cg_freeoff + - howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) - + inomapsize = newcg->cg_freeoff - newcg->cg_iusedoff; + newcg->cg_nextfreeoff = newcg->cg_freeoff + + howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); + blkmapsize = newcg->cg_nextfreeoff - newcg->cg_freeoff; + if (fs->fs_contigsumsize > 0) { + newcg->cg_clustersumoff = newcg->cg_nextfreeoff - sizeof(int32_t); newcg->cg_clustersumoff = roundup(newcg->cg_clustersumoff, sizeof(int32_t)); @@ -166,6 +169,7 @@ pass5() break; default: + inomapsize = blkmapsize = sumsize = 0; errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", fs->fs_postblformat); } @@ -320,13 +324,6 @@ pass5() cgdirty(); continue; } - if (memcmp(cg_inosused(newcg), - cg_inosused(cg), mapsize) != 0 && - dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { - memcpy(cg_inosused(cg), cg_inosused(newcg), - (size_t)mapsize); - cgdirty(); - } if ((memcmp(newcg, cg, basesize) != 0 || memcmp(&cg_blktot(newcg)[0], &cg_blktot(cg)[0], sumsize) != 0) && @@ -336,6 +333,41 @@ pass5() &cg_blktot(newcg)[0], (size_t)sumsize); cgdirty(); } + if (usedsoftdep) { + for (i = 0; i < inomapsize; i++) { + j = cg_inosused(newcg)[i]; + if ((cg_inosused(cg)[i] & j) == j) + continue; + for (k = 0; k < NBBY; k++) { + if ((j & (1 << k)) == 0) + continue; + if (cg_inosused(cg)[i] & (1 << k)) + continue; + pwarn("ALLOCATED INODE %d MARKED FREE", + c * fs->fs_ipg + i * 8 + k); + } + } + for (i = 0; i < blkmapsize; i++) { + j = cg_blksfree(cg)[i]; + if ((cg_blksfree(newcg)[i] & j) == j) + continue; + for (k = 0; k < NBBY; k++) { + if ((j & (1 << k)) == 0) + continue; + if (cg_inosused(cg)[i] & (1 << k)) + continue; + pwarn("ALLOCATED FRAG %d MARKED FREE", + c * fs->fs_fpg + i * 8 + k); + } + } + } + if (memcmp(cg_inosused(newcg), cg_inosused(cg), + mapsize) != 0 && + dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { + memmove(cg_inosused(cg), cg_inosused(newcg), + (size_t)mapsize); + cgdirty(); + } } info_fn = NULL; if (fs->fs_postblformat == FS_42POSTBLFMT) diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index 482bcc7fdfa..75c04b77e7a 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: setup.c,v 1.7 1999/08/17 09:13:14 millert Exp $ */ +/* $OpenBSD: setup.c,v 1.8 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: setup.c,v 1.27 1996/09/27 22:45:19 christos Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94"; #else -static char rcsid[] = "$OpenBSD: setup.c,v 1.7 1999/08/17 09:13:14 millert Exp $"; +static char rcsid[] = "$OpenBSD: setup.c,v 1.8 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -336,8 +336,10 @@ setup(dev) fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), size) != 0 && !asked) { pfatal("BAD SUMMARY INFORMATION"); - if (reply("CONTINUE") == 0) + if (reply("CONTINUE") == 0) { + ckfini(0); errexit("%s", ""); + } asked++; } } @@ -382,6 +384,10 @@ setup(dev) goto badsblabel; } bufinit(); + if (sblock.fs_flags & FS_DOSOFTDEP) + usedsoftdep = 1; + else + usedsoftdep = 0; return (1); badsblabel: diff --git a/sbin/fsck_ffs/utilities.c b/sbin/fsck_ffs/utilities.c index 15ee9812b1b..fade9cef9b4 100644 --- a/sbin/fsck_ffs/utilities.c +++ b/sbin/fsck_ffs/utilities.c @@ -1,4 +1,4 @@ -/* $OpenBSD: utilities.c,v 1.10 2001/01/19 17:57:36 deraadt Exp $ */ +/* $OpenBSD: utilities.c,v 1.11 2001/03/02 08:33:55 art Exp $ */ /* $NetBSD: utilities.c,v 1.18 1996/09/27 22:45:20 christos Exp $ */ /* @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)utilities.c 8.1 (Berkeley) 6/5/93"; #else -static char rcsid[] = "$OpenBSD: utilities.c,v 1.10 2001/01/19 17:57:36 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: utilities.c,v 1.11 2001/03/02 08:33:55 art Exp $"; #endif #endif /* not lint */ @@ -101,6 +101,7 @@ reply(question) printf("\n"); if (!persevere && (nflag || fswritefd < 0)) { printf("%s? no\n\n", question); + resolved = 0; return (0); } if (yflag || (persevere && nflag)) { @@ -111,13 +112,17 @@ reply(question) printf("%s? [yn] ", question); (void) fflush(stdout); c = getc(stdin); - while (c != '\n' && getc(stdin) != '\n') - if (feof(stdin)) + while (c != '\n' && getc(stdin) != '\n') { + if (feof(stdin)) { + resolved = 0; return (0); + } + } } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N'); printf("\n"); if (c == 'y' || c == 'Y') return (1); + resolved = 0; return (0); } @@ -379,7 +384,8 @@ int allocblk(frags) long frags; { - register int i, j, k; + int i, j, k, cg, baseblk; + struct cg *cgp = &cgrp; if (frags <= 0 || frags > sblock.fs_frag) return (0); @@ -394,9 +400,21 @@ allocblk(frags) j += k; continue; } - for (k = 0; k < frags; k++) + cg = dtog(&sblock, i + j); + getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize); + if (!cg_chkmagic(cgp)) + pfatal("CG %d: BAD MAGIC NUMBER\n", cg); + baseblk = dtogd(&sblock, i + j); + + for (k = 0; k < frags; k++) { setbmap(i + j + k); + clrbit(cg_blksfree(cgp), baseblk + k); + } n_blks += frags; + if (frags == sblock.fs_frag) + cgp->cg_cs.cs_nbfree--; + else + cgp->cg_cs.cs_nffree -= frags; return (i + j); } } |