diff options
Diffstat (limited to 'sbin/growfs/growfs.c')
-rw-r--r-- | sbin/growfs/growfs.c | 123 |
1 files changed, 50 insertions, 73 deletions
diff --git a/sbin/growfs/growfs.c b/sbin/growfs/growfs.c index 7670317caae7..61f90de7ea68 100644 --- a/sbin/growfs/growfs.c +++ b/sbin/growfs/growfs.c @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include <paths.h> #include <ctype.h> #include <err.h> +#include <errno.h> #include <fcntl.h> #include <fstab.h> #include <inttypes.h> @@ -95,12 +96,6 @@ static union { #define sblock fsun1.fs /* the new superblock */ #define osblock fsun2.fs /* the old superblock */ -/* - * Possible superblock locations ordered from most to least likely. - */ -static int sblock_try[] = SBLOCKSEARCH; -static ufs2_daddr_t sblockloc; - static union { struct cg cg; char pad[MAXBSIZE]; @@ -156,11 +151,10 @@ growfs(int fsi, int fso, unsigned int Nflag) fscs = (struct csum *)calloc((size_t)1, (size_t)sblock.fs_cssize); if (fscs == NULL) errx(1, "calloc failed"); - for (i = 0; i < osblock.fs_cssize; i += osblock.fs_bsize) { - rdfs(fsbtodb(&osblock, osblock.fs_csaddr + - numfrags(&osblock, i)), (size_t)MIN(osblock.fs_cssize - i, - osblock.fs_bsize), (void *)(((char *)fscs) + i), fsi); - } + memcpy(fscs, osblock.fs_csp, osblock.fs_cssize); + free(osblock.fs_csp); + osblock.fs_csp = NULL; + sblock.fs_csp = fscs; #ifdef FS_DEBUG { @@ -234,50 +228,8 @@ growfs(int fsi, int fso, unsigned int Nflag) updcsloc(modtime, fsi, fso, Nflag); /* - * Now write the cylinder summary back to disk. - */ - for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize) { - wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)), - (size_t)MIN(sblock.fs_cssize - i, sblock.fs_bsize), - (void *)(((char *)fscs) + i), fso, Nflag); - } - DBG_PRINT0("fscs written\n"); - -#ifdef FS_DEBUG - { - struct csum *dbg_csp; - u_int32_t dbg_csc; - char dbg_line[80]; - - dbg_csp = fscs; - for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) { - snprintf(dbg_line, sizeof(dbg_line), - "%d. new csum in new location", dbg_csc); - DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++); - } - } -#endif /* FS_DEBUG */ - - /* - * Now write the new superblock back to disk. - */ - sblock.fs_time = modtime; - wtfs(sblockloc, (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag); - DBG_PRINT0("sblock written\n"); - DBG_DUMP_FS(&sblock, "new initial sblock"); - - /* - * Clean up the dynamic fields in our superblock copies. - */ - sblock.fs_fmod = 0; - sblock.fs_clean = 1; - sblock.fs_ronly = 0; - sblock.fs_cgrotor = 0; - sblock.fs_state = 0; - memset((void *)&sblock.fs_fsmnt, 0, sizeof(sblock.fs_fsmnt)); - sblock.fs_flags &= FS_DOSOFTDEP; - - /* + * Clean up the dynamic fields in our superblock. + * * XXX * The following fields are currently distributed from the superblock * to the copies: @@ -287,7 +239,7 @@ growfs(int fsi, int fso, unsigned int Nflag) * fs_maxbpg * fs_minfree, * fs_optim - * fs_flags regarding SOFTPDATES + * fs_flags * * We probably should rather change the summary for the cylinder group * statistics here to the value of what would be in there, if the file @@ -297,14 +249,40 @@ growfs(int fsi, int fso, unsigned int Nflag) * "diffed" stats between the old and new superblock by still copying * certain parameters onto that. */ + sblock.fs_time = modtime; + sblock.fs_fmod = 0; + sblock.fs_clean = 1; + sblock.fs_ronly = 0; + sblock.fs_cgrotor = 0; + sblock.fs_state = 0; + memset((void *)&sblock.fs_fsmnt, 0, sizeof(sblock.fs_fsmnt)); /* - * Write out the duplicate super blocks. + * Now write the new superblock, its summary information, + * and all the alternates back to disk. */ - for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { - wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), - (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag); + if (!Nflag && sbput(fso, &sblock, sblock.fs_ncg) != 0) + errc(2, EIO, "could not write updated superblock"); + DBG_PRINT0("fscs written\n"); + +#ifdef FS_DEBUG + { + struct csum *dbg_csp; + u_int32_t dbg_csc; + char dbg_line[80]; + + dbg_csp = fscs; + for (dbg_csc = 0; dbg_csc < sblock.fs_ncg; dbg_csc++) { + snprintf(dbg_line, sizeof(dbg_line), + "%d. new csum in new location", dbg_csc); + DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++); + } } +#endif /* FS_DEBUG */ + + DBG_PRINT0("sblock written\n"); + DBG_DUMP_FS(&sblock, "new initial sblock"); + DBG_PRINT0("sblock copies written\n"); DBG_DUMP_FS(&sblock, "new other sblocks"); @@ -1374,11 +1352,12 @@ int main(int argc, char **argv) { DBG_FUNC("main") + struct fs *fs; const char *device; const struct statfs *statfsp; uint64_t size = 0; off_t mediasize; - int error, i, j, fsi, fso, ch, Nflag = 0, yflag = 0; + int error, j, fsi, fso, ch, ret, Nflag = 0, yflag = 0; char *p, reply[5], oldsizebuf[6], newsizebuf[6]; void *testbuf; @@ -1452,19 +1431,17 @@ main(int argc, char **argv) /* * Read the current superblock, and take a backup. */ - for (i = 0; sblock_try[i] != -1; i++) { - sblockloc = sblock_try[i] / DEV_BSIZE; - rdfs(sblockloc, (size_t)SBLOCKSIZE, (void *)&(osblock), fsi); - if ((osblock.fs_magic == FS_UFS1_MAGIC || - (osblock.fs_magic == FS_UFS2_MAGIC && - osblock.fs_sblockloc == sblock_try[i])) && - osblock.fs_bsize <= MAXBSIZE && - osblock.fs_bsize >= (int32_t) sizeof(struct fs)) - break; + if ((ret = sbget(fsi, &fs, -1)) != 0) { + switch (ret) { + case ENOENT: + errx(1, "superblock not recognized"); + default: + errc(1, ret, "unable to read superblock"); + } } - if (sblock_try[i] == -1) - errx(1, "superblock not recognized"); - memcpy((void *)&fsun1, (void *)&fsun2, sizeof(fsun2)); + memcpy(&osblock, fs, fs->fs_sbsize); + free(fs); + memcpy((void *)&fsun1, (void *)&fsun2, osblock.fs_sbsize); DBG_OPEN("/tmp/growfs.debug"); /* already here we need a superblock */ DBG_DUMP_FS(&sblock, "old sblock"); |