summaryrefslogtreecommitdiffstats
path: root/sbin/growfs
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2010-09-19 08:18:56 +0000
committerbrian <brian@FreeBSD.org>2010-09-19 08:18:56 +0000
commitd94a5ef824af03d7acb020d7d361ae67edd353f4 (patch)
tree5c3202925642c3310478e0432de72d8a9a45970b /sbin/growfs
parent4c94bb3829b85eea7184e6ca9e7c05f446f9a433 (diff)
downloadFreeBSD-src-d94a5ef824af03d7acb020d7d361ae67edd353f4.zip
FreeBSD-src-d94a5ef824af03d7acb020d7d361ae67edd353f4.tar.gz
Revise r197763 which fixes filesystem corruption when extending
into un-zeroed storage. The original patch was questioned by Kirk as it forces the filesystem to do excessive work initialising inodes on first use, and was never MFC'd. This change mimics the newfs(8) approach of zeroing two blocks of inodes for each new cylinder group. Reviewed by: mckusick MFC after: 3 weeks
Diffstat (limited to 'sbin/growfs')
-rw-r--r--sbin/growfs/growfs.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c
index 5e950fc..bce4d59a 100644
--- a/sbin/growfs/growfs.c
+++ b/sbin/growfs/growfs.c
@@ -371,16 +371,16 @@ static void
initcg(int cylno, time_t utime, int fso, unsigned int Nflag)
{
DBG_FUNC("initcg")
- static void *iobuf;
+ static caddr_t iobuf;
long blkno, start;
ufs2_daddr_t i, cbase, dmax;
struct ufs1_dinode *dp1;
struct csum *cs;
uint d, dupper, dlower;
- if (iobuf == NULL && (iobuf = malloc(sblock.fs_bsize)) == NULL) {
+ if (iobuf == NULL && (iobuf = malloc(sblock.fs_bsize * 3)) == NULL)
errx(37, "panic: cannot allocate I/O buffer");
- }
+
/*
* Determine block bounds for cylinder group.
* Allow space for super block summary information in first
@@ -396,17 +396,12 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag)
dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
cs = &fscs[cylno];
memset(&acg, 0, sblock.fs_cgsize);
- /*
- * Note that we do not set cg_initediblk at all.
- * In this extension of a previous filesystem
- * we have no inodes initialized for the cylinder
- * group at all. The first access to that cylinder
- * group will do the correct initialization.
- */
acg.cg_time = utime;
acg.cg_magic = CG_MAGIC;
acg.cg_cgx = cylno;
acg.cg_niblk = sblock.fs_ipg;
+ acg.cg_initediblk = sblock.fs_ipg < 2 * INOPB(&sblock) ?
+ sblock.fs_ipg : 2 * INOPB(&sblock);
acg.cg_ndblk = dmax - cbase;
if (sblock.fs_contigsumsize > 0)
acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
@@ -419,6 +414,7 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag)
acg.cg_time = 0;
acg.cg_old_niblk = acg.cg_niblk;
acg.cg_niblk = 0;
+ acg.cg_initediblk = 0;
acg.cg_old_btotoff = start;
acg.cg_old_boff = acg.cg_old_btotoff +
sblock.fs_old_cpg * sizeof(int32_t);
@@ -538,11 +534,14 @@ initcg(int cylno, time_t utime, int fso, unsigned int Nflag)
sblock.fs_cstotal.cs_nbfree += acg.cg_cs.cs_nbfree;
sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree;
*cs = acg.cg_cs;
+
+ memcpy(iobuf, &acg, sblock.fs_cgsize);
+ memset(iobuf + sblock.fs_cgsize, '\0',
+ sblock.fs_bsize * 3 - sblock.fs_cgsize);
+
wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
- sblock.fs_bsize, (char *)&acg, fso, Nflag);
- DBG_DUMP_CG(&sblock,
- "new cg",
- &acg);
+ sblock.fs_bsize * 3, iobuf, fso, Nflag);
+ DBG_DUMP_CG(&sblock, "new cg", &acg);
DBG_LEAVE;
return;
OpenPOWER on IntegriCloud