summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs/pass1.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-12-03 02:27:35 +0000
committerjulian <julian@FreeBSD.org>1998-12-03 02:27:35 +0000
commitc1ef9f83c919949e90841ae0990aa9a0273d6490 (patch)
tree766d55719160577172499b05ce54cc96670cf3c4 /sbin/fsck_ffs/pass1.c
parent1a5eceeafeb45fc95a5c9fe1830e0d3e349ec69a (diff)
downloadFreeBSD-src-c1ef9f83c919949e90841ae0990aa9a0273d6490.zip
FreeBSD-src-c1ef9f83c919949e90841ae0990aa9a0273d6490.tar.gz
Reviewed by: Don Lewis <Don.Lewis@tsc.tdk.com>
Submitted by: Kirk McKusick <mckusick@McKusick.COM> Obtained from: Mckusick, BSDI and a host of others This exactly matches Kirks sources imported under the Tag MCKUSICK2. These are as supplied by kirk with one small change needed to compile under freeBSD. Some FreeBSD patches will be added back, though many have been added to Kirk's sources already.
Diffstat (limited to 'sbin/fsck_ffs/pass1.c')
-rw-r--r--sbin/fsck_ffs/pass1.c110
1 files changed, 89 insertions, 21 deletions
diff --git a/sbin/fsck_ffs/pass1.c b/sbin/fsck_ffs/pass1.c
index 30c0e7d..1ce4471 100644
--- a/sbin/fsck_ffs/pass1.c
+++ b/sbin/fsck_ffs/pass1.c
@@ -32,14 +32,11 @@
*/
#ifndef lint
-#if 0
static const char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$Id: pass1.c,v 1.11 1998/06/15 07:07:16 charnier Exp $";
#endif /* not lint */
#include <sys/param.h>
+#include <sys/time.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
@@ -52,14 +49,17 @@ static const char rcsid[] =
static ufs_daddr_t badblk;
static ufs_daddr_t dupblk;
+static ino_t lastino; /* last inode in use */
static void checkinode __P((ino_t inumber, struct inodesc *));
void
pass1()
{
+ u_int8_t *cp;
ino_t inumber;
- int c, i, cgd;
+ int c, i, cgd, inosused;
+ struct inostat *info;
struct inodesc idesc;
/*
@@ -81,15 +81,84 @@ pass1()
memset(&idesc, 0, sizeof(struct inodesc));
idesc.id_type = ADDR;
idesc.id_func = pass1check;
- inumber = 0;
n_files = n_blks = 0;
- resetinodebuf();
for (c = 0; c < sblock.fs_ncg; c++) {
- for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
- if (inumber < ROOTINO)
+ inumber = c * sblock.fs_ipg;
+ setinodebuf(inumber);
+ inosused = sblock.fs_ipg;
+ /*
+ * If we are using soft updates, then we can trust the
+ * cylinder group inode allocation maps to tell us which
+ * inodes are allocated. We will scan the used inode map
+ * to find the inodes that are really in use, and then
+ * read only those inodes in from disk.
+ */
+ if (preen && usedsoftdep) {
+ getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
+ if (!cg_chkmagic(&cgrp))
+ pfatal("CG %d: BAD MAGIC NUMBER\n", c);
+ cp = &cg_inosused(&cgrp)[(sblock.fs_ipg - 1) / NBBY];
+ for ( ; inosused > 0; inosused -= NBBY, cp--) {
+ if (*cp == 0)
+ continue;
+ for (i = 1 << (NBBY - 1); i > 0; i >>= 1) {
+ if (*cp & i)
+ break;
+ inosused--;
+ }
+ break;
+ }
+ if (inosused < 0)
+ inosused = 0;
+ }
+ /*
+ * Allocate inoinfo structures for the allocated inodes.
+ */
+ inostathead[c].il_numalloced = inosused;
+ if (inosused == 0) {
+ inostathead[c].il_stat = 0;
+ continue;
+ }
+ info = calloc((unsigned)inosused, sizeof(struct inostat));
+ if (info == NULL)
+ pfatal("cannot alloc %u bytes for inoinfo\n",
+ (unsigned)(sizeof(struct inostat) * inosused));
+ inostathead[c].il_stat = info;
+ /*
+ * Scan the allocated inodes.
+ */
+ for (i = 0; i < inosused; i++, inumber++) {
+ if (inumber < ROOTINO) {
+ (void)getnextinode(inumber);
continue;
+ }
checkinode(inumber, &idesc);
}
+ lastino += 1;
+ if (inosused < sblock.fs_ipg || inumber == lastino)
+ continue;
+ /*
+ * If we were not able to determine in advance which inodes
+ * were in use, then reduce the size of the inoinfo structure
+ * to the size necessary to describe the inodes that we
+ * really found.
+ */
+ inosused = lastino - (c * sblock.fs_ipg);
+ if (inosused < 0)
+ inosused = 0;
+ inostathead[c].il_numalloced = inosused;
+ if (inosused == 0) {
+ free(inostathead[c].il_stat);
+ inostathead[c].il_stat = 0;
+ continue;
+ }
+ info = calloc((unsigned)inosused, sizeof(struct inostat));
+ if (info == NULL)
+ pfatal("cannot alloc %u bytes for inoinfo\n",
+ (unsigned)(sizeof(struct inostat) * inosused));
+ memmove(info, inostathead[c].il_stat, inosused * sizeof(*info));
+ free(inostathead[c].il_stat);
+ inostathead[c].il_stat = info;
}
freeinodebuf();
}
@@ -120,7 +189,7 @@ checkinode(inumber, idesc)
inodirty();
}
}
- statemap[inumber] = USTATE;
+ inoinfo(inumber)->ino_state = USTATE;
return;
}
lastino = inumber;
@@ -158,8 +227,7 @@ checkinode(inumber, idesc)
if (debug) {
symbuf[dp->di_size] = 0;
printf("convert symlink %lu(%s) of size %ld\n",
- (u_long)inumber, symbuf,
- (long)dp->di_size);
+ (u_long)inumber, symbuf, (long)dp->di_size);
}
dp = ginode(inumber);
memmove(dp->di_shortlink, symbuf, (long)dp->di_size);
@@ -170,8 +238,7 @@ checkinode(inumber, idesc)
* Fake ndb value so direct/indirect block checks below
* will detect any garbage after symlink string.
*/
- if (dp->di_size < sblock.fs_maxsymlinklen ||
- dp->di_blocks == 0) {
+ if (dp->di_size < sblock.fs_maxsymlinklen) {
ndb = howmany(dp->di_size, sizeof(ufs_daddr_t));
if (ndb > NDADDR) {
j = ndb - NDADDR;
@@ -200,7 +267,7 @@ checkinode(inumber, idesc)
if (ftypeok(dp) == 0)
goto unknown;
n_files++;
- lncntp[inumber] = dp->di_nlink;
+ inoinfo(inumber)->ino_linkcnt = dp->di_nlink;
if (dp->di_nlink <= 0) {
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
if (zlnp == NULL) {
@@ -217,13 +284,14 @@ checkinode(inumber, idesc)
}
if (mode == IFDIR) {
if (dp->di_size == 0)
- statemap[inumber] = DCLEAR;
+ inoinfo(inumber)->ino_state = DCLEAR;
else
- statemap[inumber] = DSTATE;
+ inoinfo(inumber)->ino_state = DSTATE;
cacheino(dp, inumber);
+ countdirs++;
} else
- statemap[inumber] = FSTATE;
- typemap[inumber] = IFTODT(mode);
+ inoinfo(inumber)->ino_state = FSTATE;
+ inoinfo(inumber)->ino_type = IFTODT(mode);
if (doinglevel2 &&
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
dp = ginode(inumber);
@@ -251,9 +319,9 @@ checkinode(inumber, idesc)
return;
unknown:
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
- statemap[inumber] = FCLEAR;
+ inoinfo(inumber)->ino_state = FCLEAR;
if (reply("CLEAR") == 1) {
- statemap[inumber] = USTATE;
+ inoinfo(inumber)->ino_state = USTATE;
dp = ginode(inumber);
clearinode(dp);
inodirty();
OpenPOWER on IntegriCloud