aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/fsck_ffs/fsck.h5
-rw-r--r--sbin/fsck_ffs/pass5.c55
2 files changed, 60 insertions, 0 deletions
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index 487dcd42a669..55a57bc6959f 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -252,6 +252,11 @@ long countdirs; /* number of directories we actually found */
#define MIBSIZE 3 /* size of fsck sysctl MIBs */
int adjrefcnt[MIBSIZE]; /* MIB command to adjust inode reference cnt */
int adjblkcnt[MIBSIZE]; /* MIB command to adjust inode block count */
+int adjndir[MIBSIZE]; /* MIB command to adjust number of directories */
+int adjnbfree[MIBSIZE]; /* MIB command to adjust number of free blocks */
+int adjnifree[MIBSIZE]; /* MIB command to adjust number of free inodes */
+int adjnffree[MIBSIZE]; /* MIB command to adjust number of free frags */
+int adjnumclusters[MIBSIZE]; /* MIB command to adjust number of free clusters */
int freefiles[MIBSIZE]; /* MIB command to free a set of files */
int freedirs[MIBSIZE]; /* MIB command to free a set of directories */
int freeblks[MIBSIZE]; /* MIB command to free a set of data blocks */
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index c3c564e7700c..796b546b9516 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <ufs/ffs/fs.h>
#include <err.h>
+#include <inttypes.h>
#include <limits.h>
#include <string.h>
@@ -344,6 +345,60 @@ pass5(void)
fs->fs_fmod = 0;
sbdirty();
}
+
+ /*
+ * When doing background fsck on a snapshot, figure out whether
+ * the superblock summary is inaccurate and correct it when
+ * necessary.
+ */
+ if (cursnapshot != 0) {
+ cmd.size = 1;
+
+ cmd.value = cstotal.cs_ndir - fs->fs_cstotal.cs_ndir;
+ if (cmd.value != 0) {
+ if (debug)
+ printf("adjndir by %+" PRIi64 "\n", cmd.value);
+ if (sysctl(adjndir, MIBSIZE, 0, 0,
+ &cmd, sizeof cmd) == -1)
+ rwerror("ADJUST NUMBER OF DIRECTORIES", cmd.value);
+ }
+
+ cmd.value = cstotal.cs_nbfree - fs->fs_cstotal.cs_nbfree;
+ if (cmd.value != 0) {
+ if (debug)
+ printf("adjnbfree by %+" PRIi64 "\n", cmd.value);
+ if (sysctl(adjnbfree, MIBSIZE, 0, 0,
+ &cmd, sizeof cmd) == -1)
+ rwerror("ADJUST NUMBER OF FREE BLOCKS", cmd.value);
+ }
+
+ cmd.value = cstotal.cs_nifree - fs->fs_cstotal.cs_nifree;
+ if (cmd.value != 0) {
+ if (debug)
+ printf("adjnifree by %+" PRIi64 "\n", cmd.value);
+ if (sysctl(adjnifree, MIBSIZE, 0, 0,
+ &cmd, sizeof cmd) == -1)
+ rwerror("ADJUST NUMBER OF FREE INODES", cmd.value);
+ }
+
+ cmd.value = cstotal.cs_nffree - fs->fs_cstotal.cs_nffree;
+ if (cmd.value != 0) {
+ if (debug)
+ printf("adjnffree by %+" PRIi64 "\n", cmd.value);
+ if (sysctl(adjnffree, MIBSIZE, 0, 0,
+ &cmd, sizeof cmd) == -1)
+ rwerror("ADJUST NUMBER OF FREE FRAGS", cmd.value);
+ }
+
+ cmd.value = cstotal.cs_numclusters - fs->fs_cstotal.cs_numclusters;
+ if (cmd.value != 0) {
+ if (debug)
+ printf("adjnumclusters by %+" PRIi64 "\n", cmd.value);
+ if (sysctl(adjnumclusters, MIBSIZE, 0, 0,
+ &cmd, sizeof cmd) == -1)
+ rwerror("ADJUST NUMBER OF FREE CLUSTERS", cmd.value);
+ }
+ }
}
static void