Minor background cleanups:

1) Set the FS_NEEDSFSCK flag when unexpected problems are encountered.
2) Clear the FS_NEEDSFSCK flag after a successful foreground cleanup.
3) Refuse to run in background when the FS_NEEDSFSCK flag is set.
4) Avoid taking and removing a snapshot when the filesystem is already clean.
5) Properly implement the force cleaning (-f) flag when in preen mode.

Note that you need to have revision 1.21 (date: 2001/04/14 05:26:28) of
fs.h installed in <ufs/ffs/fs.h> defining FS_NEEDSFSCK for this to compile.
This commit is contained in:
Kirk McKusick 2001-04-16 22:22:21 +00:00
parent 7d6505e64e
commit 38375c40b8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=75557
5 changed files with 87 additions and 30 deletions

View File

@ -203,7 +203,6 @@ char snapname[BUFSIZ]; /* when doing snapshots, the name of the file */
char *cdevname; /* name of device being checked */
long dev_bsize; /* computed value of DEV_BSIZE */
long secsize; /* actual disk sector size */
char fflag; /* force check, ignore clean flag */
char nflag; /* assume a no response */
char yflag; /* assume a yes response */
int bkgrdflag; /* use a snapshot to run on an active system */
@ -313,6 +312,7 @@ void pfatal __P((const char *fmt, ...));
void pinode __P((ino_t ino));
void propagate __P((void));
void pwarn __P((const char *fmt, ...));
int readsb __P((int listerr));
int reply __P((char *question));
void rwerror __P((char *mesg, ufs_daddr_t blk));
void setinodebuf __P((ino_t));

View File

@ -321,7 +321,8 @@ ckfini(markclean)
errx(EEXIT, "panic: lost %d buffers", bufhead.b_size - cnt);
pbp = pdirbp = (struct bufarea *)0;
if (cursnapshot == 0 && sblock.fs_clean != markclean) {
sblock.fs_clean = markclean;
if ((sblock.fs_clean = markclean) != 0)
sblock.fs_flags &= ~(FS_UNCLEAN | FS_NEEDSFSCK);
sbdirty();
ofsmodified = fsmodified;
flush(fswritefd, &sblk);
@ -336,7 +337,7 @@ ckfini(markclean)
printf("\n***** FILE SYSTEM STILL DIRTY *****\n");
rerun = 1;
}
if (debug)
if (debug && totalreads > 0)
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
totalreads, (int)(diskreads * 100 / totalreads));
(void)close(fsreadfd);
@ -649,6 +650,19 @@ pfatal(fmt, va_alist)
if (usedsoftdep)
(void)fprintf(stderr,
"\nUNEXPECTED SOFT UPDATE INCONSISTENCY\n");
/*
* Force foreground fsck to clean up inconsistency.
*/
if (bkgrdflag) {
cmd.value = FS_NEEDSFSCK;
cmd.size = 1;
if (sysctlbyname("vfs.ffs.setflags", 0, 0,
&cmd, sizeof cmd) == -1)
pwarn("CANNOT SET FS_NEEDSFSCK FLAG\n");
fprintf(stderr, "CANNOT RUN IN BACKGROUND\n");
ckfini(0);
exit(EEXIT);
}
return;
}
if (cdevname == NULL)
@ -658,6 +672,16 @@ pfatal(fmt, va_alist)
(void)fprintf(stderr,
"\n%s: UNEXPECTED%sINCONSISTENCY; RUN fsck MANUALLY.\n",
cdevname, usedsoftdep ? " SOFT UPDATE " : " ");
/*
* Force foreground fsck to clean up inconsistency.
*/
if (bkgrdflag) {
cmd.value = FS_NEEDSFSCK;
cmd.size = 1;
if (sysctlbyname("vfs.ffs.setflags", 0, 0,
&cmd, sizeof cmd) == -1)
pwarn("CANNOT SET FS_NEEDSFSCK FLAG\n");
}
ckfini(0);
exit(EEXIT);
}

View File

