Index: sbin/growfs/Makefile =================================================================== RCS file: /usr/local/bsdcvs/src/sbin/growfs/Makefile,v retrieving revision 1.5 diff -u -r1.5 Makefile --- sbin/growfs/Makefile 11 Jun 2003 23:24:31 -0000 1.5 +++ sbin/growfs/Makefile 13 Sep 2003 17:58:49 -0000 @@ -11,6 +11,8 @@ PROG= growfs SRCS= growfs.c MAN= growfs.8 +DPADD= ${LIBUFS} +LDADD= -lufs WARNS?= 0 Index: sbin/growfs/growfs.c =================================================================== RCS file: /usr/local/bsdcvs/src/sbin/growfs/growfs.c,v retrieving revision 1.15 diff -u -r1.15 growfs.c --- sbin/growfs/growfs.c 12 May 2003 05:37:16 -0000 1.15 +++ sbin/growfs/growfs.c 19 Sep 2003 17:56:23 -0000 @@ -52,9 +52,11 @@ #endif /* not lint */ /* ********************************************************** INCLUDES ***** */ +#include #include #include #include +#include #include #include @@ -67,8 +69,10 @@ #include #include #include +#include #include #include +#include #include "debug.h" @@ -77,18 +81,15 @@ int _dbg_lvl_ = (DL_INFO); /* DL_TRC */ #endif /* FS_DEBUG */ +struct uufsd disk; + static union { struct fs fs; char pad[SBLOCKSIZE]; -} fsun1, fsun2; -#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; +} fsun1; +#define fsun2 disk.d_sbunion +#define sblock disk.d_fs /* the new superblock */ +#define osblock fsun1.fs /* the old superblock */ static union { struct cg cg; @@ -112,6 +113,7 @@ static char inobuf[MAXBSIZE]; /* inode block */ static int maxino; /* last valid inode */ static int unlabeled; /* unlabeled partition, e.g. vinum volume etc. */ +static int Nflag; /* * An array of elements of type struct gfs_bpp describes all blocks to @@ -128,28 +130,27 @@ }; /* ******************************************************** PROTOTYPES ***** */ -static void growfs(int, int, unsigned int); -static void rdfs(ufs2_daddr_t, size_t, void *, int); -static void wtfs(ufs2_daddr_t, size_t, void *, int, unsigned int); +static void growfs(void); +static void rdfs(ufs2_daddr_t, size_t, void *); +static void wtfs(ufs2_daddr_t, size_t, void *); static ufs2_daddr_t alloc(void); static int charsperline(void); static void usage(void); static int isblock(struct fs *, unsigned char *, int); static void clrblock(struct fs *, unsigned char *, int); static void setblock(struct fs *, unsigned char *, int); -static void initcg(int, time_t, int, unsigned int); -static void updjcg(int, time_t, int, int, unsigned int); -static void updcsloc(time_t, int, int, unsigned int); +static void initcg(int, time_t); +static void updjcg(int, time_t); +static void updcsloc(time_t); static struct disklabel *get_disklabel(int); -static void return_disklabel(int, struct disklabel *, unsigned int); -static union dinode *ginode(ino_t, int, int); +static void return_disklabel(int, struct disklabel *); +static union dinode *ginode(ino_t, int); static void frag_adjust(ufs2_daddr_t, int); -static int cond_bl_upd(ufs2_daddr_t *, struct gfs_bpp *, int, int, - unsigned int); +static int cond_bl_upd(ufs2_daddr_t *, struct gfs_bpp *); static void updclst(int); -static void updrefs(int, ino_t, struct gfs_bpp *, int, int, unsigned int); +static void updrefs(int, ino_t, struct gfs_bpp *); static void indirchk(ufs_lbn_t, ufs_lbn_t, ufs2_daddr_t, ufs_lbn_t, - struct gfs_bpp *, int, int, unsigned int); + struct gfs_bpp *); static void get_dev_size(int, int *); /* ************************************************************ growfs ***** */ @@ -165,7 +166,7 @@ * copies. */ static void -growfs(int fsi, int fso, unsigned int Nflag) +growfs(void) { DBG_FUNC("growfs") int i; @@ -199,7 +200,7 @@ 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); + osblock.fs_bsize), (void *)(((char *)fscs)+i)); } #ifdef FS_DEBUG @@ -223,7 +224,7 @@ /* * Do all needed changes in the former last cylinder group. */ - updjcg(osblock.fs_ncg-1, utime, fsi, fso, Nflag); + updjcg(osblock.fs_ncg-1, utime); /* * Dump out summary information about file system. @@ -251,7 +252,7 @@ * Iterate for only the new cylinder groups. */ for (cylno = osblock.fs_ncg; cylno < sblock.fs_ncg; cylno++) { - initcg(cylno, utime, fso, Nflag); + initcg(cylno, utime); j = sprintf(tmpbuf, " %d%s", (int)fsbtodb(&sblock, cgsblock(&sblock, cylno)), cylno < (sblock.fs_ncg-1) ? "," : "" ); @@ -269,7 +270,7 @@ * Do all needed changes in the first cylinder group. * allocate blocks in new location */ - updcsloc(utime, fsi, fso, Nflag); + updcsloc(utime); /* * Now write the cylinder summary back to disk. @@ -277,7 +278,7 @@ 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); + (void *)(((char *)fscs) + i)); } DBG_PRINT0("fscs written\n"); @@ -302,7 +303,8 @@ * Now write the new superblock back to disk. */ sblock.fs_time = utime; - wtfs(sblockloc, (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag); + if (Nflag == 0 && sbwrite(&disk, 0) == -1) + err(1, "sbwrite: %s", disk.d_error); DBG_PRINT0("sblock written\n"); DBG_DUMP_FS(&sblock, "new initial sblock"); @@ -344,7 +346,7 @@ */ for (cylno = 0; cylno < sblock.fs_ncg; cylno++) { wtfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), - (size_t)SBLOCKSIZE, (void *)&sblock, fso, Nflag); + (size_t)SBLOCKSIZE, (void *)&sblock); } DBG_PRINT0("sblock copies written\n"); DBG_DUMP_FS(&sblock, @@ -362,11 +364,11 @@ * provisions for that case are removed here. */ static void -initcg(int cylno, time_t utime, int fso, unsigned int Nflag) +initcg(int cylno, time_t utime) { DBG_FUNC("initcg") static caddr_t iobuf; - long i, j, d, dlower, dupper, blkno, start; + long i, d, dlower, dupper, blkno, start; ufs2_daddr_t cbase, dmax; struct ufs1_dinode *dp1; struct ufs2_dinode *dp2; @@ -453,7 +455,7 @@ } #endif wtfs(fsbtodb(&sblock, cgimin(&sblock, cylno) + i), - sblock.fs_bsize, iobuf, fso, Nflag); + sblock.fs_bsize, iobuf); } if (cylno > 0) { /* @@ -527,7 +529,7 @@ sblock.fs_cstotal.cs_nifree += acg.cg_cs.cs_nifree; *cs = acg.cg_cs; wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), - sblock.fs_bsize, (char *)&acg, fso, Nflag); + sblock.fs_bsize, (char *)&acg); DBG_DUMP_CG(&sblock, "new cg", &acg); @@ -605,8 +607,7 @@ * out if a write back operation is needed. */ static int -cond_bl_upd(ufs2_daddr_t *block, struct gfs_bpp *field, int fsi, int fso, - unsigned int Nflag) +cond_bl_upd(ufs2_daddr_t *block, struct gfs_bpp *field) { DBG_FUNC("cond_bl_upd") struct gfs_bpp *f; @@ -644,8 +645,8 @@ if (!ibuf) errx(1, "malloc failed"); src -= fragnum; - rdfs(fsbtodb(&sblock, src), (size_t)sblock.fs_bsize, ibuf, fsi); - wtfs(dst, (size_t)sblock.fs_bsize, ibuf, fso, Nflag); + rdfs(fsbtodb(&sblock, src), (size_t)sblock.fs_bsize, ibuf); + wtfs(dst, (size_t)sblock.fs_bsize, ibuf); free(ibuf); /* * The same block can't be found again in this loop. @@ -670,7 +671,7 @@ * tables and cluster summary during all those operations. */ static void -updjcg(int cylno, time_t utime, int fsi, int fso, unsigned int Nflag) +updjcg(int cylno, time_t utime) { DBG_FUNC("updjcg") ufs2_daddr_t cbase, dmax, dupper; @@ -685,7 +686,7 @@ * a copy. */ rdfs(fsbtodb(&osblock, cgtod(&osblock, cylno)), - (size_t)osblock.fs_cgsize, (void *)&aocg, fsi); + (size_t)osblock.fs_cgsize, (void *)&aocg); DBG_PRINT0("jcg read\n"); DBG_DUMP_CG(&sblock, "old joining cg", @@ -706,7 +707,7 @@ acg.cg_old_ncyl=sblock.fs_old_cpg; wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), - (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag); + (size_t)sblock.fs_cgsize, (void *)&acg); DBG_PRINT0("jcg written\n"); DBG_DUMP_CG(&sblock, "new joining cg", @@ -895,7 +896,7 @@ * Write the updated "joining" cylinder group back to disk. */ wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), (size_t)sblock.fs_cgsize, - (void *)&acg, fso, Nflag); + (void *)&acg); DBG_PRINT0("jcg written\n"); DBG_DUMP_CG(&sblock, "new joining cg", @@ -923,7 +924,7 @@ * completely avoid implementing copy on write if we stick to method (2) only. */ static void -updcsloc(time_t utime, int fsi, int fso, unsigned int Nflag) +updcsloc(time_t utime) { DBG_FUNC("updcsloc") struct csum *cs; @@ -959,7 +960,7 @@ * block from disk. */ rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)), - (size_t)osblock.fs_cgsize, (void *)&aocg, fsi); + (size_t)osblock.fs_cgsize, (void *)&aocg); DBG_PRINT0("oscg read\n"); DBG_DUMP_CG(&sblock, "old summary cg", @@ -1111,7 +1112,7 @@ * summary back to disk. */ wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), - (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag); + (size_t)sblock.fs_cgsize, (void *)&acg); DBG_PRINT0("oscg written\n"); DBG_DUMP_CG(&sblock, "old summary cg", @@ -1142,7 +1143,7 @@ * summary from disk, and make a copy. */ rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), - (size_t)sblock.fs_cgsize, (void *)&aocg, fsi); + (size_t)sblock.fs_cgsize, (void *)&aocg); DBG_PRINT0("nscg read\n"); DBG_DUMP_CG(&sblock, "new summary cg", @@ -1210,7 +1211,7 @@ * back to disk. */ wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), - (size_t)sblock.fs_cgsize, (void *)&acg, fso, Nflag); + (size_t)sblock.fs_cgsize, (void *)&acg); DBG_PRINT0("nscg written\n"); DBG_DUMP_CG(&sblock, "new summary cg", @@ -1461,9 +1462,9 @@ * in the case we have any active snapshots. */ rdfs(fsbtodb(&sblock, bp[i].old*sblock.fs_frag), - (size_t)sblock.fs_bsize, (void *)&ablk, fsi); + (size_t)sblock.fs_bsize, (void *)&ablk); wtfs(fsbtodb(&sblock, bp[i].new*sblock.fs_frag), - (size_t)sblock.fs_bsize, (void *)&ablk, fso, Nflag); + (size_t)sblock.fs_bsize, (void *)&ablk); DBG_DUMP_HEX(&sblock, "copied full block", (unsigned char *)&ablk); @@ -1483,7 +1484,7 @@ DBG_PRINT1("scg doing cg (%d)\n", cylno); for(inc=osblock.fs_ipg-1 ; inc>=0 ; inc--) { - updrefs(cylno, (ino_t)inc, bp, fsi, fso, Nflag); + updrefs(cylno, (ino_t)inc, bp); } } @@ -1493,7 +1494,7 @@ */ for(i=0; isblock.fs_frag)) { - warnx("error: %d refs found for block %d.", + warnx("error: %d refs found for block %jd.", bp[i].found, bp[i].old); } @@ -1516,7 +1517,7 @@ * Write summary cylinder group back to disk. */ wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), (size_t)sblock.fs_cgsize, - (void *)&acg, fso, Nflag); + (void *)&acg); DBG_PRINT0("scg written\n"); DBG_DUMP_CG(&sblock, "new summary cg", @@ -1531,20 +1532,14 @@ * Here we read some block(s) from disk. */ static void -rdfs(ufs2_daddr_t bno, size_t size, void *bf, int fsi) +rdfs(ufs2_daddr_t bno, size_t size, void *bf) { DBG_FUNC("rdfs") - ssize_t n; DBG_ENTER; - if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) { - err(33, "rdfs: seek error: %ld", (long)bno); - } - n = read(fsi, bf, size); - if (n != (ssize_t)size) { - err(34, "rdfs: read error: %ld", (long)bno); - } + if (bread(&disk, bno, bf, size) == -1) + err(1, "rdfs: read error: %ld: %s", (long)bno, disk.d_error); DBG_LEAVE; return; @@ -1555,10 +1550,9 @@ * Here we write some block(s) to disk. */ static void -wtfs(ufs2_daddr_t bno, size_t size, void *bf, int fso, unsigned int Nflag) +wtfs(ufs2_daddr_t bno, size_t size, void *bf) { DBG_FUNC("wtfs") - ssize_t n; DBG_ENTER; @@ -1566,13 +1560,9 @@ DBG_LEAVE; return; } - if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0) { - err(35, "wtfs: seek error: %ld", (long)bno); - } - n = write(fso, bf, size); - if (n != (ssize_t)size) { - err(36, "wtfs: write error: %ld", (long)bno); - } + + if (bwrite(&disk, bno, bf, size) == -1) + err(35, "wtfs: write error: %ld: %s", (long)bno, disk.d_error); DBG_LEAVE; return; @@ -1828,7 +1818,7 @@ * inodes. */ static union dinode * -ginode(ino_t inumber, int fsi, int cg) +ginode(ino_t inumber, int cg) { DBG_FUNC("ginode") static ino_t startinum = 0; /* first inode in cached block */ @@ -1841,7 +1831,7 @@ if (startinum == 0 || inumber < startinum || inumber >= startinum + INOPB(&sblock)) { inoblk = fsbtodb(&sblock, ino_to_fsba(&sblock, inumber)); - rdfs(inoblk, (size_t)sblock.fs_bsize, inobuf, fsi); + rdfs(inoblk, (size_t)sblock.fs_bsize, inobuf); startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock); } DBG_LEAVE; @@ -1936,12 +1926,10 @@ char ch; unsigned int size=0; size_t len; - unsigned int Nflag=0; int ExpertFlag=0; struct stat st; struct disklabel *lp; struct partition *pp; - int i,fsi,fso; u_int32_t p_size; char reply[5]; #ifdef FSMAXSNAP @@ -2016,24 +2004,12 @@ } /* - * Try to access our devices for writing ... - */ - if (Nflag) { - fso = -1; - } else { - fso = open(device, O_WRONLY); - if (fso < 0) { - err(1, "%s", device); - } - } - - /* - * ... and reading. + * Try to access our device read/write. */ - fsi = open(device, O_RDONLY); - if (fsi < 0) { - err(1, "%s", device); - } + if (ufs_disk_fillout(&disk, device) == -1) + err(1, "ufs_disk_fillout: %s", disk.d_error); + if (ufs_disk_write(&disk) == -1) + err(1, "ufs_disk_write: %s", disk.d_error); /* * Try to read a label and guess the slice if not specified. This @@ -2041,7 +2017,7 @@ * with the task of specifying the option -v on vinum volumes. */ cp=device+strlen(device)-1; - lp = get_disklabel(fsi); + lp = get_disklabel(disk.d_fd); if (lp != NULL) { if (isdigit(*cp)) { pp = &lp->d_partitions[2]; @@ -2052,7 +2028,7 @@ } p_size = pp->p_size; } else { - get_dev_size(fsi, &p_size); + get_dev_size(disk.d_fd, &p_size); } /* @@ -2063,21 +2039,8 @@ } /* - * Read the current superblock, and take a backup. + * Take a backup of the superblock. */ - 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 >= sizeof(struct fs)) - break; - } - if (sblock_try[i] == -1) { - errx(1, "superblock not recognized"); - } memcpy((void *)&fsun1, (void *)&fsun2, sizeof(fsun2)); maxino = sblock.fs_ncg * sblock.fs_ipg; @@ -2102,7 +2065,7 @@ * Are we really growing ? */ if(osblock.fs_size >= sblock.fs_size) { - errx(1, "we are not growing (%d->%d)", osblock.fs_size, + errx(1, "we are not growing (%jd->%jd)", osblock.fs_size, sblock.fs_size); } @@ -2136,15 +2099,14 @@ } } - printf("new file systemsize is: %d frags\n", sblock.fs_size); + printf("new file system size is: %jd frags\n", sblock.fs_size); /* * Try to access our new last block in the file system. Even if we * later on realize we have to abort our operation, on that block * there should be no data, so we can't destroy something yet. */ - wtfs((ufs2_daddr_t)p_size-1, (size_t)DEV_BSIZE, (void *)&sblock, - fso, Nflag); + wtfs((ufs2_daddr_t)p_size-1, (size_t)DEV_BSIZE, (void *)&sblock); /* * Now calculate new superblock values and check for reasonable @@ -2178,7 +2140,7 @@ sblock.fs_ncg--; if (sblock.fs_magic == FS_UFS1_MAGIC) sblock.fs_old_ncyl = sblock.fs_ncg * sblock.fs_old_cpg; - printf("Warning: %d sector(s) cannot be allocated.\n", + printf("Warning: %jd sector(s) cannot be allocated.\n", fsbtodb(&sblock, sblock.fs_size % sblock.fs_fpg)); sblock.fs_size = sblock.fs_ncg * sblock.fs_fpg; } @@ -2199,7 +2161,7 @@ /* * Ok, everything prepared, so now let's do the tricks. */ - growfs(fsi, fso, Nflag); + growfs(); /* * Update the disk label. @@ -2209,12 +2171,11 @@ pp->p_frag = sblock.fs_frag; pp->p_cpg = sblock.fs_fpg; - return_disklabel(fso, lp, Nflag); + return_disklabel(disk.d_fd, lp); DBG_PRINT0("label rewritten\n"); } - close(fsi); - if(fso>-1) close(fso); + ufs_disk_close(&disk); DBG_CLOSE; @@ -2227,7 +2188,7 @@ * Write the updated disklabel back to disk. */ static void -return_disklabel(int fd, struct disklabel *lp, unsigned int Nflag) +return_disklabel(int fd, struct disklabel *lp) { DBG_FUNC("return_disklabel") u_short sum; @@ -2358,14 +2319,13 @@ * cylinder group. */ static void -updrefs(int cg, ino_t in, struct gfs_bpp *bp, int fsi, int fso, unsigned int - Nflag) +updrefs(int cg, ino_t in, struct gfs_bpp *bp) { DBG_FUNC("updrefs") ufs_lbn_t len, lbn, numblks; ufs2_daddr_t iptr, blksperindir; union dinode *ino; - int i, mode, remaining_blocks, inodeupdated; + int i, mode, inodeupdated; DBG_ENTER; @@ -2373,7 +2333,7 @@ * XXX We should skip unused inodes even from being read from disk * here by using the bitmap. */ - ino = ginode(in, fsi, cg); + ino = ginode(in, cg); mode = DIP(ino, di_mode) & IFMT; if (mode != IFDIR && mode != IFREG && mode != IFLNK) { DBG_LEAVE; @@ -2405,7 +2365,7 @@ iptr = DIP(ino, di_db[i]); if (iptr == 0) continue; - if (cond_bl_upd(&iptr, bp, fsi, fso, Nflag)) { + if (cond_bl_upd(&iptr, bp)) { DIP(ino, di_db[i]) = iptr; inodeupdated++; } @@ -2419,18 +2379,18 @@ iptr = DIP(ino, di_ib[i]); if (iptr == 0) continue; - if (cond_bl_upd(&iptr, bp, fsi, fso, Nflag)) { + if (cond_bl_upd(&iptr, bp)) { DIP(ino, di_ib[i]) = iptr; inodeupdated++; } - indirchk(blksperindir, lbn, iptr, numblks, bp, fsi, fso, Nflag); + indirchk(blksperindir, lbn, iptr, numblks, bp); blksperindir *= NINDIR(&sblock); lbn += blksperindir; len -= blksperindir; DBG_PRINT1("scg indirect_%d blocks checked\n", i + 1); } if (inodeupdated) - wtfs(inoblk, sblock.fs_bsize, inobuf, fso, Nflag); + wtfs(inoblk, sblock.fs_bsize, inobuf); DBG_LEAVE; return; @@ -2441,11 +2401,10 @@ */ static void indirchk(ufs_lbn_t blksperindir, ufs_lbn_t lbn, ufs2_daddr_t blkno, - ufs_lbn_t lastlbn, struct gfs_bpp *bp, int fsi, int fso, unsigned int Nflag) + ufs_lbn_t lastlbn, struct gfs_bpp *bp) { DBG_FUNC("indirchk") void *ibuf; - off_t offset; int i, last; ufs2_daddr_t iptr; @@ -2455,7 +2414,7 @@ ibuf = malloc(sblock.fs_bsize); if (!ibuf) errx(1, "malloc failed"); - rdfs(fsbtodb(&sblock, blkno), (size_t)sblock.fs_bsize, ibuf, fsi); + rdfs(fsbtodb(&sblock, blkno), (size_t)sblock.fs_bsize, ibuf); last = howmany(lastlbn - lbn, blksperindir) < NINDIR(&sblock) ? howmany(lastlbn - lbn, blksperindir) : NINDIR(&sblock); for (i = 0; i < last; i++) { @@ -2465,7 +2424,7 @@ iptr = ((ufs2_daddr_t *)ibuf)[i]; if (iptr == 0) continue; - if (cond_bl_upd(&iptr, bp, fsi, fso, Nflag)) { + if (cond_bl_upd(&iptr, bp)) { if (sblock.fs_magic == FS_UFS1_MAGIC) ((ufs1_daddr_t *)ibuf)[i] = iptr; else @@ -2474,7 +2433,7 @@ if (blksperindir == 1) continue; indirchk(blksperindir / NINDIR(&sblock), lbn + blksperindir * i, - iptr, lastlbn, bp, fsi, fso, Nflag); + iptr, lastlbn, bp); } free(ibuf);