summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs/pass5.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/fsck_ffs/pass5.c')
-rw-r--r--sbin/fsck_ffs/pass5.c72
1 files changed, 44 insertions, 28 deletions
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index 01ed8a5..b95df73 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -49,8 +49,8 @@ __FBSDID("$FreeBSD$");
#include "fsck.h"
-static void check_maps(u_char *, u_char *, int, ufs2_daddr_t, const char *, int *, int, int);
-
+static void check_maps(u_char *, u_char *, int, ufs2_daddr_t, const char *,
+ int *, int, int, int);
static void clear_blocks(ufs2_daddr_t start, ufs2_daddr_t end);
void
@@ -61,7 +61,7 @@ pass5(void)
struct fs *fs = &sblock;
struct cg *cg = &cgrp;
ufs2_daddr_t d, dbase, dmax, start;
- int excessdirs, rewritecg = 0;
+ int rewritecg = 0;
struct csum *cs;
struct csum_total cstotal;
struct inodesc idesc[3];
@@ -333,27 +333,8 @@ pass5(void)
memmove(cg, newcg, (size_t)basesize);
cgdirty();
}
- if (bkgrdflag != 0 || usedsoftdep || debug) {
- excessdirs = cg->cg_cs.cs_ndir - newcg->cg_cs.cs_ndir;
- if (excessdirs < 0) {
- pfatal("LOST %d DIRECTORIES\n", -excessdirs);
- excessdirs = 0;
- }
- if (excessdirs > 0)
- check_maps(cg_inosused(newcg), cg_inosused(cg),
- inomapsize,
- cg->cg_cgx * (ufs2_daddr_t) fs->fs_ipg,
- "DIR",
- freedirs, 0, excessdirs);
- check_maps(cg_inosused(newcg), cg_inosused(cg),
- inomapsize,
- cg->cg_cgx * (ufs2_daddr_t) fs->fs_ipg, "FILE",
- freefiles, excessdirs, fs->fs_ipg);
- check_maps(cg_blksfree(cg), cg_blksfree(newcg),
- blkmapsize,
- cg->cg_cgx * (ufs2_daddr_t) fs->fs_fpg, "FRAG",
- freeblks, 0, fs->fs_fpg);
- }
+ if (bkgrdflag != 0 || usedsoftdep || debug)
+ update_maps(cg, newcg, bkgrdflag);
if (cursnapshot == 0 &&
memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0 &&
dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
@@ -426,6 +407,40 @@ pass5(void)
}
}
+/*
+ * Compare the original cylinder group inode and block bitmaps with the
+ * updated cylinder group inode and block bitmaps. Free inodes and blocks
+ * that have been added. Complain if any previously freed inodes blocks
+ * are now allocated.
+ */
+void
+update_maps(
+ struct cg *oldcg, /* cylinder group of claimed allocations */
+ struct cg *newcg, /* cylinder group of determined allocations */
+ int usesysctl) /* 1 => use sysctl interface to update maps */
+{
+ int inomapsize, excessdirs;
+ struct fs *fs = &sblock;
+
+ inomapsize = howmany(fs->fs_ipg, CHAR_BIT);
+ excessdirs = oldcg->cg_cs.cs_ndir - newcg->cg_cs.cs_ndir;
+ if (excessdirs < 0) {
+ pfatal("LOST %d DIRECTORIES\n", -excessdirs);
+ excessdirs = 0;
+ }
+ if (excessdirs > 0)
+ check_maps(cg_inosused(newcg), cg_inosused(oldcg), inomapsize,
+ oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_ipg, "DIR", freedirs,
+ 0, excessdirs, usesysctl);
+ check_maps(cg_inosused(newcg), cg_inosused(oldcg), inomapsize,
+ oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_ipg, "FILE", freefiles,
+ excessdirs, fs->fs_ipg, usesysctl);
+ check_maps(cg_blksfree(oldcg), cg_blksfree(newcg),
+ howmany(fs->fs_fpg, CHAR_BIT),
+ oldcg->cg_cgx * (ufs2_daddr_t)fs->fs_fpg, "FRAG",
+ freeblks, 0, fs->fs_fpg, usesysctl);
+}
+
static void
check_maps(
u_char *map1, /* map of claimed allocations */
@@ -435,7 +450,8 @@ check_maps(
const char *name, /* name of resource found in maps */
int *opcode, /* sysctl opcode to free resource */
int skip, /* number of entries to skip before starting to free */
- int limit) /* limit on number of entries to free */
+ int limit, /* limit on number of entries to free */
+ int usesysctl) /* 1 => use sysctl interface to update maps */
{
# define BUFSIZE 16
char buf[BUFSIZE];
@@ -443,7 +459,7 @@ check_maps(
ufs2_daddr_t n, astart, aend, ustart, uend;
void (*msg)(const char *fmt, ...);
- if (bkgrdflag)
+ if (usesysctl)
msg = pfatal;
else
msg = pwarn;
@@ -506,7 +522,7 @@ check_maps(
" MARKED USED\n",
"UNALLOCATED", name, ustart,
ustart + size - 1);
- if (bkgrdflag != 0) {
+ if (usesysctl != 0) {
cmd.value = ustart;
cmd.size = size;
if (sysctl(opcode, MIBSIZE, 0, 0,
@@ -552,7 +568,7 @@ check_maps(
" MARKED USED\n",
name, ustart, ustart + size - 1);
}
- if (bkgrdflag != 0) {
+ if (usesysctl != 0) {
cmd.value = ustart;
cmd.size = size;
if (sysctl(opcode, MIBSIZE, 0, 0, &cmd,
OpenPOWER on IntegriCloud