diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h index 55a57bc6959f..32f9cfaa7eae 100644 --- a/sbin/fsck_ffs/fsck.h +++ b/sbin/fsck_ffs/fsck.h @@ -272,6 +272,7 @@ int bflag; /* location of alternate super block */ int debug; /* output debugging info */ int cvtlevel; /* convert to newer file system format */ int bkgrdcheck; /* determine if background check is possible */ +int bkgrdsumadj; /* whether the kernel have ability to adjust superblock summary */ char usedsoftdep; /* just fix soft dependency inconsistencies */ char preen; /* just fix normal inconsistencies */ char rerun; /* rerun fsck. Only used in non-preen mode */ diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c index 796b546b9516..693831fe1578 100644 --- a/sbin/fsck_ffs/pass5.c +++ b/sbin/fsck_ffs/pass5.c @@ -358,7 +358,7 @@ pass5(void) if (cmd.value != 0) { if (debug) printf("adjndir by %+" PRIi64 "\n", cmd.value); - if (sysctl(adjndir, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || sysctl(adjndir, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF DIRECTORIES", cmd.value); } @@ -367,7 +367,7 @@ pass5(void) if (cmd.value != 0) { if (debug) printf("adjnbfree by %+" PRIi64 "\n", cmd.value); - if (sysctl(adjnbfree, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || sysctl(adjnbfree, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE BLOCKS", cmd.value); } @@ -376,7 +376,7 @@ pass5(void) if (cmd.value != 0) { if (debug) printf("adjnifree by %+" PRIi64 "\n", cmd.value); - if (sysctl(adjnifree, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || sysctl(adjnifree, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE INODES", cmd.value); } @@ -385,7 +385,7 @@ pass5(void) if (cmd.value != 0) { if (debug) printf("adjnffree by %+" PRIi64 "\n", cmd.value); - if (sysctl(adjnffree, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || sysctl(adjnffree, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE FRAGS", cmd.value); } @@ -394,7 +394,7 @@ pass5(void) if (cmd.value != 0) { if (debug) printf("adjnumclusters by %+" PRIi64 "\n", cmd.value); - if (sysctl(adjnumclusters, MIBSIZE, 0, 0, + if (bkgrdsumadj == 0 || sysctl(adjnumclusters, MIBSIZE, 0, 0, &cmd, sizeof cmd) == -1) rwerror("ADJUST NUMBER OF FREE CLUSTERS", cmd.value); } diff --git a/sbin/fsck_ffs/setup.c b/sbin/fsck_ffs/setup.c index e95a6adbb4ad..f6b736d2ec79 100644 --- a/sbin/fsck_ffs/setup.c +++ b/sbin/fsck_ffs/setup.c @@ -140,6 +140,24 @@ setup(char *dev) pfatal("kernel lacks background fsck support\n"); exit(EEXIT); } + /* + * When kernel is lack of runtime bgfsck superblock summary + * adjustment functionality, it does not mean we can not + * continue, as old kernels will recompute the summary at + * mount time. However, it will be an unexpected softupdates + * inconsistency if it turns out that the summary is still + * incorrect. Set a flag so subsequent operation can know + * this. + */ + bkgrdsumadj = 1; + if (sysctlnametomib("vfs.ffs.adjndir", adjndir, &size) < 0 || + sysctlnametomib("vfs.ffs.adjnbfree", adjnbfree, &size) < 0 || + sysctlnametomib("vfs.ffs.adjnifree", adjnifree, &size) < 0 || + sysctlnametomib("vfs.ffs.adjnffree", adjnffree, &size) < 0 || + sysctlnametomib("vfs.ffs.adjnumclusters", adjnumclusters, &size) < 0) { + bkgrdsumadj = 0; + pwarn("kernel lacks runtime superblock summary adjustment support"); + } cmd.version = FFS_CMD_VERSION; cmd.handle = fsreadfd; fswritefd = -1;