summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2001-04-16 22:22:21 +0000
committermckusick <mckusick@FreeBSD.org>2001-04-16 22:22:21 +0000
commit8553bca948638af0851ed308cfc71c940bbc179e (patch)
tree22d991906cdeef6ffaca97cddaf80f72161dae29
parent3b359dad32baa6f19fa388a452fd376f08bb28a6 (diff)
downloadFreeBSD-src-8553bca948638af0851ed308cfc71c940bbc179e.zip
FreeBSD-src-8553bca948638af0851ed308cfc71c940bbc179e.tar.gz
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.
-rw-r--r--sbin/fsck_ffs/fsck.h2
-rw-r--r--sbin/fsck_ffs/fsutil.c28
-rw-r--r--sbin/fsck_ffs/main.c34
-rw-r--r--sbin/fsck_ffs/pass5.c13
-rw-r--r--sbin/fsck_ffs/setup.c40
5 files changed, 87 insertions, 30 deletions
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index e598b35..dee89c7 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -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));
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index fa06dfb..c743aca 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -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);
}
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index a9e7e90..83bb312 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -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",
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index 5d334f9..58d706c 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -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;
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index d8d77a5..517547d 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -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 @@ badsb:
/*
* 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
OpenPOWER on IntegriCloud