aboutsummaryrefslogtreecommitdiff
path: root/sbin/growfs/growfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/growfs/growfs.c')
-rw-r--r--sbin/growfs/growfs.c123
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");