summaryrefslogtreecommitdiffstats
path: root/sbin/fsck/preen.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2001-03-30 08:01:34 +0000
committerphk <phk@FreeBSD.org>2001-03-30 08:01:34 +0000
commitc59a8fb48cd1948588682270e91ef3b2aa3f0848 (patch)
tree68b730992a0ac632dd48e727a15746bb7d8ad3e8 /sbin/fsck/preen.c
parent759dbf1c02c26b2f07532ad1a58a3d7aef8e7ae1 (diff)
downloadFreeBSD-src-c59a8fb48cd1948588682270e91ef3b2aa3f0848.zip
FreeBSD-src-c59a8fb48cd1948588682270e91ef3b2aa3f0848.tar.gz
This change sanitizes the way fsck deals with pass numbers.
Consider this /etc/fstab: # Device Mountpoint FStype Options Dump Pass# /dev/ad1s1b none swap sw 0 0 /dev/ad0s1b none swap sw 0 0 /dev/ad0s1a / ufs rw 1 1 /dev/ad0s1e /home ufs rw 2 2 /dev/ad1s1e /tmp ufs rw 2 2 /dev/ad1s1f /usr ufs rw 2 2 /dev/ccd0c /syv ufs rw 2 11 proc /proc procfs rw 0 0 ccd0c is striped over /dev/ad0f and /dev/ad1g Without this pass, fsck in preen mode will check ad0s1a first, and then issue three processes in parallel: One process doing ad0s1e One process doing ad1s1e and ad1s1f One process doing ccd0c There is no way to tell it that ccd0c overlaps ad0 and ad1. With the patch, it will do it this way: pass 2: One process doing ad0s1e One process doing ad1s1e and ad1s1f and when they are complete: pass 11: One process doing ccd0c This is much faster and more sane. Valid pass numbers are anything from 1 to INTMAX-1. I retired the '-l' option which tried to allow people to do something like this, but which didn't work and which complicated the code an awful lot.
Diffstat (limited to 'sbin/fsck/preen.c')
-rw-r--r--sbin/fsck/preen.c93
1 files changed, 45 insertions, 48 deletions
diff --git a/sbin/fsck/preen.c b/sbin/fsck/preen.c
index 3beda3e..ee1aad2 100644
--- a/sbin/fsck/preen.c
+++ b/sbin/fsck/preen.c
@@ -87,8 +87,8 @@ static int startdisk __P((struct diskentry *,
static void printpart __P((void));
int
-checkfstab(flags, maxrun, docheck, checkit)
- int flags, maxrun;
+checkfstab(flags, docheck, checkit)
+ int flags;
void *(*docheck) __P((struct fstab *));
int (*checkit) __P((const char *, const char *, const char *, void *,
pid_t *));
@@ -96,7 +96,7 @@ checkfstab(flags, maxrun, docheck, checkit)
struct fstab *fs;
struct diskentry *d, *nextdisk;
struct partentry *p;
- int ret, pid, retcode, passno, sumstatus, status;
+ int ret, pid, retcode, passno, sumstatus, status, nextpass;
void *auxarg;
const char *name;
@@ -105,7 +105,12 @@ checkfstab(flags, maxrun, docheck, checkit)
sumstatus = 0;
- for (passno = 1; passno <= 2; passno++) {
+ nextpass = 0;
+ for (passno = 1; nextpass != INT_MAX; passno = nextpass) {
+ if (flags & CHECK_DEBUG)
+ printf("pass %d\n", passno);
+
+ nextpass = INT_MAX;
if (setfsent() == 0) {
warnx("Can't open checklist file: %s\n", _PATH_FSTAB);
return (8);
@@ -114,14 +119,17 @@ checkfstab(flags, maxrun, docheck, checkit)
if ((auxarg = (*docheck)(fs)) == NULL)
continue;
- /* XXX We don't need to search for blockdevs .. */
- /* name = blockcheck(fs->fs_spec); */
name = fs->fs_spec;
+ if (fs->fs_passno > passno && fs->fs_passno < nextpass)
+ nextpass = fs->fs_passno;
+
+ if (passno != fs->fs_passno)
+ continue;
+
if (flags & CHECK_DEBUG)
printf("pass %d, name %s\n", passno, name);
- if ((flags & CHECK_PREEN) == 0 ||
- (passno == 1 && fs->fs_passno == 1)) {
+ if ((flags & CHECK_PREEN) == 0 || passno == 1) {
if (name == NULL) {
if (flags & CHECK_PREEN)
return 8;
@@ -133,36 +141,33 @@ checkfstab(flags, maxrun, docheck, checkit)
if (sumstatus)
return (sumstatus);
- } else if (passno == 2 && fs->fs_passno > 1) {
- if (name == NULL) {
- (void) fprintf(stderr,
- "BAD DISK NAME %s\n", fs->fs_spec);
- sumstatus |= 8;
- continue;
- }
- addpart(fs->fs_vfstype, name, fs->fs_file,
- auxarg);
+ continue;
+ }
+ if (name == NULL) {
+ (void) fprintf(stderr,
+ "BAD DISK NAME %s\n", fs->fs_spec);
+ sumstatus |= 8;
+ continue;
}
+ addpart(fs->fs_vfstype, name, fs->fs_file,
+ auxarg);
}
- if ((flags & CHECK_PREEN) == 0)
- return 0;
- }
- if (flags & CHECK_DEBUG)
- printpart();
+ if ((flags & CHECK_PREEN) == 0 || passno == 1)
+ continue;
- if (flags & CHECK_PREEN) {
- if (maxrun == 0)
- maxrun = ndisks;
- if (maxrun > ndisks)
- maxrun = ndisks;
- nextdisk = TAILQ_FIRST(&diskh);
- for (passno = 0; passno < maxrun; ++passno) {
+ if (flags & CHECK_DEBUG) {
+ printf("Parallel start\n");
+ printpart();
+ }
+
+ TAILQ_FOREACH(nextdisk, &diskh, d_entries) {
if ((ret = startdisk(nextdisk, checkit)) != 0)
return ret;
- nextdisk = TAILQ_NEXT(nextdisk, d_entries);
}
+ if (flags & CHECK_DEBUG)
+ printf("Parallel wait\n");
while ((pid = wait(&status)) != -1) {
TAILQ_FOREACH(d, &diskh, d_entries)
if (d->d_pid == pid)
@@ -207,28 +212,20 @@ checkfstab(flags, maxrun, docheck, checkit)
d->d_pid = 0;
nrun--;
- if (TAILQ_EMPTY(&d->d_part))
+ if (TAILQ_EMPTY(&d->d_part)) {
+ TAILQ_REMOVE(&diskh, d, d_entries);
ndisks--;
-
- if (nextdisk == NULL) {
- if (!TAILQ_EMPTY(&d->d_part)) {
- if ((ret = startdisk(d, checkit)) != 0)
- return ret;
- }
- } else if (nrun < maxrun && nrun < ndisks) {
- for ( ;; ) {
- nextdisk = TAILQ_NEXT(nextdisk, d_entries);
- if (nextdisk == NULL)
- nextdisk = TAILQ_FIRST(&diskh);
- if (!TAILQ_EMPTY(&nextdisk->d_part)
- && nextdisk->d_pid == 0)
- break;
- }
- if ((ret = startdisk(nextdisk, checkit)) != 0)
- return ret;
}
}
+ if (flags & CHECK_DEBUG) {
+ printf("Parallel end\n");
+ printpart();
+ }
}
+
+ if (!(flags & CHECK_PREEN))
+ return 0;
+
if (sumstatus) {
p = TAILQ_FIRST(&badh);
if (p == NULL)
OpenPOWER on IntegriCloud