diff options
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/fsck_ffs/fsck.h | 5 | ||||
-rw-r--r-- | sbin/fsck_ffs/pass5.c | 55 |
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 |