@ -47,6 +47,7 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/mount.h>
#include <sys/resource.h>
@ -199,6 +200,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
cdevname = filesys;
if (debug && preen)
pwarn("starting\n");
sblock_init();
/*
* If we are to do a background check:
@ -211,14 +213,35 @@ checkfilesys(filesys, mntpt, auxdata, child)
if (bkgrdflag) {
if (mntp == NULL) {
bkgrdflag = 0;
pwarn("NOT MOUNTED, CANNOT RUN IN BACKGROUND\n");
pfatal("NOT MOUNTED, CANNOT RUN IN BACKGROUND\n");
} else if ((mntp->f_flags & MNT_SOFTDEP) == 0) {
bkgrdflag = 0;
pwarn("NOT USING SOFT UPDATES, CANNOT RUN IN BACKGROUND\n");
pfatal("NOT USING SOFT UPDATES, %s\n",
"CANNOT RUN IN BACKGROUND");
} else if ((mntp->f_flags & MNT_RDONLY) != 0) {
bkgrdflag = 0;
pwarn("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
} else {
pfatal("MOUNTED READ-ONLY, CANNOT RUN IN BACKGROUND\n");
} else if ((fsreadfd = open(filesys, O_RDONLY)) >= 0) {
if (readsb(0) != 0) {
if (sblock.fs_flags & FS_NEEDSFSCK) {
bkgrdflag = 0;
pfatal("UNEXPECTED INCONSISTENCY, %s\n",
"CANNOT RUN IN BACKGROUND\n");
}
if ((sblock.fs_flags & FS_UNCLEAN) == 0 &&
skipclean && preen) {
/*
* filesystem is clean;
* skip snapshot and report it clean
*/
pwarn("FILESYSTEM CLEAN; %s\n",
"SKIPPING CHECKS");
goto clean;
}
}
close(fsreadfd);
}
if (bkgrdflag) {
snprintf(snapname, sizeof snapname, "%s/.fsck_snapshot",
mntp->f_mntonname);
args.fspec = snapname;
@ -228,7 +251,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
if (errno == EEXIST && unlink(snapname) == 0)
continue;
bkgrdflag = 0;
pwarn("CANNOT CREATE SNAPSHOT %s: %s\n",
pfatal("CANNOT CREATE SNAPSHOT %s: %s\n",
snapname, strerror(errno));
break;
}
@ -243,6 +266,7 @@ checkfilesys(filesys, mntpt, auxdata, child)
pfatal("CAN'T CHECK FILE SYSTEM.");
return (0);
case -1:
clean:
pwarn("clean, %ld free ", sblock.fs_cstotal.cs_nffree +
sblock.fs_frag * sblock.fs_cstotal.cs_nbfree);
printf("(%d frags, %d blocks, %.1f%% fragmentation)\n",

View File

@ -377,7 +377,12 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
char buf[BUFSIZE];
long i, j, k, l, m, n, size;
int astart, aend, ustart, uend;
void (*msg) __P((const char *fmt, ...));
if (bkgrdflag)
msg = pfatal;
else
msg = pwarn;
astart = ustart = aend = uend = -1;
for (i = 0; i < mapsize; i++) {
j = *map1++;
@ -398,10 +403,10 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
continue;
}
if (astart == aend)
pfatal("ALLOCATED %s %d MARKED FREE\n",
(*msg)("ALLOCATED %s %d MARKED FREE\n",
name, astart);
else
pfatal("%s %sS %d-%d MARKED FREE\n",
(*msg)("%s %sS %d-%d MARKED FREE\n",
"ALLOCATED", name, astart, aend);
astart = aend = n;
} else {
@ -452,9 +457,9 @@ check_maps(map1, map2, mapsize, startvalue, name, opcode, skip, limit)
}
if (astart != -1)
if (astart == aend)
pfatal("ALLOCATED %s %d MARKED FREE\n", name, astart);
(*msg)("ALLOCATED %s %d MARKED FREE\n", name, astart);
else
pfatal("ALLOCATED %sS %d-%d MARKED FREE\n",
(*msg)("ALLOCATED %sS %d-%d MARKED FREE\n",
name, astart, aend);
if (ustart != -1) {
size = uend - ustart + 1;

View File

@ -62,7 +62,6 @@ struct bufarea asblk;
static void badsb __P((int listerr, char *s));
static int calcsb __P((char *dev, int devfd, struct fs *fs));
static struct disklabel *getdisklabel __P((char *s, int fd));
static int readsb __P((int listerr));
/*
* Read in a superblock finding an alternate if necessary.
@ -74,8 +73,7 @@ setup(dev)
char *dev;
{
long cg, size, asked, i, j;
long skipclean, bmapsize;
struct disklabel *lp;
long bmapsize;
off_t sizepb;
struct stat statb;
struct fs proto;
@ -83,7 +81,6 @@ setup(dev)
havesb = 0;
fswritefd = -1;
cursnapshot = 0;
skipclean = fflag ? 0 : preen;
if (stat(dev, &statb) < 0) {
printf("Can't stat %s: %s\n", dev, strerror(errno));
if (bkgrdflag) {
@ -160,18 +157,6 @@ setup(dev)
}
if (preen == 0)
printf("\n");
fsmodified = 0;
lfdir = 0;
initbarea(&sblk);
initbarea(&asblk);
sblk.b_un.b_buf = malloc(SBSIZE);
asblk.b_un.b_buf = malloc(SBSIZE);
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
errx(EEXIT, "cannot allocate space for superblock");
if ((lp = getdisklabel(NULL, fsreadfd)))
dev_bsize = secsize = lp->d_secsize;
else
dev_bsize = secsize = DEV_BSIZE;
/*
* Read in the superblock, looking for alternates if necessary
*/
@ -200,7 +185,7 @@ setup(dev)
pwarn("USING ALTERNATE SUPERBLOCK AT %d\n", bflag);
bflag = 0;
}
if (skipclean && sblock.fs_clean) {
if (skipclean && preen && sblock.fs_clean) {
pwarn("FILESYSTEM CLEAN; SKIPPING CHECKS\n");
return (-1);
}
@ -372,7 +357,7 @@ setup(dev)
/*
* Read in the super block and its summary info.
*/
static int
int
readsb(listerr)
int listerr;
{
@ -490,6 +475,25 @@ badsb(listerr, s)
pfatal("BAD SUPER BLOCK: %s\n", s);
}
sblock_init()
{
struct disklabel *lp;
fswritefd = -1;
fsmodified = 0;
lfdir = 0;
initbarea(&sblk);
initbarea(&asblk);
sblk.b_un.b_buf = malloc(SBSIZE);
asblk.b_un.b_buf = malloc(SBSIZE);
if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
errx(EEXIT, "cannot allocate space for superblock");
if ((lp = getdisklabel(NULL, fsreadfd)))
dev_bsize = secsize = lp->d_secsize;
else
dev_bsize = secsize = DEV_BSIZE;
}
/*
* Calculate a prototype superblock based on information in the disk label.
* When done the cgsblock macro can be calculated and the fs_ncg field