corrected spelling mistakes in comments

check a couple of mallocs
usage of errx
linebreaks of DBG_ macros,
correcting the usage of nroff macros

Submitted by:	grog, charnier
Reviewed by:	chm
This commit is contained in:
Thomas-Henning von Kamptz 2000-12-12 20:03:17 +00:00
parent 34da0ef197
commit 4020c5bc54
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=69926
5 changed files with 310 additions and 235 deletions

View File

@ -34,7 +34,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $TSHeader: src/sbin/ffsinfo/ffsinfo.8,v 1.2 2000/12/09 15:12:31 tomsoft Exp $ .\" $TSHeader: src/sbin/ffsinfo/ffsinfo.8,v 1.3 2000/12/12 19:30:55 tomsoft Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd September 8, 2000 .Dd September 8, 2000
@ -50,7 +50,7 @@
.Op Fl i Ar inode .Op Fl i Ar inode
.Op Fl l Ar level .Op Fl l Ar level
.Op Fl o Ar outfile .Op Fl o Ar outfile
.Ar < special | file > .Ar special | file
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm Ffsinfo .Nm Ffsinfo
extends the extends the
@ -58,26 +58,27 @@ extends the
program. program.
.Pp .Pp
The output is generated into the file The output is generated into the file
.Nm outfile . .Pa outfile .
Also expect the output file to be rather large. Up to 2 percent of the size Also expect the output file to be rather large.
of the specified filesystem is not uncommon. Up to 2 percent of the size of the specified filesystem is not uncommon.
.Nm Ffsinfo .Pp
has some options to allow the defaults to be overridden. The following options are available:
.\".Pp .\".Pp
.Bl -tag -width indent .Bl -tag -width indent
.It Fl L .It Fl L
Specifying this options skips the tests of the disklabel. This is automatically Specifying this option skips the tests of the disklabel.
done, if the specified filename to dump is a plain file. This is done automatically, if the specified filename to dump is a plain file.
.It Fl g Ar cylinder group .It Fl g Ar cylinder group
This restrictes the dump to infomation about this cylinder group only. Here This restricts the dump to infomation about this cylinder group only.
0 means the first cylinder group and -1 the last one. Here 0 means the first cylinder group and -1 the last one.
.It Fl i Ar inode .It Fl i Ar inode
This restrictes the dump to infomation about this particular inode only. Here This restrictes the dump to infomation about this particular inode only.
the minimum acceptable inode is 2. If this option is omitted but a cylinder Here the minimum acceptable inode is 2.
group is defined then only inodes within that cylinder group are dumped. If this option is omitted but a cylinder group is defined then only inodes
within that cylinder group are dumped.
.It Fl l Ar level .It Fl l Ar level
The level of detail which will be dumped. This value defaults The level of detail which will be dumped.
to 255 and is the bitwise and of the following table: This value defaults to 255 and is the bitwise and of the following table:
.Bd -literal -offset left .Bd -literal -offset left
0x001 - initial superblock 0x001 - initial superblock
0x002 - superblock copys in each cylindergroup 0x002 - superblock copys in each cylindergroup
@ -91,25 +92,29 @@ to 255 and is the bitwise and of the following table:
0x200 - indirect block dump 0x200 - indirect block dump
.Ed .Ed
.It Fl o Ar outfile .It Fl o Ar outfile
This allows to change the output filename where the dump is written to. The This allows to change the output filename where the dump is written to.
current default is The current default is
.Nm /var/tmp/ffsinfo . .Pa /var/tmp/ffsinfo .
.El .El
.Sh EXAMPLES .Sh EXAMPLES
.Pp .Pp
.Dl ffsinfo -l 1023 /dev/vinum/testvol .Dl ffsinfo -l 1023 /dev/vinum/testvol
.Pp .Pp
will dump /dev/vinum/testvol with all available information. will dump
.Pa /dev/vinum/testvol
with all available information.
.Sh BUGS .Sh BUGS
Currently Currently
.Nm .Nm
can only dump unmounted file systems. Do not try dumping a mounted file system, can only dump unmounted file systems.
your system may panic and you will not be able to use the file system any Do not try dumping a mounted file system, your system may panic and you will
longer. not be able to use the file system any longer.
.Pp .Pp
Also snapshots are handled like plain files. They should get a their own Also snapshots are handled like plain files.
level to provide for independent control of the amount of what gets dumped. It They should get a their own level to provide for independent control of the
probably also makes sense to some extend to dump the snapshot as a filesystem. amount of what gets dumped.
It probably also makes sense to some extend to dump the snapshot as a
filesystem.
.Sh SEE ALSO .Sh SEE ALSO
.Xr vinum 8 , .Xr vinum 8 ,
.Xr disklabel 8 , .Xr disklabel 8 ,

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $TSHeader: src/sbin/ffsinfo/ffsinfo.c,v 1.3 2000/12/09 15:12:31 tomsoft Exp $ * $TSHeader: src/sbin/ffsinfo/ffsinfo.c,v 1.4 2000/12/12 19:30:55 tomsoft Exp $
* $FreeBSD$ * $FreeBSD$
* *
*/ */
@ -55,22 +55,16 @@ static const char rcsid[] =
/* ********************************************************** INCLUDES ***** */ /* ********************************************************** INCLUDES ***** */
#include <sys/param.h> #include <sys/param.h>
#include <sys/disklabel.h> #include <sys/disklabel.h>
#include <sys/ioctl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h>
#include <stdio.h> #include <stdio.h>
#include <paths.h> #include <paths.h>
#include <ctype.h> #include <ctype.h>
#include <err.h> #include <err.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <machine/param.h>
#include "debug.h" #include "debug.h"
@ -101,7 +95,7 @@ static struct csum *fscs;
/* ******************************************************** PROTOTYPES ***** */ /* ******************************************************** PROTOTYPES ***** */
static void rdfs(daddr_t, int, char *, int); static void rdfs(daddr_t, int, char *, int);
static void usage(char *); static void usage(void);
static struct disklabel *get_disklabel(int); static struct disklabel *get_disklabel(int);
static struct dinode *ginode(ino_t, int); static struct dinode *ginode(ino_t, int);
static void dump_whole_inode(ino_t, int, int); static void dump_whole_inode(ino_t, int, int);
@ -119,13 +113,11 @@ rdfs(daddr_t bno, int size, char *bf, int fsi)
DBG_ENTER; DBG_ENTER;
if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) { if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) {
fprintf(stderr, "seek error: %ld\n", (long)bno); err(33, "rdfs: seek error: %ld", (long)bno);
err(33, "rdfs");
} }
n = read(fsi, bf, (size_t)size); n = read(fsi, bf, (size_t)size);
if (n != size) { if (n != size) {
fprintf(stderr, "read error: %ld\n", (long)bno); err(34, "rdfs: read error: %ld", (long)bno);
err(34, "rdfs");
} }
DBG_LEAVE; DBG_LEAVE;
@ -149,7 +141,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
DBG_FUNC("main") DBG_FUNC("main")
char *a0, *device, *special, *cp; char *device, *special, *cp;
char ch; char ch;
size_t len; size_t len;
struct stat st; struct stat st;
@ -172,8 +164,10 @@ main(int argc, char **argv)
cfg_in=-2; cfg_in=-2;
cfg_cg=-2; cfg_cg=-2;
out_file=strdup("/var/tmp/ffsinfo"); out_file=strdup("/var/tmp/ffsinfo");
if(out_file == NULL) {
a0=*argv; /* save argv[0] for usage() */ errx(1, "strdup failed");
}
while ((ch=getopt(argc, argv, "Lg:i:l:o:")) != -1) { while ((ch=getopt(argc, argv, "Lg:i:l:o:")) != -1) {
switch(ch) { switch(ch) {
case 'L': case 'L':
@ -182,36 +176,39 @@ main(int argc, char **argv)
case 'g': case 'g':
cfg_cg=atol(optarg); cfg_cg=atol(optarg);
if(cfg_cg < -1) { if(cfg_cg < -1) {
usage(a0); usage();
} }
break; break;
case 'i': case 'i':
cfg_in=atol(optarg); cfg_in=atol(optarg);
if(cfg_in < 0) { if(cfg_in < 0) {
usage(a0); usage();
} }
break; break;
case 'l': case 'l':
cfg_lv=atol(optarg); cfg_lv=atol(optarg);
if(cfg_lv < 0x1||cfg_lv > 0x3ff) { if(cfg_lv < 0x1||cfg_lv > 0x3ff) {
usage(a0); usage();
} }
break; break;
case 'o': case 'o':
free(out_file); free(out_file);
out_file=strdup(optarg); out_file=strdup(optarg);
if(out_file == NULL) {
errx(1, "strdup failed");
}
break; break;
case '?': case '?':
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
usage(a0); usage();
} }
} }
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if(argc != 1) { if(argc != 1) {
usage(a0); usage();
} }
device=*argv; device=*argv;
@ -231,6 +228,9 @@ main(int argc, char **argv)
*/ */
len=strlen(device)+strlen(_PATH_DEV)+2+strlen("vinum/"); len=strlen(device)+strlen(_PATH_DEV)+2+strlen("vinum/");
special=(char *)malloc(len); special=(char *)malloc(len);
if(special == NULL) {
errx(1, "malloc failed");
}
snprintf(special, len, "%sr%s", _PATH_DEV, device); snprintf(special, len, "%sr%s", _PATH_DEV, device);
if (stat(special, &st) == -1) { if (stat(special, &st) == -1) {
snprintf(special, len, "%s%s", _PATH_DEV, device); snprintf(special, len, "%s%s", _PATH_DEV, device);
@ -254,8 +254,7 @@ main(int argc, char **argv)
*/ */
fsi = open(device, O_RDONLY); fsi = open(device, O_RDONLY);
if (fsi < 0) { if (fsi < 0) {
fprintf(stderr, "%s: %s\n", device, strerror(errno)); err(1, "%s", device);
exit(-1);
} }
stat(device, &st); stat(device, &st);
@ -280,20 +279,17 @@ main(int argc, char **argv)
} else if (*cp>='a' && *cp<='h') { } else if (*cp>='a' && *cp<='h') {
pp = &lp->d_partitions[*cp - 'a']; pp = &lp->d_partitions[*cp - 'a'];
} else { } else {
fprintf(stderr, "unknown device\n"); errx(1, "unknown device");
exit(-1);
} }
/* /*
* Check if that partition looks suited for dumping. * Check if that partition looks suited for dumping.
*/ */
if (pp->p_size < 1) { if (pp->p_size < 1) {
fprintf(stderr, "partition is unavailable\n"); errx(1, "partition is unavailable");
exit(-1);
} }
if (pp->p_fstype != FS_BSDFFS) { if (pp->p_fstype != FS_BSDFFS) {
fprintf(stderr, "partition not 4.2BSD\n"); errx(1, "partition not 4.2BSD");
exit(-1);
} }
} }
@ -302,14 +298,14 @@ main(int argc, char **argv)
*/ */
rdfs((daddr_t)(SBOFF/DEV_BSIZE), SBSIZE, (char *)&(sblock), fsi); rdfs((daddr_t)(SBOFF/DEV_BSIZE), SBSIZE, (char *)&(sblock), fsi);
if (sblock.fs_magic != FS_MAGIC) { if (sblock.fs_magic != FS_MAGIC) {
fprintf(stderr, "superblock not recognized\n"); errx(1, "superblock not recognized");
exit(-1);
} }
DBG_OPEN(out_file); /* already here we need a superblock */ DBG_OPEN(out_file); /* already here we need a superblock */
if(cfg_lv & 0x001) { if(cfg_lv & 0x001) {
DBG_DUMP_FS(&sblock, "primary sblock"); DBG_DUMP_FS(&sblock,
"primary sblock");
} }
/* /*
@ -331,6 +327,9 @@ main(int argc, char **argv)
if (cfg_lv & 0x004) { if (cfg_lv & 0x004) {
fscs = (struct csum *)calloc(1, (size_t)sblock.fs_cssize); fscs = (struct csum *)calloc(1, (size_t)sblock.fs_cssize);
if(fscs == NULL) {
errx(1, "calloc failed");
}
/* /*
* Get the cylinder summary into the memory ... * Get the cylinder summary into the memory ...
@ -349,7 +348,9 @@ main(int argc, char **argv)
for(dbg_csc=0; dbg_csc<sblock.fs_ncg; dbg_csc++) { for(dbg_csc=0; dbg_csc<sblock.fs_ncg; dbg_csc++) {
snprintf(dbg_line, 80, "%d. csum in fscs", snprintf(dbg_line, 80, "%d. csum in fscs",
dbg_csc); dbg_csc);
DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++); DBG_DUMP_CSUM(&sblock,
dbg_line,
dbg_csp++);
} }
} }
@ -364,7 +365,8 @@ main(int argc, char **argv)
*/ */
rdfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)), rdfs(fsbtodb(&sblock, cgsblock(&sblock, cylno)),
SBSIZE, (char *)&osblock, fsi); SBSIZE, (char *)&osblock, fsi);
DBG_DUMP_FS(&osblock, dbg_line); DBG_DUMP_FS(&osblock,
dbg_line);
} }
/* /*
* ... read the cylinder group and dump whatever was requested. * ... read the cylinder group and dump whatever was requested.
@ -372,20 +374,32 @@ main(int argc, char **argv)
rdfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, rdfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize,
(char *)&acg, fsi); (char *)&acg, fsi);
if(cfg_lv & 0x008) { if(cfg_lv & 0x008) {
DBG_DUMP_CG(&sblock, dbg_line, &acg); DBG_DUMP_CG(&sblock,
dbg_line,
&acg);
} }
if(cfg_lv & 0x010) { if(cfg_lv & 0x010) {
DBG_DUMP_INMAP(&sblock, dbg_line, &acg); DBG_DUMP_INMAP(&sblock,
dbg_line,
&acg);
} }
if(cfg_lv & 0x020) { if(cfg_lv & 0x020) {
DBG_DUMP_FRMAP(&sblock, dbg_line, &acg); DBG_DUMP_FRMAP(&sblock,
dbg_line,
&acg);
} }
if(cfg_lv & 0x040) { if(cfg_lv & 0x040) {
DBG_DUMP_CLMAP(&sblock, dbg_line, &acg); DBG_DUMP_CLMAP(&sblock,
DBG_DUMP_CLSUM(&sblock, dbg_line, &acg); dbg_line,
&acg);
DBG_DUMP_CLSUM(&sblock,
dbg_line,
&acg);
} }
if(cfg_lv & 0x080) { if(cfg_lv & 0x080) {
DBG_DUMP_SPTBL(&sblock, dbg_line, &acg); DBG_DUMP_SPTBL(&sblock,
dbg_line,
&acg);
} }
} }
/* /*
@ -440,7 +454,9 @@ dump_whole_inode(ino_t inode, int fsi, int level)
*/ */
snprintf(comment, 80, "Inode 0x%08x", inode); snprintf(comment, 80, "Inode 0x%08x", inode);
if (level & 0x100) { if (level & 0x100) {
DBG_DUMP_INO(&sblock, comment, ino); DBG_DUMP_INO(&sblock,
comment,
ino);
} }
if (!(level & 0x200)) { if (!(level & 0x200)) {
@ -459,7 +475,10 @@ dump_whole_inode(ino_t inode, int fsi, int level)
rdfs(fsbtodb(&sblock, ino->di_ib[0]), sblock.fs_bsize, i1blk, rdfs(fsbtodb(&sblock, ino->di_ib[0]), sblock.fs_bsize, i1blk,
fsi); fsi);
snprintf(comment, 80, "Inode 0x%08x: indirect 0", inode); snprintf(comment, 80, "Inode 0x%08x: indirect 0", inode);
DBG_DUMP_IBLK(&sblock, comment, i1blk, (size_t)rb); DBG_DUMP_IBLK(&sblock,
comment,
i1blk,
(size_t)rb);
rb-=howmany(sblock.fs_bsize, sizeof(ufs_daddr_t)); rb-=howmany(sblock.fs_bsize, sizeof(ufs_daddr_t));
} }
if(rb>0) { if(rb>0) {
@ -469,8 +488,10 @@ dump_whole_inode(ino_t inode, int fsi, int level)
rdfs(fsbtodb(&sblock, ino->di_ib[1]), sblock.fs_bsize, i2blk, rdfs(fsbtodb(&sblock, ino->di_ib[1]), sblock.fs_bsize, i2blk,
fsi); fsi);
snprintf(comment, 80, "Inode 0x%08x: indirect 1", inode); snprintf(comment, 80, "Inode 0x%08x: indirect 1", inode);
DBG_DUMP_IBLK(&sblock, comment, i2blk, howmany(rb, DBG_DUMP_IBLK(&sblock,
howmany(sblock.fs_bsize, sizeof(ufs_daddr_t)))); comment,
i2blk,
howmany(rb, howmany(sblock.fs_bsize, sizeof(ufs_daddr_t))));
for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize, for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize,
sizeof(ufs_daddr_t)))&&(rb>0)); ind2ctr++) { sizeof(ufs_daddr_t)))&&(rb>0)); ind2ctr++) {
ind2ptr=&((ufs_daddr_t *)&i2blk)[ind2ctr]; ind2ptr=&((ufs_daddr_t *)&i2blk)[ind2ctr];
@ -479,7 +500,10 @@ dump_whole_inode(ino_t inode, int fsi, int level)
i1blk, fsi); i1blk, fsi);
snprintf(comment, 80, "Inode 0x%08x: indirect 1->%d", snprintf(comment, 80, "Inode 0x%08x: indirect 1->%d",
inode, ind2ctr); inode, ind2ctr);
DBG_DUMP_IBLK(&sblock, comment, i1blk, (size_t)rb); DBG_DUMP_IBLK(&sblock,
comment,
i1blk,
(size_t)rb);
rb-=howmany(sblock.fs_bsize, sizeof(ufs_daddr_t)); rb-=howmany(sblock.fs_bsize, sizeof(ufs_daddr_t));
} }
} }
@ -491,8 +515,11 @@ dump_whole_inode(ino_t inode, int fsi, int level)
fsi); fsi);
snprintf(comment, 80, "Inode 0x%08x: indirect 2", inode); snprintf(comment, 80, "Inode 0x%08x: indirect 2", inode);
#define SQUARE(a) ((a)*(a)) #define SQUARE(a) ((a)*(a))
DBG_DUMP_IBLK(&sblock, comment, i3blk, howmany(rb, DBG_DUMP_IBLK(&sblock,
SQUARE(howmany(sblock.fs_bsize, sizeof(ufs_daddr_t))))); comment,
i3blk,
howmany(rb,
SQUARE(howmany(sblock.fs_bsize, sizeof(ufs_daddr_t)))));
#undef SQUARE #undef SQUARE
for(ind3ctr=0; ((ind3ctr < howmany(sblock.fs_bsize, for(ind3ctr=0; ((ind3ctr < howmany(sblock.fs_bsize,
sizeof(ufs_daddr_t)))&&(rb>0)); ind3ctr ++) { sizeof(ufs_daddr_t)))&&(rb>0)); ind3ctr ++) {
@ -502,8 +529,11 @@ dump_whole_inode(ino_t inode, int fsi, int level)
i2blk, fsi); i2blk, fsi);
snprintf(comment, 80, "Inode 0x%08x: indirect 2->%d", snprintf(comment, 80, "Inode 0x%08x: indirect 2->%d",
inode, ind3ctr); inode, ind3ctr);
DBG_DUMP_IBLK(&sblock, comment, i2blk, howmany(rb, DBG_DUMP_IBLK(&sblock,
howmany(sblock.fs_bsize, sizeof(ufs_daddr_t)))); comment,
i2blk,
howmany(rb,
howmany(sblock.fs_bsize, sizeof(ufs_daddr_t))));
for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize, for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize,
sizeof(ufs_daddr_t)))&&(rb>0)); ind2ctr ++) { sizeof(ufs_daddr_t)))&&(rb>0)); ind2ctr ++) {
ind2ptr=&((ufs_daddr_t *)&i2blk)[ind2ctr]; ind2ptr=&((ufs_daddr_t *)&i2blk)[ind2ctr];
@ -513,7 +543,10 @@ dump_whole_inode(ino_t inode, int fsi, int level)
snprintf(comment, 80, snprintf(comment, 80,
"Inode 0x%08x: indirect 2->%d->%d", inode, "Inode 0x%08x: indirect 2->%d->%d", inode,
ind3ctr, ind3ctr); ind3ctr, ind3ctr);
DBG_DUMP_IBLK(&sblock, comment, i1blk, (size_t)rb); DBG_DUMP_IBLK(&sblock,
comment,
i1blk,
(size_t)rb);
rb-=howmany(sblock.fs_bsize, rb-=howmany(sblock.fs_bsize,
sizeof(ufs_daddr_t)); sizeof(ufs_daddr_t));
} }
@ -538,11 +571,10 @@ get_disklabel(int fd)
lab=(struct disklabel *)malloc(sizeof(struct disklabel)); lab=(struct disklabel *)malloc(sizeof(struct disklabel));
if (!lab) { if (!lab) {
fprintf(stderr, "malloc failed\n"); errx(1, "malloc failed");
exit(-1);
} }
if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) { if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) {
fprintf(stderr, "DIOCGDINFO failed\n"); errx(1, "DIOCGDINFO failed");
exit(-1); exit(-1);
} }
@ -556,26 +588,19 @@ get_disklabel(int fd)
* Dump a line of usage. * Dump a line of usage.
*/ */
void void
usage(char *name) usage(void)
{ {
DBG_FUNC("usage") DBG_FUNC("usage")
char *basename;
DBG_ENTER; DBG_ENTER;
basename=strrchr(name, '/');
if(!basename) {
basename=name;
} else {
basename++;
}
fprintf(stderr, fprintf(stderr,
"usage:\t%s\t[-L] [-g cylgrp] [-i inode] [-l level] [-o outfile]\n" "usage: ffsinfo [-L] [-g cylgrp] [-i inode] [-l level] "
"\t\t< special | file >\n", "[-o outfile]\n"
basename); " special | file\n");
DBG_LEAVE; DBG_LEAVE;
exit(-1); exit(1);
} }
/* ************************************************************ ginode ***** */ /* ************************************************************ ginode ***** */
@ -583,7 +608,7 @@ usage(char *name)
* This function provides access to an individual inode. We find out in which * This function provides access to an individual inode. We find out in which
* block the requested inode is located, read it from disk if needed, and * block the requested inode is located, read it from disk if needed, and
* return the pointer into that block. We maintain a cache of one block to * return the pointer into that block. We maintain a cache of one block to
* not read the same block again and again if we iterate lineary over all * not read the same block again and again if we iterate linearly over all
* inodes. * inodes.
*/ */
struct dinode * struct dinode *

