diff options
author | mckusick <mckusick@FreeBSD.org> | 2011-07-15 15:43:40 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2011-07-15 15:43:40 +0000 |
commit | f57829beea18717741f7192062e2b29432479afe (patch) | |
tree | 5326bbb7b4d31239aa6edc469390fec0c4109702 /sbin/fsck_ffs/pass5.c | |
parent | 3b092444e94a084b65ab95d481df255b58d72825 (diff) | |
download | FreeBSD-src-f57829beea18717741f7192062e2b29432479afe.zip FreeBSD-src-f57829beea18717741f7192062e2b29432479afe.tar.gz |
Break out the pass 5 inode and block map updating into a separate function
so that the function can be used by the journaling soft updates recovery.
Diffstat (limited to 'sbin/fsck_ffs/pass5.c')
-rw-r--r-- | sbin/fsck_ffs/pass5.c | 72 |
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, |