aboutsummaryrefslogtreecommitdiff
path: root/sbin/fsck_ffs
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2023-08-01 20:16:11 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2023-08-01 20:17:02 +0000
commit344b5bf82528575ada304f0df356d2f045772328 (patch)
tree88cf48d1e1c1558d83100d813a230fa912208d73 /sbin/fsck_ffs
parentff3d1a3f9d71e706f320f51bae258e4e1a51b388 (diff)
downloadsrc-344b5bf82528575ada304f0df356d2f045772328.tar.gz
src-344b5bf82528575ada304f0df356d2f045772328.zip
Support background fsck_ffs(8) on filesystems using journaled soft updates
An earlier addition of code to fsck_ffs(8) allowed it to support snapshots when running with journalled soft updates. Further functionality has now been added to fsck_ffs(8) to allow it to use snapshots to run in background on live filesystems running with journaled soft updates. This commit enables the use of this functionality. Tested-by: Peter Holm Sponsored-by: The FreeBSD Foundation MFC-after: 2 weeks
Diffstat (limited to 'sbin/fsck_ffs')
-rw-r--r--sbin/fsck_ffs/main.c19
-rw-r--r--sbin/fsck_ffs/suj.c25
2 files changed, 30 insertions, 14 deletions
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index 0acf7e709180..bfe2901c4053 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -274,9 +274,16 @@ checkfilesys(char *filesys)
if (bkgrdcheck) {
if (sbreadfailed)
exit(3); /* Cannot read superblock */
- /* Earlier background failed or journaled */
- if (sblock.fs_flags & (FS_NEEDSFSCK | FS_SUJ))
- exit(4);
+ if ((sblock.fs_flags & FS_NEEDSFSCK) == FS_NEEDSFSCK)
+ exit(4); /* Earlier background failed */
+ if ((sblock.fs_flags & FS_SUJ) == FS_SUJ) {
+ maxino = sblock.fs_ncg * sblock.fs_ipg;
+ maxfsblock = sblock.fs_size;
+ bufinit();
+ preen = 1;
+ if (suj_check(filesys) == 0)
+ exit(4); /* Journal good, run it now */
+ }
if ((sblock.fs_flags & FS_DOSOFTDEP) == 0)
exit(5); /* Not running soft updates */
size = MIBSIZE;
@@ -350,7 +357,7 @@ checkfilesys(char *filesys)
/*
* Determine if we can and should do journal recovery.
*/
- if ((sblock.fs_flags & FS_SUJ) == FS_SUJ) {
+ if (bkgrdflag == 0 && (sblock.fs_flags & FS_SUJ) == FS_SUJ) {
if ((sblock.fs_flags & FS_NEEDSFSCK) != FS_NEEDSFSCK &&
skipclean) {
sujrecovery = 1;
@@ -619,10 +626,6 @@ setup_bkgrdchk(struct statfs *mntp, int sbreadfailed, char **filesys)
pwarn("FULL FSCK NEEDED, CANNOT RUN IN BACKGROUND\n");
return (0);
}
- if ((sblock.fs_flags & FS_SUJ) != 0) {
- pwarn("JOURNALED FILESYSTEM, CANNOT RUN IN BACKGROUND\n");
- return (0);
- }
if (skipclean && ckclean &&
(sblock.fs_flags & (FS_UNCLEAN|FS_NEEDSFSCK)) == 0) {
/*
diff --git a/sbin/fsck_ffs/suj.c b/sbin/fsck_ffs/suj.c
index e55e3fb1c782..b78123b59678 100644
--- a/sbin/fsck_ffs/suj.c
+++ b/sbin/fsck_ffs/suj.c
@@ -2135,7 +2135,9 @@ suj_verifyino(union dinode *dp)
}
if (DIP(dp, di_modrev) != fs->fs_mtime) {
- printf("Journal timestamp does not match fs mount time\n");
+ if (!bkgrdcheck || debug)
+ printf("Journal timestamp does not match "
+ "fs mount time\n");
return (-1);
}
@@ -2436,7 +2438,9 @@ suj_check(const char *filesys)
sujino = idesc.id_parent;
irelse(&ip);
} else {
- printf("Journal inode removed. Use tunefs to re-create.\n");
+ if (!bkgrdcheck || debug)
+ printf("Journal inode removed. "
+ "Use tunefs to re-create.\n");
sblock.fs_flags &= ~FS_SUJ;
sblock.fs_sujfree = 0;
irelse(&ip);
@@ -2447,7 +2451,8 @@ suj_check(const char *filesys)
*/
ginode(sujino, &ip);
jip = ip.i_dp;
- printf("** SU+J Recovering %s\n", filesys);
+ if (!bkgrdcheck || debug)
+ printf("** SU+J Recovering %s\n", filesys);
if (suj_verifyino(jip) != 0 || (!preen && !reply("USE JOURNAL"))) {
irelse(&ip);
return (-1);
@@ -2456,15 +2461,23 @@ suj_check(const char *filesys)
* Build a list of journal blocks in jblocks before parsing the
* available journal blocks in with suj_read().
*/
- printf("** Reading %jd byte journal from inode %ju.\n",
- DIP(jip, di_size), (uintmax_t)sujino);
+ if (!bkgrdcheck || debug)
+ printf("** Reading %jd byte journal from inode %ju.\n",
+ DIP(jip, di_size), (uintmax_t)sujino);
suj_jblocks = jblocks_create();
blocks = ino_visit(jip, sujino, suj_add_block, 0);
if (blocks != numfrags(fs, DIP(jip, di_size))) {
- printf("Sparse journal inode %ju.\n", (uintmax_t)sujino);
+ if (!bkgrdcheck || debug)
+ printf("Sparse journal inode %ju.\n",
+ (uintmax_t)sujino);
irelse(&ip);
return (-1);
}
+ /* If journal is valid then do journal check rather than background */
+ if (bkgrdcheck) {
+ irelse(&ip);
+ return (0);
+ }
irelse(&ip);
suj_read();
jblocks_destroy(suj_jblocks);