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
This commit is contained in:
parent
ff3d1a3f9d
commit
344b5bf825
@ -274,9 +274,16 @@ checkfilesys(char *filesys)
|
|||||||
if (bkgrdcheck) {
|
if (bkgrdcheck) {
|
||||||
if (sbreadfailed)
|
if (sbreadfailed)
|
||||||
exit(3); /* Cannot read superblock */
|
exit(3); /* Cannot read superblock */
|
||||||
/* Earlier background failed or journaled */
|
if ((sblock.fs_flags & FS_NEEDSFSCK) == FS_NEEDSFSCK)
|
||||||
if (sblock.fs_flags & (FS_NEEDSFSCK | FS_SUJ))
|
exit(4); /* Earlier background failed */
|
||||||
exit(4);
|
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)
|
if ((sblock.fs_flags & FS_DOSOFTDEP) == 0)
|
||||||
exit(5); /* Not running soft updates */
|
exit(5); /* Not running soft updates */
|
||||||
size = MIBSIZE;
|
size = MIBSIZE;
|
||||||
@ -350,7 +357,7 @@ checkfilesys(char *filesys)
|
|||||||
/*
|
/*
|
||||||
* Determine if we can and should do journal recovery.
|
* 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 &&
|
if ((sblock.fs_flags & FS_NEEDSFSCK) != FS_NEEDSFSCK &&
|
||||||
skipclean) {
|
skipclean) {
|
||||||
sujrecovery = 1;
|
sujrecovery = 1;
|
||||||
@ -619,10 +626,6 @@ setup_bkgrdchk(struct statfs *mntp, int sbreadfailed, char **filesys)
|
|||||||
pwarn("FULL FSCK NEEDED, CANNOT RUN IN BACKGROUND\n");
|
pwarn("FULL FSCK NEEDED, CANNOT RUN IN BACKGROUND\n");
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if ((sblock.fs_flags & FS_SUJ) != 0) {
|
|
||||||
pwarn("JOURNALED FILESYSTEM, CANNOT RUN IN BACKGROUND\n");
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (skipclean && ckclean &&
|
if (skipclean && ckclean &&
|
||||||
(sblock.fs_flags & (FS_UNCLEAN|FS_NEEDSFSCK)) == 0) {
|
(sblock.fs_flags & (FS_UNCLEAN|FS_NEEDSFSCK)) == 0) {
|
||||||
/*
|
/*
|
||||||
|
@ -2135,7 +2135,9 @@ suj_verifyino(union dinode *dp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DIP(dp, di_modrev) != fs->fs_mtime) {
|
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);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2436,7 +2438,9 @@ suj_check(const char *filesys)
|
|||||||
sujino = idesc.id_parent;
|
sujino = idesc.id_parent;
|
||||||
irelse(&ip);
|
irelse(&ip);
|
||||||
} else {
|
} 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_flags &= ~FS_SUJ;
|
||||||
sblock.fs_sujfree = 0;
|
sblock.fs_sujfree = 0;
|
||||||
irelse(&ip);
|
irelse(&ip);
|
||||||
@ -2447,7 +2451,8 @@ suj_check(const char *filesys)
|
|||||||
*/
|
*/
|
||||||
ginode(sujino, &ip);
|
ginode(sujino, &ip);
|
||||||
jip = ip.i_dp;
|
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"))) {
|
if (suj_verifyino(jip) != 0 || (!preen && !reply("USE JOURNAL"))) {
|
||||||
irelse(&ip);
|
irelse(&ip);
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -2456,15 +2461,23 @@ suj_check(const char *filesys)
|
|||||||
* Build a list of journal blocks in jblocks before parsing the
|
* Build a list of journal blocks in jblocks before parsing the
|
||||||
* available journal blocks in with suj_read().
|
* available journal blocks in with suj_read().
|
||||||
*/
|
*/
|
||||||
printf("** Reading %jd byte journal from inode %ju.\n",
|
if (!bkgrdcheck || debug)
|
||||||
DIP(jip, di_size), (uintmax_t)sujino);
|
printf("** Reading %jd byte journal from inode %ju.\n",
|
||||||
|
DIP(jip, di_size), (uintmax_t)sujino);
|
||||||
suj_jblocks = jblocks_create();
|
suj_jblocks = jblocks_create();
|
||||||
blocks = ino_visit(jip, sujino, suj_add_block, 0);
|
blocks = ino_visit(jip, sujino, suj_add_block, 0);
|
||||||
if (blocks != numfrags(fs, DIP(jip, di_size))) {
|
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);
|
irelse(&ip);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
/* If journal is valid then do journal check rather than background */
|
||||||
|
if (bkgrdcheck) {
|
||||||
|
irelse(&ip);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
irelse(&ip);
|
irelse(&ip);
|
||||||
suj_read();
|
suj_read();
|
||||||
jblocks_destroy(suj_jblocks);
|
jblocks_destroy(suj_jblocks);
|
||||||
|
Loading…
Reference in New Issue
Block a user