View File

@ -35,14 +35,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $TSHeader: src/sbin/growfs/debug.c,v 1.2 2000/11/16 18:43:49 tom Exp $ * $TSHeader: src/sbin/growfs/debug.c,v 1.3 2000/12/12 19:31:00 tomsoft Exp $
* $FreeBSD$ * $FreeBSD$
* *
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] = static const char rcsid[] =
"$TSHeader: src/sbin/growfs/debug.c,v 1.2 2000/11/16 18:43:49 tom Exp $"; "$FreeBSD$";
#endif /* not lint */ #endif /* not lint */
/* ********************************************************** INCLUDES ***** */ /* ********************************************************** INCLUDES ***** */

View File

@ -34,7 +34,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" $TSHeader: src/sbin/growfs/growfs.8,v 1.2 2000/12/09 15:12:33 tomsoft Exp $ .\" $TSHeader: src/sbin/growfs/growfs.8,v 1.3 2000/12/12 19:31:00 tomsoft Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd September 8, 2000 .Dd September 8, 2000
@ -49,7 +49,7 @@
.Op Fl s Ar size .Op Fl s Ar size
.Ar special .Ar special
.Sh DESCRIPTION .Sh DESCRIPTION
.Nm Growfs .Nm
extends the extends the
.Xr newfs 8 .Xr newfs 8
program. program.
@ -59,38 +59,43 @@ the disk must be labeled to a bigger size using
.Xr disklabel 8 . .Xr disklabel 8 .
If you are using volumes you must grow them using If you are using volumes you must grow them using
.Xr vinum 8 . .Xr vinum 8 .
.Nm Growfs .Nm
extends the size of the file system on the specified special file. extends the size of the file system on the specified special file.
Currently Currently
.Nm .Nm
can only grow unmounted file systems. Do not try growing an mounted file system, can only grow unmounted file systems.
your system may panic and you will not be able to use the file system any longer. Do not try growing a mounted file system, your system may panic and you will
not be able to use the file system any longer.
Most of the options you have used with Most of the options you have used with
.Xr newfs 8 .Xr newfs 8
once can not be changed. In fact you can only increase the size of the file once can not be changed.
system. Use In fact you can only increase the size of the file system.
Use
.Xr tunefs 8 .Xr tunefs 8
for other changes. for other changes.
Typically the defaults are reasonable, however .Pp
.Nm The following options are available:
has some options to allow the defaults to be overridden.
.\".Pp .\".Pp
.Bl -tag -width indent .Bl -tag -width indent
.It Fl N .It Fl N
Cause the new file system parameters to be printed out Cause the new file system parameters to be printed out without actually growing
without realy growing the file system. the file system.
.It Fl y .It Fl y
.Dq Expert mode .Dq Expert mode
Normally Normally
.Nm .Nm
will ask you, if you took a backup of your data before und will do some tests will ask you, if you took a backup of your data before and will do some tests
if if
.Ar special .Ar special
is currently mounted or if there are any active snapshots on the filesystem is currently mounted or if there are any active snapshots on the filesystem
specified. This will be supressed. So use this option with care! specified.
This will be supressed.
So use this option with great care!
.It Fl s Ar size .It Fl s Ar size
The size of the file system after growing in sectors. This value defaults The
to the size of the raw partition specified in .Ar size
of the file system after growing in sectors.
This value defaults to the size of the raw partition specified in
.Ar special .Ar special
(in other words, (in other words,
.Nm .Nm
@ -100,8 +105,10 @@ will grow the file system to the size of the entire partition).
.Pp .Pp
.Dl growfs -s 4194304 /dev/vinum/testvol .Dl growfs -s 4194304 /dev/vinum/testvol
.Pp .Pp
will grow /dev/vinum/testvol up to 2GB if there is enough space in will grow
/dev/vinum/testvol . .Pa /dev/vinum/testvol
up to 2GB if there is enough space in
.Pa /dev/vinum/testvol .
.Sh BUGS .Sh BUGS
In some cases on In some cases on
.Bx Free .Bx Free
@ -110,27 +117,31 @@ In some cases on
did not recognize exactly, if the file system is mounted or not and did not recognize exactly, if the file system is mounted or not and
exits with an error message, then use exits with an error message, then use
.Nm .Nm
-y if you are sure, that the file system is not mounted. .Fl y
if you are sure, that the file system is not mounted.
It is also recommended to always use It is also recommended to always use
.Nm fsck .Xr fsck 8
after growing just to be on the safe side. after growing just to be on the safe side.
.Pp .Pp
Pay attention, as in certain cases we have to change the location of an file Pay attention, as in certain cases we have to change the location of an file
system internal structure which had never been moved before. Almost everything system internal structure which had never been moved before.
works perfect with this relocated structure except the Almost everything works perfect with this relocated structure except the
.Nm fsck(8) .Xr fsck 8
utility. There is a patch available for utility.
.Nm fsck(8) . There is a patch available for
.Xr fsck 8 ) .
For growing above certain limits it is essential to have some free blocks For growing above certain limits it is essential to have some free blocks
available in the first cylinder group. To avoid the relocation of that available in the first cylinder group.
structure it is currently recommended to use To avoid the relocation of that structure it is currently recommended to use
.Nm ffsinfo -c 0 .Nm
.Fl c Ar 0
on the first cylinder group and check that on the first cylinder group and check that
.Nm nbfree .Em nbfree
in the CYLINDER SUMMARY (internal cs) of the CYLINDER GROUP in the CYLINDER SUMMARY (internal cs) of the CYLINDER GROUP
.Nm cgr0 .Em cgr0
has enough blocks. As a rule of thumb for default filesystem parameters a block has enough blocks.
is needed for every 2 GB of total filesystem size. As a rule of thumb for default filesystem parameters a block is needed for
every 2 GB of total filesystem size.
.Pp .Pp
.Sh SEE ALSO .Sh SEE ALSO
.Xr vinum 8 , .Xr vinum 8 ,

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $TSHeader: src/sbin/growfs/growfs.c,v 1.4 2000/12/09 15:12:33 tomsoft Exp $ * $TSHeader: src/sbin/growfs/growfs.c,v 1.5 2000/12/12 19:31:00 tomsoft Exp $
* $FreeBSD$ * $FreeBSD$
* *
*/ */
@ -49,7 +49,7 @@ All rights reserved.\n";
#ifndef lint #ifndef lint
static const char rcsid[] = static const char rcsid[] =
"$FreeBSD$"; "$FreeBSD$";
#endif /* not lint */ #endif /* not lint */
/* ********************************************************** INCLUDES ***** */ /* ********************************************************** INCLUDES ***** */
@ -57,20 +57,17 @@ static const char rcsid[] =
#include <sys/disklabel.h> #include <sys/disklabel.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h>
#include <stdio.h> #include <stdio.h>
#include <paths.h> #include <paths.h>
#include <ctype.h> #include <ctype.h>
#include <err.h> #include <err.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <ufs/ufs/dinode.h> #include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h> #include <ufs/ffs/fs.h>
#include <machine/param.h>
#include "debug.h" #include "debug.h"
@ -132,7 +129,7 @@ static void rdfs(daddr_t, int, char *, int);
static void wtfs(daddr_t, int, char *, int, int); static void wtfs(daddr_t, int, char *, int, int);
static daddr_t alloc(void); static daddr_t alloc(void);
static int charsperline(void); static int charsperline(void);
static void usage(char *); static void usage(void);
static int isblock(struct fs *, unsigned char *, int); static int isblock(struct fs *, unsigned char *, int);
static void clrblock(struct fs *, unsigned char *, int); static void clrblock(struct fs *, unsigned char *, int);
static void setblock(struct fs *, unsigned char *, int); static void setblock(struct fs *, unsigned char *, int);
@ -151,7 +148,7 @@ static void updrefs(int, ino_t, struct gfs_bpp *, int, int, int);
/* ************************************************************ growfs ***** */ /* ************************************************************ growfs ***** */
/* /*
* Here we actually start growing the filesystem. We basically read the * Here we actually start growing the filesystem. We basically read the
* cylinder summary from the first cylinder group as we wan't to update * cylinder summary from the first cylinder group as we want to update
* this on the fly during our various operations. First we handle the * this on the fly during our various operations. First we handle the
* changes in the former last cylinder group. Afterwards we create all new * changes in the former last cylinder group. Afterwards we create all new
* cylinder groups. Now we handle the cylinder group containing the * cylinder groups. Now we handle the cylinder group containing the
@ -189,6 +186,9 @@ growfs(int fsi, int fso, int Nflag)
* Get the cylinder summary into the memory. * Get the cylinder summary into the memory.
*/ */
fscs = (struct csum *)calloc(1, (size_t)sblock.fs_cssize); fscs = (struct csum *)calloc(1, (size_t)sblock.fs_cssize);
if(fscs == NULL) {
errx(1, "calloc failed");
}
for (i = 0; i < osblock.fs_cssize; i += osblock.fs_bsize) { for (i = 0; i < osblock.fs_cssize; i += osblock.fs_bsize) {
rdfs(fsbtodb(&osblock, osblock.fs_csaddr + rdfs(fsbtodb(&osblock, osblock.fs_csaddr +
numfrags(&osblock, i)), MIN(osblock.fs_cssize - i, numfrags(&osblock, i)), MIN(osblock.fs_cssize - i,
@ -204,7 +204,9 @@ growfs(int fsi, int fso, int Nflag)
dbg_csp=fscs; dbg_csp=fscs;
for(dbg_csc=0; dbg_csc<osblock.fs_ncg; dbg_csc++) { for(dbg_csc=0; dbg_csc<osblock.fs_ncg; dbg_csc++) {
snprintf(dbg_line, 80, "%d. old csum in old location", dbg_csc); snprintf(dbg_line, 80, "%d. old csum in old location", dbg_csc);
DBG_DUMP_CSUM(&osblock, dbg_line, dbg_csp++); DBG_DUMP_CSUM(&osblock,
dbg_line,
dbg_csp++);
} }
} }
#endif /* FS_DEBUG */ #endif /* FS_DEBUG */
@ -280,7 +282,9 @@ growfs(int fsi, int fso, int Nflag)
dbg_csp=fscs; dbg_csp=fscs;
for(dbg_csc=0; dbg_csc<sblock.fs_ncg; dbg_csc++) { for(dbg_csc=0; dbg_csc<sblock.fs_ncg; dbg_csc++) {
snprintf(dbg_line, 80, "%d. new csum in new location", dbg_csc); snprintf(dbg_line, 80, "%d. new csum in new location", dbg_csc);
DBG_DUMP_CSUM(&sblock, dbg_line, dbg_csp++); DBG_DUMP_CSUM(&sblock,
dbg_line,
dbg_csp++);
} }
} }
#endif /* FS_DEBUG */ #endif /* FS_DEBUG */
@ -291,7 +295,8 @@ growfs(int fsi, int fso, int Nflag)
sblock.fs_time = utime; sblock.fs_time = utime;
wtfs((int)SBOFF / DEV_BSIZE, SBSIZE, (char *)&sblock, fso, Nflag); wtfs((int)SBOFF / DEV_BSIZE, SBSIZE, (char *)&sblock, fso, Nflag);
DBG_PRINT0("sblock written\n"); DBG_PRINT0("sblock written\n");
DBG_DUMP_FS(&sblock, "new initial sblock"); DBG_DUMP_FS(&sblock,
"new initial sblock");
/* /*
* Clean up the dynamic fields in our superblock copies. * Clean up the dynamic fields in our superblock copies.
@ -333,7 +338,8 @@ growfs(int fsi, int fso, int Nflag)
SBSIZE, (char *)&sblock, fso, Nflag); SBSIZE, (char *)&sblock, fso, Nflag);
} }
DBG_PRINT0("sblock copies written\n"); DBG_PRINT0("sblock copies written\n");
DBG_DUMP_FS(&sblock, "new other sblocks"); DBG_DUMP_FS(&sblock,
"new other sblocks");
DBG_LEAVE; DBG_LEAVE;
return; return;
@ -411,8 +417,7 @@ initcg(int cylno, time_t utime, int fso, int Nflag)
* XXX This should never happen as we would have had that panic * XXX This should never happen as we would have had that panic
* already on filesystem creation * already on filesystem creation
*/ */
fprintf(stderr, "Panic: cylinder group too big\n"); errx(37, "panic: cylinder group too big");
exit(37);
} }
acg.cg_cs.cs_nifree += sblock.fs_ipg; acg.cg_cs.cs_nifree += sblock.fs_ipg;
if (cylno == 0) if (cylno == 0)
@ -506,7 +511,9 @@ initcg(int cylno, time_t utime, int fso, int Nflag)
*cs = acg.cg_cs; *cs = acg.cg_cs;
wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
sblock.fs_bsize, (char *)&acg, fso, Nflag); sblock.fs_bsize, (char *)&acg, fso, Nflag);
DBG_DUMP_CG(&sblock, "new cg", &acg); DBG_DUMP_CG(&sblock,
"new cg",
&acg);
DBG_LEAVE; DBG_LEAVE;
return; return;
@ -547,7 +554,9 @@ frag_adjust(daddr_t frag, int sign)
* We found something in between. * We found something in between.
*/ */
acg.cg_frsum[fragsize]+=sign; acg.cg_frsum[fragsize]+=sign;
DBG_PRINT2("frag_adjust [%d]+=%d\n", fragsize, sign); DBG_PRINT2("frag_adjust [%d]+=%d\n",
fragsize,
sign);
} }
fragsize=0; fragsize=0;
} }
@ -557,9 +566,13 @@ frag_adjust(daddr_t frag, int sign)
* We found something. * We found something.
*/ */
acg.cg_frsum[fragsize]+=sign; acg.cg_frsum[fragsize]+=sign;
DBG_PRINT2("frag_adjust [%d]+=%d\n", fragsize, sign); DBG_PRINT2("frag_adjust [%d]+=%d\n",
fragsize,
sign);
} }
DBG_PRINT2("frag_adjust [[%d]]+=%d\n", fragsize, sign); DBG_PRINT2("frag_adjust [[%d]]+=%d\n",
fragsize,
sign);
DBG_LEAVE; DBG_LEAVE;
return; return;
@ -593,7 +606,10 @@ cond_bl_upd(ufs_daddr_t *block, struct gfs_bpp *field,
*/ */
*block=(f->new*sblock.fs_frag+(*block%sblock.fs_frag)); *block=(f->new*sblock.fs_frag+(*block%sblock.fs_frag));
f->found++; f->found++;
DBG_PRINT3("scg (%d->%d)[%d] reference updated\n", f->old, f->new, *block%sblock.fs_frag); DBG_PRINT3("scg (%d->%d)[%d] reference updated\n",
f->old,
f->new,
*block%sblock.fs_frag);
/* Write the block back to disk immediately */ /* Write the block back to disk immediately */
switch (source) { switch (source) {
@ -668,7 +684,9 @@ updjcg(int cylno, time_t utime, int fsi, int fso, int Nflag)
rdfs(fsbtodb(&osblock, cgtod(&osblock, cylno)), osblock.fs_cgsize, rdfs(fsbtodb(&osblock, cgtod(&osblock, cylno)), osblock.fs_cgsize,
(char *)&aocg, fsi); (char *)&aocg, fsi);
DBG_PRINT0("jcg read\n"); DBG_PRINT0("jcg read\n");
DBG_DUMP_CG(&sblock, "old joining cg", &aocg); DBG_DUMP_CG(&sblock,
"old joining cg",
&aocg);
memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2)); memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
@ -686,7 +704,9 @@ updjcg(int cylno, time_t utime, int fsi, int fso, int Nflag)
wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize,
(char *)&acg, fso, Nflag); (char *)&acg, fso, Nflag);
DBG_PRINT0("jcg written\n"); DBG_PRINT0("jcg written\n");
DBG_DUMP_CG(&sblock, "new joining cg", &acg); DBG_DUMP_CG(&sblock,
"new joining cg",
&acg);
DBG_LEAVE; DBG_LEAVE;
return; return;
@ -722,7 +742,11 @@ updjcg(int cylno, time_t utime, int fsi, int fso, int Nflag)
} else { } else {
acg.cg_ncyl = sblock.fs_cpg; acg.cg_ncyl = sblock.fs_cpg;
} }
DBG_PRINT4("jcg dbg: %d %u %d %u\n", cylno, sblock.fs_ncg, acg.cg_ncyl, sblock.fs_cpg); DBG_PRINT4("jcg dbg: %d %u %d %u\n",
cylno,
sblock.fs_ncg,
acg.cg_ncyl,
sblock.fs_cpg);
acg.cg_ndblk = dmax - cbase; acg.cg_ndblk = dmax - cbase;
sblock.fs_dsize += acg.cg_ndblk-aocg.cg_ndblk; sblock.fs_dsize += acg.cg_ndblk-aocg.cg_ndblk;
if (sblock.fs_contigsumsize > 0) { if (sblock.fs_contigsumsize > 0) {
@ -870,7 +894,9 @@ updjcg(int cylno, time_t utime, int fsi, int fso, int Nflag)
wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize, wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize,
(char *)&acg, fso, Nflag); (char *)&acg, fso, Nflag);
DBG_PRINT0("jcg written\n"); DBG_PRINT0("jcg written\n");
DBG_DUMP_CG(&sblock, "new joining cg", &acg); DBG_DUMP_CG(&sblock,
"new joining cg",
&acg);
DBG_LEAVE; DBG_LEAVE;
return; return;
@ -929,7 +955,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)), osblock.fs_cgsize, rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)), osblock.fs_cgsize,
(char *)&aocg, fsi); (char *)&aocg, fsi);
DBG_PRINT0("oscg read\n"); DBG_PRINT0("oscg read\n");
DBG_DUMP_CG(&sblock, "old summary cg", &aocg); DBG_DUMP_CG(&sblock,
"old summary cg",
&aocg);
memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2)); memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
@ -967,8 +995,7 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
*/ */
DBG_TRC; DBG_TRC;
if(sblock.fs_ncg-osblock.fs_ncg < 2) { if(sblock.fs_ncg-osblock.fs_ncg < 2) {
fprintf(stderr, "growfs: panic, not enough space\n"); errx(2, "panic: not enough space");
exit(2);
} }
/* /*
@ -997,7 +1024,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
*/ */
d--; d--;
DBG_PRINT1("d=%d\n",d); DBG_PRINT1("d=%d\n",
d);
if((d+1)%sblock.fs_frag) { if((d+1)%sblock.fs_frag) {
/* /*
* The end of the cylinder summary is not a complete * The end of the cylinder summary is not a complete
@ -1006,7 +1034,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
DBG_TRC; DBG_TRC;
frag_adjust(d%sblock.fs_fpg, -1); frag_adjust(d%sblock.fs_fpg, -1);
for(; (d+1)%sblock.fs_frag; d--) { for(; (d+1)%sblock.fs_frag; d--) {
DBG_PRINT1("d=%d\n",d); DBG_PRINT1("d=%d\n",
d);
setbit(cg_blksfree(&acg), d%sblock.fs_fpg); setbit(cg_blksfree(&acg), d%sblock.fs_fpg);
acg.cg_cs.cs_nffree++; acg.cg_cs.cs_nffree++;
sblock.fs_cstotal.cs_nffree++; sblock.fs_cstotal.cs_nffree++;
@ -1020,7 +1049,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
if(isblock(&sblock, cg_blksfree(&acg), if(isblock(&sblock, cg_blksfree(&acg),
(d%sblock.fs_fpg)/sblock.fs_frag)) { (d%sblock.fs_fpg)/sblock.fs_frag)) {
DBG_PRINT1("d=%d\n",d); DBG_PRINT1("d=%d\n",
d);
acg.cg_cs.cs_nffree-=sblock.fs_frag; acg.cg_cs.cs_nffree-=sblock.fs_frag;
acg.cg_cs.cs_nbfree++; acg.cg_cs.cs_nbfree++;
sblock.fs_cstotal.cs_nffree-=sblock.fs_frag; sblock.fs_cstotal.cs_nffree-=sblock.fs_frag;
@ -1050,11 +1080,13 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
d--; d--;
} }
DBG_PRINT1("d=%d\n",d); DBG_PRINT1("d=%d\n",
d);
for(d=rounddown(d, sblock.fs_frag); d >= osblock.fs_csaddr; for(d=rounddown(d, sblock.fs_frag); d >= osblock.fs_csaddr;
d-=sblock.fs_frag) { d-=sblock.fs_frag) {
DBG_TRC; DBG_TRC;
DBG_PRINT1("d=%d\n",d); DBG_PRINT1("d=%d\n",
d);
setblock(&sblock, cg_blksfree(&acg), setblock(&sblock, cg_blksfree(&acg),
(d%sblock.fs_fpg)/sblock.fs_frag); (d%sblock.fs_fpg)/sblock.fs_frag);
acg.cg_cs.cs_nbfree++; acg.cg_cs.cs_nbfree++;
@ -1087,7 +1119,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), sblock.fs_cgsize, wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), sblock.fs_cgsize,
(char *)&acg, fso, Nflag); (char *)&acg, fso, Nflag);
DBG_PRINT0("oscg written\n"); DBG_PRINT0("oscg written\n");
DBG_DUMP_CG(&sblock, "old summary cg", &acg); DBG_DUMP_CG(&sblock,
"old summary cg",
&acg);
/* /*
* Find the beginning of the new cylinder group containing the * Find the beginning of the new cylinder group containing the
@ -1104,7 +1138,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
sblock.fs_cgsize, (char *)&aocg, fsi); sblock.fs_cgsize, (char *)&aocg, fsi);
DBG_PRINT0("nscg read\n"); DBG_PRINT0("nscg read\n");
DBG_DUMP_CG(&sblock, "new summary cg", &aocg); DBG_DUMP_CG(&sblock,
"new summary cg",
&aocg);
memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2)); memcpy((void *)&cgun1, (void *)&cgun2, sizeof(cgun2));
@ -1178,7 +1214,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), sblock.fs_cgsize, wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), sblock.fs_cgsize,
(char *)&acg, fso, Nflag); (char *)&acg, fso, Nflag);
DBG_PRINT0("nscg written\n"); DBG_PRINT0("nscg written\n");
DBG_DUMP_CG(&sblock, "new summary cg", &acg); DBG_DUMP_CG(&sblock,
"new summary cg",
&acg);
DBG_LEAVE; DBG_LEAVE;
return; return;
@ -1203,6 +1241,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
*/ */
bp=(struct gfs_bpp *)malloc(((dupper-odupper)/sblock.fs_frag+2)* bp=(struct gfs_bpp *)malloc(((dupper-odupper)/sblock.fs_frag+2)*
sizeof(struct gfs_bpp)); sizeof(struct gfs_bpp));
if(bp == NULL) {
errx(1, "malloc failed");
}
memset((char *)bp, 0, sizeof(struct gfs_bpp)); memset((char *)bp, 0, sizeof(struct gfs_bpp));
/* /*
@ -1216,7 +1257,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
ind=0; ind=0;
frag_adjust(odupper, -1); frag_adjust(odupper, -1);
for(d=odupper; ((d<dupper)&&(d%sblock.fs_frag)); d++) { for(d=odupper; ((d<dupper)&&(d%sblock.fs_frag)); d++) {
DBG_PRINT1("scg first frag check loop d=%d\n", d); DBG_PRINT1("scg first frag check loop d=%d\n",
d);
if(isclr(cg_blksfree(&acg), d)) { if(isclr(cg_blksfree(&acg), d)) {
if (!ind) { if (!ind) {
bp[ind].old=d/sblock.fs_frag; bp[ind].old=d/sblock.fs_frag;
@ -1245,7 +1287,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
* Handle all needed complete blocks here. * Handle all needed complete blocks here.
*/ */
for(; d+sblock.fs_frag<=dupper; d+=sblock.fs_frag) { for(; d+sblock.fs_frag<=dupper; d+=sblock.fs_frag) {
DBG_PRINT1("scg block check loop d=%d\n", d); DBG_PRINT1("scg block check loop d=%d\n",
d);
if(!isblock(&sblock, cg_blksfree(&acg), d/sblock.fs_frag)) { if(!isblock(&sblock, cg_blksfree(&acg), d/sblock.fs_frag)) {
for(f=d; f<d+sblock.fs_frag; f++) { for(f=d; f<d+sblock.fs_frag; f++) {
if(isset(cg_blksfree(&aocg), f)) { if(isset(cg_blksfree(&aocg), f)) {
@ -1319,7 +1362,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
} }
for(; d<dupper; d++) { for(; d<dupper; d++) {
DBG_PRINT1("scg second frag check loop d=%d\n", d); DBG_PRINT1("scg second frag check loop d=%d\n",
d);
if(isclr(cg_blksfree(&acg), d)) { if(isclr(cg_blksfree(&acg), d)) {
bp[ind].old=d/sblock.fs_frag; bp[ind].old=d/sblock.fs_frag;
bp[ind].flags|=GFS_FL_LAST; bp[ind].flags|=GFS_FL_LAST;
@ -1428,9 +1472,13 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
sblock.fs_bsize, (char *)&ablk, fsi); sblock.fs_bsize, (char *)&ablk, fsi);
wtfs(fsbtodb(&sblock, bp[i].new*sblock.fs_frag), wtfs(fsbtodb(&sblock, bp[i].new*sblock.fs_frag),
sblock.fs_bsize, (char *)&ablk, fso, Nflag); sblock.fs_bsize, (char *)&ablk, fso, Nflag);
DBG_DUMP_HEX(&sblock, "copied full block", (unsigned char *)&ablk); DBG_DUMP_HEX(&sblock,
"copied full block",
(unsigned char *)&ablk);
DBG_PRINT2("scg (%d->%d) block relocated\n", bp[i].old, bp[i].new); DBG_PRINT2("scg (%d->%d) block relocated\n",
bp[i].old,
bp[i].new);
} }
/* /*
@ -1440,7 +1488,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
* inodes. * inodes.
*/ */
for(cylno=0; cylno<osblock.fs_ncg; cylno++) { for(cylno=0; cylno<osblock.fs_ncg; cylno++) {
DBG_PRINT1("scg doing cg (%d)\n", cylno); DBG_PRINT1("scg doing cg (%d)\n",
cylno);
for(inc=osblock.fs_ipg-1 ; inc>=0 ; inc--) { for(inc=osblock.fs_ipg-1 ; inc>=0 ; inc--) {
updrefs(cylno, (ino_t)inc, bp, fsi, fso, Nflag); updrefs(cylno, (ino_t)inc, bp, fsi, fso, Nflag);
} }
@ -1452,8 +1501,7 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
*/ */
for(i=0; i<ind; i++) { for(i=0; i<ind; i++) {
if(!bp[i].found || (bp[i].found>sblock.fs_frag)) { if(!bp[i].found || (bp[i].found>sblock.fs_frag)) {
fprintf(stderr, warnx("error: %d refs found for block %d.",
"error: %d refs found for block %d.\n",
bp[i].found, bp[i].old); bp[i].found, bp[i].old);
} }
@ -1478,7 +1526,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), sblock.fs_cgsize, wtfs(fsbtodb(&sblock, cgtod(&sblock, ocscg)), sblock.fs_cgsize,
(char *)&acg, fso, Nflag); (char *)&acg, fso, Nflag);
DBG_PRINT0("scg written\n"); DBG_PRINT0("scg written\n");
DBG_DUMP_CG(&sblock, "new summary cg", &acg); DBG_DUMP_CG(&sblock,
"new summary cg",
&acg);
DBG_LEAVE; DBG_LEAVE;
return; return;
@ -1497,13 +1547,11 @@ rdfs(daddr_t bno, int size, char *bf, int fsi)
DBG_ENTER; DBG_ENTER;
if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) { if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) {
fprintf(stderr, "seek error: %ld\n", (long)bno); err(33, "rdfs: seek error: %ld", (long)bno);
err(33, "rdfs");
} }
n = read(fsi, bf, (size_t)size); n = read(fsi, bf, (size_t)size);
if (n != size) { if (n != size) {
fprintf(stderr, "read error: %ld\n", (long)bno); err(34, "rdfs: read error: %ld", (long)bno);
err(34, "rdfs");
} }
DBG_LEAVE; DBG_LEAVE;
@ -1527,13 +1575,11 @@ wtfs(daddr_t bno, int size, char *bf, int fso, int Nflag)
return; return;
} }
if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0) { if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0) {
fprintf(stderr, "seek error: %ld\n", (long)bno); err(35, "wtfs: seek error: %ld", (long)bno);
err(35, "wtfs");
} }
n = write(fso, bf, (size_t)size); n = write(fso, bf, (size_t)size);
if (n != size) { if (n != size) {
fprintf(stderr, "write error: %ld\n", (long)bno); err(36, "wtfs: write error: %ld", (long)bno);
err(36, "wtfs");
} }
DBG_LEAVE; DBG_LEAVE;
@ -1559,12 +1605,12 @@ alloc(void)
DBG_ENTER; DBG_ENTER;
if (acg.cg_magic != CG_MAGIC) { if (acg.cg_magic != CG_MAGIC) {
fprintf(stderr, "acg: bad magic number\n"); warnx("acg: bad magic number");
DBG_LEAVE; DBG_LEAVE;
return (0); return (0);
} }
if (acg.cg_cs.cs_nbfree == 0) { if (acg.cg_cs.cs_nbfree == 0) {
fprintf(stderr, "error: cylinder group ran out of space\n"); warnx("error: cylinder group ran out of space");
DBG_LEAVE; DBG_LEAVE;
return (0); return (0);
} }
@ -1584,8 +1630,13 @@ alloc(void)
dmax-=cgbase(&sblock, acg.cg_cgx); /* retransform into cg */ dmax-=cgbase(&sblock, acg.cg_cgx); /* retransform into cg */
csmin=sblock.fs_csaddr-cgbase(&sblock, acg.cg_cgx); csmin=sblock.fs_csaddr-cgbase(&sblock, acg.cg_cgx);
csmax=csmin+howmany(sblock.fs_cssize, sblock.fs_fsize); csmax=csmin+howmany(sblock.fs_cssize, sblock.fs_fsize);
DBG_PRINT3("seek range: dl=%d, du=%d, dm=%d\n", dlower, dupper, dmax); DBG_PRINT3("seek range: dl=%d, du=%d, dm=%d\n",
DBG_PRINT2("range cont: csmin=%d, csmax=%d\n", csmin, csmax); dlower,
dupper,
dmax);
DBG_PRINT2("range cont: csmin=%d, csmax=%d\n",
csmin,
csmax);
for(d=0; (d<dlower && blkno==-1); d+=sblock.fs_frag) { for(d=0; (d<dlower && blkno==-1); d+=sblock.fs_frag) {
if(d>=csmin && d<=csmax) { if(d>=csmin && d<=csmax) {
@ -1608,8 +1659,7 @@ alloc(void)
} }
} }
if(blkno==-1) { if(blkno==-1) {
fprintf(stderr, warnx("internal error: couldn't find promised block in cg");
"internal error: couldn't find promised block in cg\n");
DBG_LEAVE; DBG_LEAVE;
return (0); return (0);
} }
@ -1627,7 +1677,7 @@ alloc(void)
clrbit(cg_clustersfree(&acg), blkno); clrbit(cg_clustersfree(&acg), blkno);
/* /*
* We possibly have split a cluster here, so we have to do * We possibly have split a cluster here, so we have to do
* recalculate the sizes of the remaining cluster halfes now, * recalculate the sizes of the remaining cluster halves now,
* and use them for updating the cluster summary information. * and use them for updating the cluster summary information.
* *
* Lets start with the blocks before our allocated block ... * Lets start with the blocks before our allocated block ...
@ -1736,7 +1786,7 @@ clrblock(struct fs *fs, unsigned char *cp, int h)
cp[h >> 3] &= ~(0x01 << (h & 0x7)); cp[h >> 3] &= ~(0x01 << (h & 0x7));
break; break;
default: default:
fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); warnx("clrblock bad fs_frag %d", fs->fs_frag);
break; break;
} }
@ -1771,7 +1821,7 @@ setblock(struct fs *fs, unsigned char *cp, int h)
cp[h >> 3] |= (0x01 << (h & 0x7)); cp[h >> 3] |= (0x01 << (h & 0x7));
break; break;
default: default:
fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); warnx("setblock bad fs_frag %d", fs->fs_frag);
break; break;
} }
@ -1784,7 +1834,7 @@ setblock(struct fs *fs, unsigned char *cp, int h)
* This function provides access to an individual inode. We find out in which * This function provides access to an individual inode. We find out in which
* block the requested inode is located, read it from disk if needed, and * block the requested inode is located, read it from disk if needed, and
* return the pointer into that block. We maintain a cache of one block to * return the pointer into that block. We maintain a cache of one block to
* not read the same block again and again if we iterate lineary over all * not read the same block again and again if we iterate linearly over all
* inodes. * inodes.
*/ */
static struct dinode * static struct dinode *
@ -1859,21 +1909,21 @@ charsperline(void)
* We still have to provide support for snapshots. Therefore we first have to * We still have to provide support for snapshots. Therefore we first have to
* understand what data structures are always replicated in the snapshot on * understand what data structures are always replicated in the snapshot on
* creation, for all other blocks we touch during our procedure, we have to * creation, for all other blocks we touch during our procedure, we have to
* keep the old blocks unchanged somewere available for the snapshots. If we * keep the old blocks unchanged somewhere available for the snapshots. If we
* are lucky, then we only have to handle our blocks to be relocated in that * are lucky, then we only have to handle our blocks to be relocated in that
* way. * way.
* Also we have to consider in what order we actually update the critical * Also we have to consider in what order we actually update the critical
* data structures of the filesystem to make sure, that in case of a desaster * data structures of the filesystem to make sure, that in case of a disaster
* fsck(8) is still able to restore any lost data. * fsck(8) is still able to restore any lost data.
* The forseen last step then will be to provide for growing even mounted * The foreseen last step then will be to provide for growing even mounted
* file systems. There we have to extend the mount() systemcall to provide * file systems. There we have to extend the mount() system call to provide
* userland access to the file system locking facility. * userland access to the file system locking facility.
*/ */
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
DBG_FUNC("main") DBG_FUNC("main")
char *a0, *device, *special, *cp; char *device, *special, *cp;
char ch; char ch;
unsigned long size=0; unsigned long size=0;
size_t len; size_t len;
@ -1890,7 +1940,6 @@ main(int argc, char **argv)
DBG_ENTER; DBG_ENTER;
a0=*argv; /* save argv[0] for usage() */
while((ch=getopt(argc, argv, "Ns:vy")) != -1) { while((ch=getopt(argc, argv, "Ns:vy")) != -1) {
switch(ch) { switch(ch) {
case 'N': case 'N':
@ -1899,7 +1948,7 @@ main(int argc, char **argv)
case 's': case 's':
size=(size_t)atol(optarg); size=(size_t)atol(optarg);
if(size<1) { if(size<1) {
usage(a0); usage();
} }
break; break;
case 'v': /* for compatibility to newfs */ case 'v': /* for compatibility to newfs */
@ -1910,14 +1959,14 @@ main(int argc, char **argv)
case '?': case '?':
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
usage(a0); usage();
} }
} }
argc -= optind; argc -= optind;
argv += optind; argv += optind;
if(argc != 1) { if(argc != 1) {
usage(a0); usage();
} }
device=*argv; device=*argv;
@ -1937,6 +1986,9 @@ main(int argc, char **argv)
*/ */
len=strlen(device)+strlen(_PATH_DEV)+2+strlen("vinum/"); len=strlen(device)+strlen(_PATH_DEV)+2+strlen("vinum/");
special=(char *)malloc(len); special=(char *)malloc(len);
if(special == NULL) {
errx(1, "malloc failed");
}
snprintf(special, len, "%sr%s", _PATH_DEV, device); snprintf(special, len, "%sr%s", _PATH_DEV, device);
if (stat(special, &st) == -1) { if (stat(special, &st) == -1) {
snprintf(special, len, "%s%s", _PATH_DEV, device); snprintf(special, len, "%s%s", _PATH_DEV, device);
@ -1961,8 +2013,7 @@ main(int argc, char **argv)
} else { } else {
fso = open(device, O_WRONLY); fso = open(device, O_WRONLY);
if (fso < 0) { if (fso < 0) {
fprintf(stderr, "%s: %s\n", device, strerror(errno)); err(1, "%s", device);
exit(-1);
} }
} }
@ -1971,8 +2022,7 @@ main(int argc, char **argv)
*/ */
fsi = open(device, O_RDONLY); fsi = open(device, O_RDONLY);
if (fsi < 0) { if (fsi < 0) {
fprintf(stderr, "%s: %s\n", device, strerror(errno)); err(1, "%s", device);
exit(-1);
} }
/* /*
@ -1989,20 +2039,17 @@ main(int argc, char **argv)
} else if (*cp>='a' && *cp<='h') { } else if (*cp>='a' && *cp<='h') {
pp = &lp->d_partitions[*cp - 'a']; pp = &lp->d_partitions[*cp - 'a'];
} else { } else {
fprintf(stderr, "unknown device\n"); errx(1, "unknown device");
exit(-1);
} }
/* /*
* Check if that partition looks suited for growing a file system. * Check if that partition looks suited for growing a file system.
*/ */
if (pp->p_size < 1) { if (pp->p_size < 1) {
fprintf(stderr, "partition is unavailable\n"); errx(1, "partition is unavailable");
exit(-1);
} }
if (pp->p_fstype != FS_BSDFFS) { if (pp->p_fstype != FS_BSDFFS) {
fprintf(stderr, "partition not 4.2BSD\n"); errx(1, "partition not 4.2BSD");
exit(-1);
} }
/* /*
@ -2010,13 +2057,13 @@ main(int argc, char **argv)
*/ */
rdfs((daddr_t)(SBOFF/DEV_BSIZE), SBSIZE, (char *)&(osblock), fsi); rdfs((daddr_t)(SBOFF/DEV_BSIZE), SBSIZE, (char *)&(osblock), fsi);
if (osblock.fs_magic != FS_MAGIC) { if (osblock.fs_magic != FS_MAGIC) {
fprintf(stderr, "superblock not recognized\n"); errx(1, "superblock not recognized");
exit(-1);
} }
memcpy((void *)&fsun1, (void *)&fsun2, sizeof(fsun2)); memcpy((void *)&fsun1, (void *)&fsun2, sizeof(fsun2));
DBG_OPEN("/tmp/growfs.debug"); /* already here we need a superblock */ DBG_OPEN("/tmp/growfs.debug"); /* already here we need a superblock */
DBG_DUMP_FS(&sblock, "old sblock"); DBG_DUMP_FS(&sblock,
"old sblock");
/* /*
* Determine size to grow to. Default to the full size specified in * Determine size to grow to. Default to the full size specified in
@ -2025,10 +2072,8 @@ main(int argc, char **argv)
sblock.fs_size = dbtofsb(&osblock, pp->p_size); sblock.fs_size = dbtofsb(&osblock, pp->p_size);
if (size != 0) { if (size != 0) {
if (size > pp->p_size){ if (size > pp->p_size){
fprintf(stderr, errx(1, "There is not enough space (%d < %ld)",
"There is not enough space (%d < %ld)\n",
pp->p_size, size); pp->p_size, size);
exit(-1);
} }
sblock.fs_size = dbtofsb(&osblock, size); sblock.fs_size = dbtofsb(&osblock, size);
} }
@ -2037,9 +2082,8 @@ main(int argc, char **argv)
* Are we really growing ? * Are we really growing ?
*/ */
if(osblock.fs_size >= sblock.fs_size) { if(osblock.fs_size >= sblock.fs_size) {
fprintf(stderr, "we are not growing (%d->%d)\n", errx(1, "we are not growing (%d->%d)", osblock.fs_size,
osblock.fs_size, sblock.fs_size); sblock.fs_size);
exit(-1);
} }
@ -2050,11 +2094,9 @@ main(int argc, char **argv)
if(ExpertFlag == 0) { if(ExpertFlag == 0) {
for(j=0; j<FSMAXSNAP; j++) { for(j=0; j<FSMAXSNAP; j++) {
if(sblock.fs_snapinum[j]) { if(sblock.fs_snapinum[j]) {
fprintf(stderr, errx(1, "active snapshot found in filesystem\n"
"active snapshot found in filesystem\n"
" please remove all snapshots before " " please remove all snapshots before "
"using growfs\n"); "using growfs\n");
exit(-1);
} }
if(!sblock.fs_snapinum[j]) { /* list is dense */ if(!sblock.fs_snapinum[j]) { /* list is dense */
break; break;
@ -2138,8 +2180,7 @@ main(int argc, char **argv)
fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum)); fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum));
if(osblock.fs_size >= sblock.fs_size) { if(osblock.fs_size >= sblock.fs_size) {
fprintf(stderr, "not enough new space\n"); errx(1, "not enough new space");
exit(-1);
} }
DBG_PRINT0("sblock calculated\n"); DBG_PRINT0("sblock calculated\n");
@ -2199,8 +2240,7 @@ return_disklabel(int fd, struct disklabel *lp, int Nflag)
lp->d_checksum=sum; lp->d_checksum=sum;
if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) { if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) {
fprintf(stderr, "DIOCWDINFO failed\n"); errx(1, "DIOCWDINFO failed");
exit(-1);
} }
} }
free(lp); free(lp);
@ -2223,12 +2263,10 @@ get_disklabel(int fd)
lab=(struct disklabel *)malloc(sizeof(struct disklabel)); lab=(struct disklabel *)malloc(sizeof(struct disklabel));
if (!lab) { if (!lab) {
fprintf(stderr, "malloc failed\n"); errx(1, "malloc failed");
exit(-1);
} }
if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) { if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) {
fprintf(stderr, "DIOCGDINFO failed\n"); errx(1, "DIOCGDINFO failed");
exit(-1);
} }
DBG_LEAVE; DBG_LEAVE;
@ -2241,22 +2279,16 @@ get_disklabel(int fd)
* Dump a line of usage. * Dump a line of usage.
*/ */
static void static void
usage(char *name) usage(void)
{ {
DBG_FUNC("usage") DBG_FUNC("usage")
char *basename;
DBG_ENTER; DBG_ENTER;
basename=strrchr(name, '/'); fprintf(stderr, "usage: growfs [-Ny] [-s size] special\n");
if(!basename) {
basename=name;
} else {
basename++;
}
fprintf(stderr, "usage: %s [-Ny] [-s size] special_file\n", basename);
DBG_LEAVE; DBG_LEAVE;
exit(-1); exit(1);
} }
/* *********************************************************** updclst ***** */ /* *********************************************************** updclst ***** */
@ -2344,7 +2376,9 @@ updrefs(int cg, ino_t in, struct gfs_bpp *bp, int fsi, int fso, int Nflag)
DBG_LEAVE; DBG_LEAVE;
return; /* skip empty swiss cheesy file or old fastlink */ return; /* skip empty swiss cheesy file or old fastlink */
} }
DBG_PRINT2("scg checking inode (%d in %d)\n", in, cg); DBG_PRINT2("scg checking inode (%d in %d)\n",
in,
cg);
/* /*
* Start checking all direct blocks. * Start checking all direct blocks.