summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ifs
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-03-08 09:59:44 +0000
committerjulian <julian@FreeBSD.org>1998-03-08 09:59:44 +0000
commit10c5ccc30ae8155c4d8bd25aeffd9ed0e476c387 (patch)
treed2ed60b6b9462fe6eebf4796c39dfcf3cec39874 /sbin/fsck_ifs
parent1d108bde84c6b5fa5d119363c4f401cc3dcc8110 (diff)
downloadFreeBSD-src-10c5ccc30ae8155c4d8bd25aeffd9ed0e476c387.zip
FreeBSD-src-10c5ccc30ae8155c4d8bd25aeffd9ed0e476c387.tar.gz
Reviewed by: dyson@freebsd.org (john Dyson), dg@root.com (david greenman)
Submitted by: Kirk McKusick (mcKusick@mckusick.com) Obtained from: WHistle development tree
Diffstat (limited to 'sbin/fsck_ifs')
-rw-r--r--sbin/fsck_ifs/dir.c9
-rw-r--r--sbin/fsck_ifs/fsck.h2
-rw-r--r--sbin/fsck_ifs/inode.c11
-rw-r--r--sbin/fsck_ifs/main.c22
-rw-r--r--sbin/fsck_ifs/pass1.c16
-rw-r--r--sbin/fsck_ifs/pass2.c31
-rw-r--r--sbin/fsck_ifs/pass5.c60
-rw-r--r--sbin/fsck_ifs/setup.c8
-rw-r--r--sbin/fsck_ifs/utilities.c41
9 files changed, 152 insertions, 48 deletions
diff --git a/sbin/fsck_ifs/dir.c b/sbin/fsck_ifs/dir.c
index 4b6999b..6ab67d3 100644
--- a/sbin/fsck_ifs/dir.c
+++ b/sbin/fsck_ifs/dir.c
@@ -315,12 +315,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;
@@ -406,13 +407,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_ifs/fsck.h b/sbin/fsck_ifs/fsck.h
index 1967691..4e0271d 100644
--- a/sbin/fsck_ifs/fsck.h
+++ b/sbin/fsck_ifs/fsck.h
@@ -176,6 +176,8 @@ 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 */
+char resolved; /* cleared if unresolved changes => not clean */
char preen; /* just fix normal inconsistencies */
char hotroot; /* checking root device */
char havesb; /* superblock has been read */
diff --git a/sbin/fsck_ifs/inode.c b/sbin/fsck_ifs/inode.c
index 429dd3b..74561c8 100644
--- a/sbin/fsck_ifs/inode.c
+++ b/sbin/fsck_ifs/inode.c
@@ -559,6 +559,8 @@ allocino(request, type)
{
register ino_t ino;
register struct dinode *dp;
+ struct cg *cgp = &cgrp;
+ int cg;
if (request == 0)
request = ROOTINO;
@@ -569,9 +571,16 @@ 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:
@@ -580,12 +589,14 @@ allocino(request, type)
default:
return (0);
}
+ cgdirty();
dp = ginode(ino);
dp->di_db[0] = allocblk((long)1);
if (dp->di_db[0] == 0) {
statemap[ino] = USTATE;
return (0);
}
+ dp->di_flags = 0;
dp->di_mode = type;
dp->di_atime = time(NULL);
dp->di_mtime = dp->di_ctime = dp->di_atime;
diff --git a/sbin/fsck_ifs/main.c b/sbin/fsck_ifs/main.c
index dcb7006..b4bc2c9 100644
--- a/sbin/fsck_ifs/main.c
+++ b/sbin/fsck_ifs/main.c
@@ -42,7 +42,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
#endif
static const char rcsid[] =
- "$Id$";
+ "$Id: main.c,v 1.12 1997/12/20 22:24:32 bde Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -210,6 +210,11 @@ checkfilesys(filesys, mntpt, auxdata, child)
}
/*
+ * Cleared if any questions answered no. Used to decide if
+ * the superblock should be marked clean.
+ */
+ resolved = 1;
+ /*
* 1: scan inodes tallying blocks used
*/
if (preen == 0) {
@@ -224,7 +229,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,19 +311,20 @@ checkfilesys(filesys, mntpt, auxdata, child)
bwrite(fswritefd, (char *)&sblock,
fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE);
}
- if (!hotroot) {
- ckfini(1);
- } else {
+ if (rerun)
+ resolved = 0;
+ flags = 0;
+ if (hotroot) {
struct statfs stfs_buf;
/*
* Check to see if root is mounted read-write.
*/
if (statfs("/", &stfs_buf) == 0)
flags = stfs_buf.f_flags;
- else
- flags = 0;
- ckfini(flags & MNT_RDONLY);
+ if ((flags & MNT_RDONLY) == 0)
+ resolved = 0;
}
+ ckfini(resolved);
free(blockmap);
free(statemap);
free((char *)lncntp);
diff --git a/sbin/fsck_ifs/pass1.c b/sbin/fsck_ifs/pass1.c
index 9958277..181f858 100644
--- a/sbin/fsck_ifs/pass1.c
+++ b/sbin/fsck_ifs/pass1.c
@@ -200,8 +200,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);
exit(EEXIT);
+ }
} else {
zlnp->zlncnt = inumber;
zlnp->next = zlnhead;
@@ -270,8 +272,10 @@ pass1check(idesc)
idesc->id_number);
if (preen)
printf(" (SKIPPING)\n");
- else if (reply("CONTINUE") == 0)
+ else if (reply("CONTINUE") == 0) {
+ ckfini(0);
exit(EEXIT);
+ }
return (STOP);
}
}
@@ -288,15 +292,19 @@ pass1check(idesc)
idesc->id_number);
if (preen)
printf(" (SKIPPING)\n");
- else if (reply("CONTINUE") == 0)
+ else if (reply("CONTINUE") == 0) {
+ ckfini(0);
exit(EEXIT);
+ }
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);
exit(EEXIT);
+ }
return (STOP);
}
new->dup = blkno;
diff --git a/sbin/fsck_ifs/pass2.c b/sbin/fsck_ifs/pass2.c
index 445f6f1..ebc33b8 100644
--- a/sbin/fsck_ifs/pass2.c
+++ b/sbin/fsck_ifs/pass2.c
@@ -66,8 +66,10 @@ pass2()
case USTATE:
pfatal("ROOT INODE UNALLOCATED");
- if (reply("ALLOCATE") == 0)
+ if (reply("ALLOCATE") == 0) {
+ ckfini(0);
exit(EEXIT);
+ }
if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break;
@@ -80,8 +82,10 @@ pass2()
errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break;
}
- if (reply("CONTINUE") == 0)
+ if (reply("CONTINUE") == 0) {
+ ckfini(0);
exit(EEXIT);
+ }
break;
case FSTATE:
@@ -93,8 +97,10 @@ pass2()
errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
break;
}
- if (reply("FIX") == 0)
+ if (reply("FIX") == 0) {
+ ckfini(0);
exit(EEXIT);
+ }
dp = ginode(ROOTINO);
dp->di_mode &= ~IFMT;
dp->di_mode |= IFDIR;
@@ -139,8 +145,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);
@@ -394,7 +406,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;
@@ -423,8 +435,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_ifs/pass5.c b/sbin/fsck_ifs/pass5.c
index 3dd0c1a..873f008 100644
--- a/sbin/fsck_ifs/pass5.c
+++ b/sbin/fsck_ifs/pass5.c
@@ -50,11 +50,12 @@ void
pass5()
{
int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
+ int inomapsize, blkmapsize;
struct fs *fs = &sblock;
struct cg *cg = &cgrp;
ufs_daddr_t dbase, dmax;
ufs_daddr_t d;
- long i, j;
+ long i, j, k;
struct csum *cs;
struct csum cstotal;
struct inodesc idesc[3];
@@ -112,6 +113,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_free[0] - (u_char *)&ocg->cg_iused[0];
ocg->cg_magic = CG_MAGIC;
savednrpos = fs->fs_nrpos;
fs->fs_nrpos = 8;
@@ -126,12 +129,12 @@ pass5()
fs->fs_cpg * fs->fs_nrpos * sizeof(short);
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(long);
newcg->cg_clustersumoff =
roundup(newcg->cg_clustersumoff, sizeof(long));
@@ -148,7 +151,7 @@ pass5()
break;
default:
- sumsize = 0; /* keep lint happy */
+ inomapsize = blkmapsize = sumsize = 0; /* keep lint happy */
errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
fs->fs_postblformat);
}
@@ -299,13 +302,6 @@ pass5()
cgdirty();
continue;
}
- 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();
- }
if ((memcmp(newcg, cg, basesize) != 0 ||
memcmp(&cg_blktot(newcg)[0],
&cg_blktot(cg)[0], sumsize) != 0) &&
@@ -315,6 +311,40 @@ 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();
+ }
}
if (fs->fs_postblformat == FS_42POSTBLFMT)
fs->fs_nrpos = savednrpos;
diff --git a/sbin/fsck_ifs/setup.c b/sbin/fsck_ifs/setup.c
index 28e7e4b..f464b63 100644
--- a/sbin/fsck_ifs/setup.c
+++ b/sbin/fsck_ifs/setup.c
@@ -255,8 +255,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);
exit(EEXIT);
+ }
asked++;
}
}
@@ -311,6 +313,10 @@ setup(dev)
goto badsb;
}
bufinit();
+ if (sblock.fs_flags & FS_DOSOFTDEP)
+ usedsoftdep = 1;
+ else
+ usedsoftdep = 0;
return (1);
badsb:
diff --git a/sbin/fsck_ifs/utilities.c b/sbin/fsck_ifs/utilities.c
index 30c31cf..465fb3b 100644
--- a/sbin/fsck_ifs/utilities.c
+++ b/sbin/fsck_ifs/utilities.c
@@ -87,6 +87,7 @@ reply(question)
printf("\n");
if (!persevere && (nflag || fswritefd < 0)) {
printf("%s? no\n\n", question);
+ resolved = 0;
return (0);
}
if (yflag || (persevere && nflag)) {
@@ -97,13 +98,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);
}
@@ -360,7 +365,8 @@ ufs_daddr_t
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);
@@ -375,9 +381,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;
+ cgdirty();
return (i + j);
}
}
@@ -545,7 +563,8 @@ dofix(idesc, msg)
/*
* An unexpected inconsistency occured.
- * Die if preening, otherwise just print message and continue.
+ * Die if preening or filesystem is running with soft dependency protocol,
+ * otherwise just print message and continue.
*/
void
#if __STDC__
@@ -565,19 +584,23 @@ pfatal(fmt, va_alist)
if (!preen) {
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
+ if (usedsoftdep)
+ (void)fprintf(stderr,
+ "\nUNEXPECTED SOFTDEP INCONSISTENCY\n");
return;
}
(void)fprintf(stderr, "%s: ", cdevname);
(void)vfprintf(stderr, fmt, ap);
(void)fprintf(stderr,
- "\n%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
- cdevname);
+ "\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
+ cdevname, usedsoftdep ? " SOFTDEP " : " ");
+ ckfini(0);
exit(EEXIT);
}
/*
- * Pwarn just prints a message when not preening,
- * or a warning (preceded by filename) when preening.
+ * Pwarn just prints a message when not preening or running soft dependency
+ * protocol, or a warning (preceded by filename) when preening.
*/
void
#if __STDC__
OpenPOWER on IntegriCloud