diff options
author | mckusick <mckusick@FreeBSD.org> | 2001-04-24 22:38:08 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2001-04-24 22:38:08 +0000 |
commit | ecbf3eacd9a17a3a9b238e2fa65b2d33d85e8d1f (patch) | |
tree | 261472238f24e110d11cd5bf7fc8de94dc83e882 /sbin/fsck_ffs/main.c | |
parent | b92d41b0e964c6163071505bd9fdc9f02b6410fe (diff) | |
download | FreeBSD-src-ecbf3eacd9a17a3a9b238e2fa65b2d33d85e8d1f.zip FreeBSD-src-ecbf3eacd9a17a3a9b238e2fa65b2d33d85e8d1f.tar.gz |
Add support for the -F flag which determines whether a specified
filesystem needs foreground checking (usually at boot time) or
can defer to background checking (after the system is up and running).
See the manual page, fsck_ffs(8), for details on the -F and -B options.
These options are primarily intended for use by the fsck front end.
All output is directed to stdout so that the output is coherent
when redirected to a file or a pipe. Unify the code with the fsck
front end that allows either a device or a mount point to be
specified as the argument to be checked.
Diffstat (limited to 'sbin/fsck_ffs/main.c')
-rw-r--r-- | sbin/fsck_ffs/main.c | 76 |
1 files changed, 58 insertions, 18 deletions
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c index 83bb312..930a4c4 100644 --- a/sbin/fsck_ffs/main.c +++ b/sbin/fsck_ffs/main.c @@ -63,8 +63,6 @@ static const char rcsid[] = #include "fsck.h" -int returntosingle; - static void usage __P((void)); static int argtoi __P((int flag, char *req, char *str, int base)); static int docheck __P((struct fstab *fsp)); @@ -84,7 +82,7 @@ main(argc, argv) sync(); skipclean = 1; - while ((ch = getopt(argc, argv, "b:Bc:dfm:npy")) != -1) { + while ((ch = getopt(argc, argv, "b:Bc:dfFm:npy")) != -1) { switch (ch) { case 'b': skipclean = 0; @@ -109,6 +107,10 @@ main(argc, argv) skipclean = 0; break; + case 'F': + bkgrdcheck = 1; + break; + case 'm': lfmode = argtoi('m', "mode", optarg, 8); if (lfmode &~ 07777) @@ -154,7 +156,7 @@ main(argc, argv) (void)setrlimit(RLIMIT_DATA, &rlimit); } while (argc-- > 0) - (void)checkfilesys(blockcheck(*argv++), 0, 0L, 0); + (void)checkfilesys(*argv++, 0, 0L, 0); if (returntosingle) ret = 2; @@ -193,15 +195,46 @@ checkfilesys(filesys, mntpt, auxdata, child) struct zlncnt *zlnp; ufs_daddr_t blks; ufs_daddr_t files; - int cylno; + int cylno, size; if (preen && child) (void)signal(SIGQUIT, voidquit); cdevname = filesys; if (debug && preen) pwarn("starting\n"); + /* + * Make best effort to get the disk name. Check first to see + * if it is listed among the mounted filesystems. Failing that + * check to see if it is listed in /etc/fstab. + */ + mntp = getmntpt(filesys); + if (mntp != NULL) + filesys = mntp->f_mntfromname; + else + filesys = blockcheck(filesys); + /* + * If -F flag specified, check to see whether a background check + * is possible and needed. If possible and needed, exit with + * status zero. Otherwise exit with status non-zero. A non-zero + * exit status will cause a foreground check to be run. + */ sblock_init(); - + if (bkgrdcheck) { + if ((fsreadfd = open(filesys, O_RDONLY)) < 0 || readsb(0) == 0) + exit(3); /* Cannot read superblock */ + close(fsreadfd); + if (sblock.fs_flags & FS_NEEDSFSCK) + exit(4); /* Earlier background failed */ + if ((sblock.fs_flags & FS_DOSOFTDEP) == 0) + exit(5); /* Not running soft updates */ + size = MIBSIZE; + if (sysctlnametomib("vfs.ffs.adjrefcnt", adjrefcnt, &size) < 0) + exit(6); /* Lacks kernel support */ + if ((mntp == NULL && sblock.fs_clean == 1) || + (mntp != NULL && (sblock.fs_flags & FS_UNCLEAN) == 0)) + exit(7); /* Filesystem clean, report it now */ + exit(0); + } /* * If we are to do a background check: * Get the mount point information of the filesystem @@ -209,7 +242,6 @@ checkfilesys(filesys, mntpt, auxdata, child) * return created snapshot file * if not found, clear bkgrdflag and proceed with normal fsck */ - mntp = getmntpt(filesys); if (bkgrdflag) { if (mntp == NULL) { bkgrdflag = 0; @@ -432,7 +464,7 @@ checkfilesys(filesys, mntpt, auxdata, child) } /* - * Get the directory that the device is mounted on. + * Get the mount point information for name. */ static struct statfs * getmntpt(name) @@ -441,27 +473,35 @@ getmntpt(name) struct stat devstat, mntdevstat; char device[sizeof(_PATH_DEV) - 1 + MNAMELEN]; char *devname; - struct statfs *mntbuf; - int i, mntsize; + struct statfs *mntbuf, *statfsp; + int i, mntsize, isdev; - if (stat(name, &devstat) != 0 || - !(S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode))) + if (stat(name, &devstat) != 0) return (NULL); + if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode)) + isdev = 1; + else + isdev = 0; mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); for (i = 0; i < mntsize; i++) { - if (strcmp(mntbuf[i].f_fstypename, "ufs") != 0) - continue; - devname = mntbuf[i].f_mntfromname; + statfsp = &mntbuf[i]; + devname = statfsp->f_mntfromname; if (*devname != '/') { strcpy(device, _PATH_DEV); strcat(device, devname); - devname = device; + strcpy(statfsp->f_mntfromname, device); + } + if (isdev == 0) { + if (strcmp(name, statfsp->f_mntonname)) + continue; + return (statfsp); } if (stat(devname, &mntdevstat) == 0 && mntdevstat.st_rdev == devstat.st_rdev) - return (&mntbuf[i]); + return (statfsp); } - return (NULL); + statfsp = NULL; + return (statfsp); } static void |