aboutsummaryrefslogtreecommitdiff
path: root/sbin/fsck_ffs/setup.c
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2001-03-21 09:48:03 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2001-03-21 09:48:03 +0000
commit7578c6ab98589fcbfc585e67ba7973fa40efb8b4 (patch)
tree9ae22c7c2279fbc251d488106c58f641f5904fcf /sbin/fsck_ffs/setup.c
parent3fa18367c216de605a4905dc7637074739c3457c (diff)
downloadsrc-7578c6ab98589fcbfc585e67ba7973fa40efb8b4.tar.gz
src-7578c6ab98589fcbfc585e67ba7973fa40efb8b4.zip
Additions to run checks on live filesystems. This change will not
affect current systems until fsck is modified to use these new facilities. To try out this change, set the fsck passno to zero in /etc/fstab to cause the filesystem to be mounted without running fsck, then run `fsck_ffs -p -B <filesystem>' after the system has been brought up multiuser to run a background cleanup on <filesystem>. Note that the <filesystem> in question must have soft updates enabled.
Notes
Notes: svn path=/head/; revision=74556
Diffstat (limited to 'sbin/fsck_ffs/setup.c')
-rw-r--r--sbin/fsck_ffs/setup.c62
1 files changed, 55 insertions, 7 deletions
diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c
index 24000beca25c..bd928fb86988 100644
--- a/sbin/fsck_ffs/setup.c
+++ b/sbin/fsck_ffs/setup.c
@@ -86,25 +86,73 @@ setup(dev)
skipclean = fflag ? 0 : preen;
if (stat(dev, &statb) < 0) {
printf("Can't stat %s: %s\n", dev, strerror(errno));
+ if (bkgrdflag) {
+ unlink(snapname);
+ bkgrdflag = 0;
+ }
return (0);
}
if ((statb.st_mode & S_IFMT) != S_IFCHR &&
(statb.st_mode & S_IFMT) != S_IFBLK) {
- if ((statb.st_flags & SF_SNAPSHOT) != 0) {
+ if (bkgrdflag != 0 && (statb.st_flags & SF_SNAPSHOT) == 0) {
+ unlink(snapname);
+ printf("background fsck lacks a snapshot\n");
+ exit(EEXIT);
+ }
+ if ((statb.st_flags & SF_SNAPSHOT) != 0 && cvtlevel == 0) {
cursnapshot = statb.st_ino;
} else {
- pfatal("%s is not a disk device", dev);
- if (reply("CONTINUE") == 0)
- return (0);
+ if (cvtlevel == 0 ||
+ (statb.st_flags & SF_SNAPSHOT) == 0) {
+ if (preen && bkgrdflag) {
+ unlink(snapname);
+ bkgrdflag = 0;
+ }
+ pfatal("%s is not a disk device", dev);
+ if (reply("CONTINUE") == 0) {
+ if (bkgrdflag) {
+ unlink(snapname);
+ bkgrdflag = 0;
+ }
+ return (0);
+ }
+ } else {
+ if (bkgrdflag) {
+ unlink(snapname);
+ bkgrdflag = 0;
+ }
+ pfatal("cannot convert a snapshot");
+ exit(EEXIT);
+ }
}
}
if ((fsreadfd = open(dev, O_RDONLY)) < 0) {
+ if (bkgrdflag) {
+ unlink(snapname);
+ bkgrdflag = 0;
+ }
printf("Can't open %s: %s\n", dev, strerror(errno));
return (0);
}
+ if (bkgrdflag) {
+ unlink(snapname);
+ size = MIBSIZE;
+ if (sysctlnametomib("vfs.ffs.adjrefcnt", adjrefcnt, &size) < 0||
+ sysctlnametomib("vfs.ffs.adjblkcnt", adjblkcnt, &size) < 0||
+ sysctlnametomib("vfs.ffs.freefiles", freefiles, &size) < 0||
+ sysctlnametomib("vfs.ffs.freedirs", freedirs, &size) < 0 ||
+ sysctlnametomib("vfs.ffs.freeblks", freeblks, &size) < 0) {
+ pfatal("kernel lacks background fsck support\n");
+ exit(EEXIT);
+ }
+ cmd.version = FFS_CMD_VERSION;
+ cmd.handle = fsreadfd;
+ fswritefd = -1;
+ }
if (preen == 0)
printf("** %s", dev);
- if (nflag || (fswritefd = open(dev, O_WRONLY)) < 0) {
+ if (bkgrdflag == 0 &&
+ (nflag || (fswritefd = open(dev, O_WRONLY)) < 0)) {
fswritefd = -1;
if (preen)
pfatal("NO WRITE ACCESS");
@@ -178,7 +226,7 @@ setup(dev)
}
if (sblock.fs_interleave < 1 ||
sblock.fs_interleave > sblock.fs_nsect) {
- pwarn("IMPOSSIBLE INTERLEAVE=%d IN SUPERBLOCK",
+ pfatal("IMPOSSIBLE INTERLEAVE=%d IN SUPERBLOCK",
sblock.fs_interleave);
sblock.fs_interleave = 1;
if (preen)
@@ -190,7 +238,7 @@ setup(dev)
}
if (sblock.fs_npsect < sblock.fs_nsect ||
sblock.fs_npsect > sblock.fs_nsect*2) {
- pwarn("IMPOSSIBLE NPSECT=%d IN SUPERBLOCK",
+ pfatal("IMPOSSIBLE NPSECT=%d IN SUPERBLOCK",
sblock.fs_npsect);
sblock.fs_npsect = sblock.fs_nsect;
if (preen)