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:
parent
34da0ef197
commit
4020c5bc54
@ -34,7 +34,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" 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$
|
||||
.\"
|
||||
.Dd September 8, 2000
|
||||
@ -50,7 +50,7 @@
|
||||
.Op Fl i Ar inode
|
||||
.Op Fl l Ar level
|
||||
.Op Fl o Ar outfile
|
||||
.Ar < special | file >
|
||||
.Ar special | file
|
||||
.Sh DESCRIPTION
|
||||
.Nm Ffsinfo
|
||||
extends the
|
||||
@ -58,26 +58,27 @@ extends the
|
||||
program.
|
||||
.Pp
|
||||
The output is generated into the file
|
||||
.Nm outfile .
|
||||
Also expect the output file to be rather large. Up to 2 percent of the size
|
||||
of the specified filesystem is not uncommon.
|
||||
.Nm Ffsinfo
|
||||
has some options to allow the defaults to be overridden.
|
||||
.Pa outfile .
|
||||
Also expect the output file to be rather large.
|
||||
Up to 2 percent of the size of the specified filesystem is not uncommon.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.\".Pp
|
||||
.Bl -tag -width indent
|
||||
.It Fl L
|
||||
Specifying this options skips the tests of the disklabel. This is automatically
|
||||
done, if the specified filename to dump is a plain file.
|
||||
Specifying this option skips the tests of the disklabel.
|
||||
This is done automatically, if the specified filename to dump is a plain file.
|
||||
.It Fl g Ar cylinder group
|
||||
This restrictes the dump to infomation about this cylinder group only. Here
|
||||
0 means the first cylinder group and -1 the last one.
|
||||
This restricts the dump to infomation about this cylinder group only.
|
||||
Here 0 means the first cylinder group and -1 the last one.
|
||||
.It Fl i Ar inode
|
||||
This restrictes the dump to infomation about this particular inode only. Here
|
||||
the minimum acceptable inode is 2. If this option is omitted but a cylinder
|
||||
group is defined then only inodes within that cylinder group are dumped.
|
||||
This restrictes the dump to infomation about this particular inode only.
|
||||
Here the minimum acceptable inode is 2.
|
||||
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
|
||||
The level of detail which will be dumped. This value defaults
|
||||
to 255 and is the bitwise and of the following table:
|
||||
The level of detail which will be dumped.
|
||||
This value defaults to 255 and is the bitwise and of the following table:
|
||||
.Bd -literal -offset left
|
||||
0x001 - initial superblock
|
||||
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
|
||||
.Ed
|
||||
.It Fl o Ar outfile
|
||||
This allows to change the output filename where the dump is written to. The
|
||||
current default is
|
||||
.Nm /var/tmp/ffsinfo .
|
||||
This allows to change the output filename where the dump is written to.
|
||||
The current default is
|
||||
.Pa /var/tmp/ffsinfo .
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Pp
|
||||
.Dl ffsinfo -l 1023 /dev/vinum/testvol
|
||||
.Pp
|
||||
will dump /dev/vinum/testvol with all available information.
|
||||
will dump
|
||||
.Pa /dev/vinum/testvol
|
||||
with all available information.
|
||||
.Sh BUGS
|
||||
Currently
|
||||
.Nm
|
||||
can only dump unmounted file systems. Do not try dumping a mounted file system,
|
||||
your system may panic and you will not be able to use the file system any
|
||||
longer.
|
||||
can only dump unmounted file systems.
|
||||
Do not try dumping a mounted file system, your system may panic and you will
|
||||
not be able to use the file system any longer.
|
||||
.Pp
|
||||
Also snapshots are handled like plain files. They should get a their own
|
||||
level to provide for independent control of the amount of what gets dumped. It
|
||||
probably also makes sense to some extend to dump the snapshot as a filesystem.
|
||||
Also snapshots are handled like plain files.
|
||||
They should get a their own level to provide for independent control of the
|
||||
amount of what gets dumped.
|
||||
It probably also makes sense to some extend to dump the snapshot as a
|
||||
filesystem.
|
||||
.Sh SEE ALSO
|
||||
.Xr vinum 8 ,
|
||||
.Xr disklabel 8 ,
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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$
|
||||
*
|
||||
*/
|
||||
@ -55,22 +55,16 @@ static const char rcsid[] =
|
||||
/* ********************************************************** INCLUDES ***** */
|
||||
#include <sys/param.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <paths.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <machine/param.h>
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@ -101,7 +95,7 @@ static struct csum *fscs;
|
||||
|
||||
/* ******************************************************** PROTOTYPES ***** */
|
||||
static void rdfs(daddr_t, int, char *, int);
|
||||
static void usage(char *);
|
||||
static void usage(void);
|
||||
static struct disklabel *get_disklabel(int);
|
||||
static struct dinode *ginode(ino_t, 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;
|
||||
|
||||
if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) {
|
||||
fprintf(stderr, "seek error: %ld\n", (long)bno);
|
||||
err(33, "rdfs");
|
||||
err(33, "rdfs: seek error: %ld", (long)bno);
|
||||
}
|
||||
n = read(fsi, bf, (size_t)size);
|
||||
if (n != size) {
|
||||
fprintf(stderr, "read error: %ld\n", (long)bno);
|
||||
err(34, "rdfs");
|
||||
err(34, "rdfs: read error: %ld", (long)bno);
|
||||
}
|
||||
|
||||
DBG_LEAVE;
|
||||
@ -149,7 +141,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
DBG_FUNC("main")
|
||||
char *a0, *device, *special, *cp;
|
||||
char *device, *special, *cp;
|
||||
char ch;
|
||||
size_t len;
|
||||
struct stat st;
|
||||
@ -172,8 +164,10 @@ main(int argc, char **argv)
|
||||
cfg_in=-2;
|
||||
cfg_cg=-2;
|
||||
out_file=strdup("/var/tmp/ffsinfo");
|
||||
|
||||
a0=*argv; /* save argv[0] for usage() */
|
||||
if(out_file == NULL) {
|
||||
errx(1, "strdup failed");
|
||||
}
|
||||
|
||||
while ((ch=getopt(argc, argv, "Lg:i:l:o:")) != -1) {
|
||||
switch(ch) {
|
||||
case 'L':
|
||||
@ -182,36 +176,39 @@ main(int argc, char **argv)
|
||||
case 'g':
|
||||
cfg_cg=atol(optarg);
|
||||
if(cfg_cg < -1) {
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
cfg_in=atol(optarg);
|
||||
if(cfg_in < 0) {
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
cfg_lv=atol(optarg);
|
||||
if(cfg_lv < 0x1||cfg_lv > 0x3ff) {
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
free(out_file);
|
||||
out_file=strdup(optarg);
|
||||
if(out_file == NULL) {
|
||||
errx(1, "strdup failed");
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if(argc != 1) {
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
device=*argv;
|
||||
|
||||
@ -231,6 +228,9 @@ main(int argc, char **argv)
|
||||
*/
|
||||
len=strlen(device)+strlen(_PATH_DEV)+2+strlen("vinum/");
|
||||
special=(char *)malloc(len);
|
||||
if(special == NULL) {
|
||||
errx(1, "malloc failed");
|
||||
}
|
||||
snprintf(special, len, "%sr%s", _PATH_DEV, device);
|
||||
if (stat(special, &st) == -1) {
|
||||
snprintf(special, len, "%s%s", _PATH_DEV, device);
|
||||
@ -254,8 +254,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
fsi = open(device, O_RDONLY);
|
||||
if (fsi < 0) {
|
||||
fprintf(stderr, "%s: %s\n", device, strerror(errno));
|
||||
exit(-1);
|
||||
err(1, "%s", device);
|
||||
}
|
||||
|
||||
stat(device, &st);
|
||||
@ -280,20 +279,17 @@ main(int argc, char **argv)
|
||||
} else if (*cp>='a' && *cp<='h') {
|
||||
pp = &lp->d_partitions[*cp - 'a'];
|
||||
} else {
|
||||
fprintf(stderr, "unknown device\n");
|
||||
exit(-1);
|
||||
errx(1, "unknown device");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if that partition looks suited for dumping.
|
||||
*/
|
||||
if (pp->p_size < 1) {
|
||||
fprintf(stderr, "partition is unavailable\n");
|
||||
exit(-1);
|
||||
errx(1, "partition is unavailable");
|
||||
}
|
||||
if (pp->p_fstype != FS_BSDFFS) {
|
||||
fprintf(stderr, "partition not 4.2BSD\n");
|
||||
exit(-1);
|
||||
errx(1, "partition not 4.2BSD");
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,14 +298,14 @@ main(int argc, char **argv)
|
||||
*/
|
||||
rdfs((daddr_t)(SBOFF/DEV_BSIZE), SBSIZE, (char *)&(sblock), fsi);
|
||||
if (sblock.fs_magic != FS_MAGIC) {
|
||||
fprintf(stderr, "superblock not recognized\n");
|
||||
exit(-1);
|
||||
errx(1, "superblock not recognized");
|
||||
}
|
||||
|
||||
DBG_OPEN(out_file); /* already here we need a superblock */
|
||||
|
||||
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) {
|
||||
fscs = (struct csum *)calloc(1, (size_t)sblock.fs_cssize);
|
||||
if(fscs == NULL) {
|
||||
errx(1, "calloc failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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++) {
|
||||
snprintf(dbg_line, 80, "%d. csum in fscs",
|
||||
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)),
|
||||
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.
|
||||
@ -372,20 +374,32 @@ main(int argc, char **argv)
|
||||
rdfs(fsbtodb(&sblock, cgtod(&sblock, cylno)), sblock.fs_cgsize,
|
||||
(char *)&acg, fsi);
|
||||
if(cfg_lv & 0x008) {
|
||||
DBG_DUMP_CG(&sblock, dbg_line, &acg);
|
||||
DBG_DUMP_CG(&sblock,
|
||||
dbg_line,
|
||||
&acg);
|
||||
}
|
||||
if(cfg_lv & 0x010) {
|
||||
DBG_DUMP_INMAP(&sblock, dbg_line, &acg);
|
||||
DBG_DUMP_INMAP(&sblock,
|
||||
dbg_line,
|
||||
&acg);
|
||||
}
|
||||
if(cfg_lv & 0x020) {
|
||||
DBG_DUMP_FRMAP(&sblock, dbg_line, &acg);
|
||||
DBG_DUMP_FRMAP(&sblock,
|
||||
dbg_line,
|
||||
&acg);
|
||||
}
|
||||
if(cfg_lv & 0x040) {
|
||||
DBG_DUMP_CLMAP(&sblock, dbg_line, &acg);
|
||||
DBG_DUMP_CLSUM(&sblock, dbg_line, &acg);
|
||||
DBG_DUMP_CLMAP(&sblock,
|
||||
dbg_line,
|
||||
&acg);
|
||||
DBG_DUMP_CLSUM(&sblock,
|
||||
dbg_line,
|
||||
&acg);
|
||||
}
|
||||
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);
|
||||
if (level & 0x100) {
|
||||
DBG_DUMP_INO(&sblock, comment, ino);
|
||||
DBG_DUMP_INO(&sblock,
|
||||
comment,
|
||||
ino);
|
||||
}
|
||||
|
||||
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,
|
||||
fsi);
|
||||
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));
|
||||
}
|
||||
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,
|
||||
fsi);
|
||||
snprintf(comment, 80, "Inode 0x%08x: indirect 1", inode);
|
||||
DBG_DUMP_IBLK(&sblock, comment, i2blk, howmany(rb,
|
||||
howmany(sblock.fs_bsize, sizeof(ufs_daddr_t))));
|
||||
DBG_DUMP_IBLK(&sblock,
|
||||
comment,
|
||||
i2blk,
|
||||
howmany(rb, howmany(sblock.fs_bsize, sizeof(ufs_daddr_t))));
|
||||
for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize,
|
||||
sizeof(ufs_daddr_t)))&&(rb>0)); ind2ctr++) {
|
||||
ind2ptr=&((ufs_daddr_t *)&i2blk)[ind2ctr];
|
||||
@ -479,7 +500,10 @@ dump_whole_inode(ino_t inode, int fsi, int level)
|
||||
i1blk, fsi);
|
||||
snprintf(comment, 80, "Inode 0x%08x: indirect 1->%d",
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -491,8 +515,11 @@ dump_whole_inode(ino_t inode, int fsi, int level)
|
||||
fsi);
|
||||
snprintf(comment, 80, "Inode 0x%08x: indirect 2", inode);
|
||||
#define SQUARE(a) ((a)*(a))
|
||||
DBG_DUMP_IBLK(&sblock, comment, i3blk, howmany(rb,
|
||||
SQUARE(howmany(sblock.fs_bsize, sizeof(ufs_daddr_t)))));
|
||||
DBG_DUMP_IBLK(&sblock,
|
||||
comment,
|
||||
i3blk,
|
||||
howmany(rb,
|
||||
SQUARE(howmany(sblock.fs_bsize, sizeof(ufs_daddr_t)))));
|
||||
#undef SQUARE
|
||||
for(ind3ctr=0; ((ind3ctr < howmany(sblock.fs_bsize,
|
||||
sizeof(ufs_daddr_t)))&&(rb>0)); ind3ctr ++) {
|
||||
@ -502,8 +529,11 @@ dump_whole_inode(ino_t inode, int fsi, int level)
|
||||
i2blk, fsi);
|
||||
snprintf(comment, 80, "Inode 0x%08x: indirect 2->%d",
|
||||
inode, ind3ctr);
|
||||
DBG_DUMP_IBLK(&sblock, comment, i2blk, howmany(rb,
|
||||
howmany(sblock.fs_bsize, sizeof(ufs_daddr_t))));
|
||||
DBG_DUMP_IBLK(&sblock,
|
||||
comment,
|
||||
i2blk,
|
||||
howmany(rb,
|
||||
howmany(sblock.fs_bsize, sizeof(ufs_daddr_t))));
|
||||
for(ind2ctr=0; ((ind2ctr < howmany(sblock.fs_bsize,
|
||||
sizeof(ufs_daddr_t)))&&(rb>0)); ind2ctr ++) {
|
||||
ind2ptr=&((ufs_daddr_t *)&i2blk)[ind2ctr];
|
||||
@ -513,7 +543,10 @@ dump_whole_inode(ino_t inode, int fsi, int level)
|
||||
snprintf(comment, 80,
|
||||
"Inode 0x%08x: indirect 2->%d->%d", inode,
|
||||
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,
|
||||
sizeof(ufs_daddr_t));
|
||||
}
|
||||
@ -538,11 +571,10 @@ get_disklabel(int fd)
|
||||
|
||||
lab=(struct disklabel *)malloc(sizeof(struct disklabel));
|
||||
if (!lab) {
|
||||
fprintf(stderr, "malloc failed\n");
|
||||
exit(-1);
|
||||
errx(1, "malloc failed");
|
||||
}
|
||||
if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) {
|
||||
fprintf(stderr, "DIOCGDINFO failed\n");
|
||||
errx(1, "DIOCGDINFO failed");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
@ -556,26 +588,19 @@ get_disklabel(int fd)
|
||||
* Dump a line of usage.
|
||||
*/
|
||||
void
|
||||
usage(char *name)
|
||||
usage(void)
|
||||
{
|
||||
DBG_FUNC("usage")
|
||||
char *basename;
|
||||
|
||||
DBG_ENTER;
|
||||
|
||||
basename=strrchr(name, '/');
|
||||
if(!basename) {
|
||||
basename=name;
|
||||
} else {
|
||||
basename++;
|
||||
}
|
||||
fprintf(stderr,
|
||||
"usage:\t%s\t[-L] [-g cylgrp] [-i inode] [-l level] [-o outfile]\n"
|
||||
"\t\t< special | file >\n",
|
||||
basename);
|
||||
"usage: ffsinfo [-L] [-g cylgrp] [-i inode] [-l level] "
|
||||
"[-o outfile]\n"
|
||||
" special | file\n");
|
||||
|
||||
DBG_LEAVE;
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* ************************************************************ ginode ***** */
|
||||
@ -583,7 +608,7 @@ usage(char *name)
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
struct dinode *
|
||||
|
@ -35,14 +35,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
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 */
|
||||
|
||||
/* ********************************************************** INCLUDES ***** */
|
||||
|
@ -34,7 +34,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" 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$
|
||||
.\"
|
||||
.Dd September 8, 2000
|
||||
@ -49,7 +49,7 @@
|
||||
.Op Fl s Ar size
|
||||
.Ar special
|
||||
.Sh DESCRIPTION
|
||||
.Nm Growfs
|
||||
.Nm
|
||||
extends the
|
||||
.Xr newfs 8
|
||||
program.
|
||||
@ -59,38 +59,43 @@ the disk must be labeled to a bigger size using
|
||||
.Xr disklabel 8 .
|
||||
If you are using volumes you must grow them using
|
||||
.Xr vinum 8 .
|
||||
.Nm Growfs
|
||||
.Nm
|
||||
extends the size of the file system on the specified special file.
|
||||
Currently
|
||||
.Nm
|
||||
can only grow unmounted file systems. Do not try growing an mounted file system,
|
||||
your system may panic and you will not be able to use the file system any longer.
|
||||
can only grow unmounted file systems.
|
||||
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
|
||||
.Xr newfs 8
|
||||
once can not be changed. In fact you can only increase the size of the file
|
||||
system. Use
|
||||
once can not be changed.
|
||||
In fact you can only increase the size of the file system.
|
||||
Use
|
||||
.Xr tunefs 8
|
||||
for other changes.
|
||||
Typically the defaults are reasonable, however
|
||||
.Nm
|
||||
has some options to allow the defaults to be overridden.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.\".Pp
|
||||
.Bl -tag -width indent
|
||||
.It Fl N
|
||||
Cause the new file system parameters to be printed out
|
||||
without realy growing the file system.
|
||||
Cause the new file system parameters to be printed out without actually growing
|
||||
the file system.
|
||||
.It Fl y
|
||||
.Dq Expert mode
|
||||
Normally
|
||||
.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
|
||||
.Ar special
|
||||
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
|
||||
The size of the file system after growing in sectors. This value defaults
|
||||
to the size of the raw partition specified in
|
||||
The
|
||||
.Ar size
|
||||
of the file system after growing in sectors.
|
||||
This value defaults to the size of the raw partition specified in
|
||||
.Ar special
|
||||
(in other words,
|
||||
.Nm
|
||||
@ -100,8 +105,10 @@ will grow the file system to the size of the entire partition).
|
||||
.Pp
|
||||
.Dl growfs -s 4194304 /dev/vinum/testvol
|
||||
.Pp
|
||||
will grow /dev/vinum/testvol up to 2GB if there is enough space in
|
||||
/dev/vinum/testvol .
|
||||
will grow
|
||||
.Pa /dev/vinum/testvol
|
||||
up to 2GB if there is enough space in
|
||||
.Pa /dev/vinum/testvol .
|
||||
.Sh BUGS
|
||||
In some cases on
|
||||
.Bx Free
|
||||
@ -110,27 +117,31 @@ In some cases on
|
||||
did not recognize exactly, if the file system is mounted or not and
|
||||
exits with an error message, then use
|
||||
.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
|
||||
.Nm fsck
|
||||
.Xr fsck 8
|
||||
after growing just to be on the safe side.
|
||||
.Pp
|
||||
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
|
||||
works perfect with this relocated structure except the
|
||||
.Nm fsck(8)
|
||||
utility. There is a patch available for
|
||||
.Nm fsck(8) .
|
||||
system internal structure which had never been moved before.
|
||||
Almost everything works perfect with this relocated structure except the
|
||||
.Xr fsck 8
|
||||
utility.
|
||||
There is a patch available for
|
||||
.Xr fsck 8 ) .
|
||||
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
|
||||
structure it is currently recommended to use
|
||||
.Nm ffsinfo -c 0
|
||||
available in the first cylinder group.
|
||||
To avoid the relocation of that structure it is currently recommended to use
|
||||
.Nm
|
||||
.Fl c Ar 0
|
||||
on the first cylinder group and check that
|
||||
.Nm nbfree
|
||||
.Em nbfree
|
||||
in the CYLINDER SUMMARY (internal cs) of the CYLINDER GROUP
|
||||
.Nm cgr0
|
||||
has enough blocks. As a rule of thumb for default filesystem parameters a block
|
||||
is needed for every 2 GB of total filesystem size.
|
||||
.Em cgr0
|
||||
has enough blocks.
|
||||
As a rule of thumb for default filesystem parameters a block is needed for
|
||||
every 2 GB of total filesystem size.
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Xr vinum 8 ,
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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$
|
||||
*
|
||||
*/
|
||||
@ -49,7 +49,7 @@ All rights reserved.\n";
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
"$FreeBSD$";
|
||||
#endif /* not lint */
|
||||
|
||||
/* ********************************************************** INCLUDES ***** */
|
||||
@ -57,20 +57,17 @@ static const char rcsid[] =
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <paths.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <machine/param.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 daddr_t alloc(void);
|
||||
static int charsperline(void);
|
||||
static void usage(char *);
|
||||
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);
|
||||
@ -151,7 +148,7 @@ static void updrefs(int, ino_t, struct gfs_bpp *, int, int, int);
|
||||
/* ************************************************************ growfs ***** */
|
||||
/*
|
||||
* 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
|
||||
* changes in the former last cylinder group. Afterwards we create all new
|
||||
* 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.
|
||||
*/
|
||||
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) {
|
||||
rdfs(fsbtodb(&osblock, osblock.fs_csaddr +
|
||||
numfrags(&osblock, i)), MIN(osblock.fs_cssize - i,
|
||||
@ -204,7 +204,9 @@ growfs(int fsi, int fso, int Nflag)
|
||||
dbg_csp=fscs;
|
||||
for(dbg_csc=0; dbg_csc<osblock.fs_ncg; 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 */
|
||||
@ -280,7 +282,9 @@ growfs(int fsi, int fso, int Nflag)
|
||||
dbg_csp=fscs;
|
||||
for(dbg_csc=0; dbg_csc<sblock.fs_ncg; 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 */
|
||||
@ -291,7 +295,8 @@ growfs(int fsi, int fso, int Nflag)
|
||||
sblock.fs_time = utime;
|
||||
wtfs((int)SBOFF / DEV_BSIZE, SBSIZE, (char *)&sblock, fso, Nflag);
|
||||
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.
|
||||
@ -333,7 +338,8 @@ growfs(int fsi, int fso, int Nflag)
|
||||
SBSIZE, (char *)&sblock, fso, Nflag);
|
||||
}
|
||||
DBG_PRINT0("sblock copies written\n");
|
||||
DBG_DUMP_FS(&sblock, "new other sblocks");
|
||||
DBG_DUMP_FS(&sblock,
|
||||
"new other sblocks");
|
||||
|
||||
DBG_LEAVE;
|
||||
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
|
||||
* already on filesystem creation
|
||||
*/
|
||||
fprintf(stderr, "Panic: cylinder group too big\n");
|
||||
exit(37);
|
||||
errx(37, "panic: cylinder group too big");
|
||||
}
|
||||
acg.cg_cs.cs_nifree += sblock.fs_ipg;
|
||||
if (cylno == 0)
|
||||
@ -506,7 +511,9 @@ initcg(int cylno, time_t utime, int fso, int Nflag)
|
||||
*cs = acg.cg_cs;
|
||||
wtfs(fsbtodb(&sblock, cgtod(&sblock, cylno)),
|
||||
sblock.fs_bsize, (char *)&acg, fso, Nflag);
|
||||
DBG_DUMP_CG(&sblock, "new cg", &acg);
|
||||
DBG_DUMP_CG(&sblock,
|
||||
"new cg",
|
||||
&acg);
|
||||
|
||||
DBG_LEAVE;
|
||||
return;
|
||||
@ -547,7 +554,9 @@ frag_adjust(daddr_t frag, int sign)
|
||||
* We found something in between.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -557,9 +566,13 @@ frag_adjust(daddr_t frag, int sign)
|
||||
* We found something.
|
||||
*/
|
||||
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;
|
||||
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));
|
||||
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 */
|
||||
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,
|
||||
(char *)&aocg, fsi);
|
||||
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));
|
||||
|
||||
@ -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,
|
||||
(char *)&acg, fso, Nflag);
|
||||
DBG_PRINT0("jcg written\n");
|
||||
DBG_DUMP_CG(&sblock, "new joining cg", &acg);
|
||||
DBG_DUMP_CG(&sblock,
|
||||
"new joining cg",
|
||||
&acg);
|
||||
|
||||
DBG_LEAVE;
|
||||
return;
|
||||
@ -722,7 +742,11 @@ updjcg(int cylno, time_t utime, int fsi, int fso, int Nflag)
|
||||
} else {
|
||||
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;
|
||||
sblock.fs_dsize += acg.cg_ndblk-aocg.cg_ndblk;
|
||||
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,
|
||||
(char *)&acg, fso, Nflag);
|
||||
DBG_PRINT0("jcg written\n");
|
||||
DBG_DUMP_CG(&sblock, "new joining cg", &acg);
|
||||
DBG_DUMP_CG(&sblock,
|
||||
"new joining cg",
|
||||
&acg);
|
||||
|
||||
DBG_LEAVE;
|
||||
return;
|
||||
@ -929,7 +955,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
|
||||
rdfs(fsbtodb(&osblock, cgtod(&osblock, ocscg)), osblock.fs_cgsize,
|
||||
(char *)&aocg, fsi);
|
||||
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));
|
||||
|
||||
@ -967,8 +995,7 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
|
||||
*/
|
||||
DBG_TRC;
|
||||
if(sblock.fs_ncg-osblock.fs_ncg < 2) {
|
||||
fprintf(stderr, "growfs: panic, not enough space\n");
|
||||
exit(2);
|
||||
errx(2, "panic: not enough space");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -997,7 +1024,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
|
||||
*/
|
||||
d--;
|
||||
|
||||
DBG_PRINT1("d=%d\n",d);
|
||||
DBG_PRINT1("d=%d\n",
|
||||
d);
|
||||
if((d+1)%sblock.fs_frag) {
|
||||
/*
|
||||
* 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;
|
||||
frag_adjust(d%sblock.fs_fpg, -1);
|
||||
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);
|
||||
acg.cg_cs.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),
|
||||
(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_nbfree++;
|
||||
sblock.fs_cstotal.cs_nffree-=sblock.fs_frag;
|
||||
@ -1050,11 +1080,13 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
|
||||
d--;
|
||||
}
|
||||
|
||||
DBG_PRINT1("d=%d\n",d);
|
||||
DBG_PRINT1("d=%d\n",
|
||||
d);
|
||||
for(d=rounddown(d, sblock.fs_frag); d >= osblock.fs_csaddr;
|
||||
d-=sblock.fs_frag) {
|
||||
DBG_TRC;
|
||||
DBG_PRINT1("d=%d\n",d);
|
||||
DBG_PRINT1("d=%d\n",
|
||||
d);
|
||||
setblock(&sblock, cg_blksfree(&acg),
|
||||
(d%sblock.fs_fpg)/sblock.fs_frag);
|
||||
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,
|
||||
(char *)&acg, fso, Nflag);
|
||||
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
|
||||
@ -1104,7 +1138,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
|
||||
rdfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)),
|
||||
sblock.fs_cgsize, (char *)&aocg, fsi);
|
||||
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));
|
||||
|
||||
@ -1178,7 +1214,9 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
|
||||
wtfs(fsbtodb(&sblock, cgtod(&sblock, ncscg)), sblock.fs_cgsize,
|
||||
(char *)&acg, fso, Nflag);
|
||||
DBG_PRINT0("nscg written\n");
|
||||
DBG_DUMP_CG(&sblock, "new summary cg", &acg);
|
||||
DBG_DUMP_CG(&sblock,
|
||||
"new summary cg",
|
||||
&acg);
|
||||
|
||||
DBG_LEAVE;
|
||||
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)*
|
||||
sizeof(struct gfs_bpp));
|
||||
if(bp == NULL) {
|
||||
errx(1, "malloc failed");
|
||||
}
|
||||
memset((char *)bp, 0, sizeof(struct gfs_bpp));
|
||||
|
||||
/*
|
||||
@ -1216,7 +1257,8 @@ updcsloc(time_t utime, int fsi, int fso, int Nflag)
|
||||
ind=0;
|
||||
frag_adjust(odupper, -1);
|
||||
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 (!ind) {
|
||||
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.
|
||||
*/
|
||||
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)) {
|
||||
for(f=d; f<d+sblock.fs_frag; 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++) {
|
||||
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)) {
|
||||
bp[ind].old=d/sblock.fs_frag;
|
||||
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);
|
||||
wtfs(fsbtodb(&sblock, bp[i].new*sblock.fs_frag),
|
||||
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.
|
||||
*/
|
||||
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--) {
|
||||
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++) {
|
||||
if(!bp[i].found || (bp[i].found>sblock.fs_frag)) {
|
||||
fprintf(stderr,
|
||||
"error: %d refs found for block %d.\n",
|
||||
warnx("error: %d refs found for block %d.",
|
||||
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,
|
||||
(char *)&acg, fso, Nflag);
|
||||
DBG_PRINT0("scg written\n");
|
||||
DBG_DUMP_CG(&sblock, "new summary cg", &acg);
|
||||
DBG_DUMP_CG(&sblock,
|
||||
"new summary cg",
|
||||
&acg);
|
||||
|
||||
DBG_LEAVE;
|
||||
return;
|
||||
@ -1497,13 +1547,11 @@ rdfs(daddr_t bno, int size, char *bf, int fsi)
|
||||
DBG_ENTER;
|
||||
|
||||
if (lseek(fsi, (off_t)bno * DEV_BSIZE, 0) < 0) {
|
||||
fprintf(stderr, "seek error: %ld\n", (long)bno);
|
||||
err(33, "rdfs");
|
||||
err(33, "rdfs: seek error: %ld", (long)bno);
|
||||
}
|
||||
n = read(fsi, bf, (size_t)size);
|
||||
if (n != size) {
|
||||
fprintf(stderr, "read error: %ld\n", (long)bno);
|
||||
err(34, "rdfs");
|
||||
err(34, "rdfs: read error: %ld", (long)bno);
|
||||
}
|
||||
|
||||
DBG_LEAVE;
|
||||
@ -1527,13 +1575,11 @@ wtfs(daddr_t bno, int size, char *bf, int fso, int Nflag)
|
||||
return;
|
||||
}
|
||||
if (lseek(fso, (off_t)bno * DEV_BSIZE, SEEK_SET) < 0) {
|
||||
fprintf(stderr, "seek error: %ld\n", (long)bno);
|
||||
err(35, "wtfs");
|
||||
err(35, "wtfs: seek error: %ld", (long)bno);
|
||||
}
|
||||
n = write(fso, bf, (size_t)size);
|
||||
if (n != size) {
|
||||
fprintf(stderr, "write error: %ld\n", (long)bno);
|
||||
err(36, "wtfs");
|
||||
err(36, "wtfs: write error: %ld", (long)bno);
|
||||
}
|
||||
|
||||
DBG_LEAVE;
|
||||
@ -1559,12 +1605,12 @@ alloc(void)
|
||||
DBG_ENTER;
|
||||
|
||||
if (acg.cg_magic != CG_MAGIC) {
|
||||
fprintf(stderr, "acg: bad magic number\n");
|
||||
warnx("acg: bad magic number");
|
||||
DBG_LEAVE;
|
||||
return (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;
|
||||
return (0);
|
||||
}
|
||||
@ -1584,8 +1630,13 @@ alloc(void)
|
||||
dmax-=cgbase(&sblock, acg.cg_cgx); /* retransform into cg */
|
||||
csmin=sblock.fs_csaddr-cgbase(&sblock, acg.cg_cgx);
|
||||
csmax=csmin+howmany(sblock.fs_cssize, sblock.fs_fsize);
|
||||
DBG_PRINT3("seek range: dl=%d, du=%d, dm=%d\n", dlower, dupper, dmax);
|
||||
DBG_PRINT2("range cont: csmin=%d, csmax=%d\n", csmin, csmax);
|
||||
DBG_PRINT3("seek range: dl=%d, du=%d, dm=%d\n",
|
||||
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) {
|
||||
if(d>=csmin && d<=csmax) {
|
||||
@ -1608,8 +1659,7 @@ alloc(void)
|
||||
}
|
||||
}
|
||||
if(blkno==-1) {
|
||||
fprintf(stderr,
|
||||
"internal error: couldn't find promised block in cg\n");
|
||||
warnx("internal error: couldn't find promised block in cg");
|
||||
DBG_LEAVE;
|
||||
return (0);
|
||||
}
|
||||
@ -1627,7 +1677,7 @@ alloc(void)
|
||||
clrbit(cg_clustersfree(&acg), blkno);
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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));
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
|
||||
warnx("clrblock bad fs_frag %d", fs->fs_frag);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1771,7 +1821,7 @@ setblock(struct fs *fs, unsigned char *cp, int h)
|
||||
cp[h >> 3] |= (0x01 << (h & 0x7));
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
|
||||
warnx("setblock bad fs_frag %d", fs->fs_frag);
|
||||
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
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
static struct dinode *
|
||||
@ -1859,21 +1909,21 @@ charsperline(void)
|
||||
* We still have to provide support for snapshots. Therefore we first have to
|
||||
* understand what data structures are always replicated in the snapshot on
|
||||
* 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
|
||||
* way.
|
||||
* 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.
|
||||
* The forseen last step then will be to provide for growing even mounted
|
||||
* file systems. There we have to extend the mount() systemcall to provide
|
||||
* The foreseen last step then will be to provide for growing even mounted
|
||||
* file systems. There we have to extend the mount() system call to provide
|
||||
* userland access to the file system locking facility.
|
||||
*/
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
DBG_FUNC("main")
|
||||
char *a0, *device, *special, *cp;
|
||||
char *device, *special, *cp;
|
||||
char ch;
|
||||
unsigned long size=0;
|
||||
size_t len;
|
||||
@ -1890,7 +1940,6 @@ main(int argc, char **argv)
|
||||
|
||||
DBG_ENTER;
|
||||
|
||||
a0=*argv; /* save argv[0] for usage() */
|
||||
while((ch=getopt(argc, argv, "Ns:vy")) != -1) {
|
||||
switch(ch) {
|
||||
case 'N':
|
||||
@ -1899,7 +1948,7 @@ main(int argc, char **argv)
|
||||
case 's':
|
||||
size=(size_t)atol(optarg);
|
||||
if(size<1) {
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
case 'v': /* for compatibility to newfs */
|
||||
@ -1910,14 +1959,14 @@ main(int argc, char **argv)
|
||||
case '?':
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if(argc != 1) {
|
||||
usage(a0);
|
||||
usage();
|
||||
}
|
||||
device=*argv;
|
||||
|
||||
@ -1937,6 +1986,9 @@ main(int argc, char **argv)
|
||||
*/
|
||||
len=strlen(device)+strlen(_PATH_DEV)+2+strlen("vinum/");
|
||||
special=(char *)malloc(len);
|
||||
if(special == NULL) {
|
||||
errx(1, "malloc failed");
|
||||
}
|
||||
snprintf(special, len, "%sr%s", _PATH_DEV, device);
|
||||
if (stat(special, &st) == -1) {
|
||||
snprintf(special, len, "%s%s", _PATH_DEV, device);
|
||||
@ -1961,8 +2013,7 @@ main(int argc, char **argv)
|
||||
} else {
|
||||
fso = open(device, O_WRONLY);
|
||||
if (fso < 0) {
|
||||
fprintf(stderr, "%s: %s\n", device, strerror(errno));
|
||||
exit(-1);
|
||||
err(1, "%s", device);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1971,8 +2022,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
fsi = open(device, O_RDONLY);
|
||||
if (fsi < 0) {
|
||||
fprintf(stderr, "%s: %s\n", device, strerror(errno));
|
||||
exit(-1);
|
||||
err(1, "%s", device);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1989,20 +2039,17 @@ main(int argc, char **argv)
|
||||
} else if (*cp>='a' && *cp<='h') {
|
||||
pp = &lp->d_partitions[*cp - 'a'];
|
||||
} else {
|
||||
fprintf(stderr, "unknown device\n");
|
||||
exit(-1);
|
||||
errx(1, "unknown device");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if that partition looks suited for growing a file system.
|
||||
*/
|
||||
if (pp->p_size < 1) {
|
||||
fprintf(stderr, "partition is unavailable\n");
|
||||
exit(-1);
|
||||
errx(1, "partition is unavailable");
|
||||
}
|
||||
if (pp->p_fstype != FS_BSDFFS) {
|
||||
fprintf(stderr, "partition not 4.2BSD\n");
|
||||
exit(-1);
|
||||
errx(1, "partition not 4.2BSD");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2010,13 +2057,13 @@ main(int argc, char **argv)
|
||||
*/
|
||||
rdfs((daddr_t)(SBOFF/DEV_BSIZE), SBSIZE, (char *)&(osblock), fsi);
|
||||
if (osblock.fs_magic != FS_MAGIC) {
|
||||
fprintf(stderr, "superblock not recognized\n");
|
||||
exit(-1);
|
||||
errx(1, "superblock not recognized");
|
||||
}
|
||||
memcpy((void *)&fsun1, (void *)&fsun2, sizeof(fsun2));
|
||||
|
||||
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
|
||||
@ -2025,10 +2072,8 @@ main(int argc, char **argv)
|
||||
sblock.fs_size = dbtofsb(&osblock, pp->p_size);
|
||||
if (size != 0) {
|
||||
if (size > pp->p_size){
|
||||
fprintf(stderr,
|
||||
"There is not enough space (%d < %ld)\n",
|
||||
errx(1, "There is not enough space (%d < %ld)",
|
||||
pp->p_size, size);
|
||||
exit(-1);
|
||||
}
|
||||
sblock.fs_size = dbtofsb(&osblock, size);
|
||||
}
|
||||
@ -2037,9 +2082,8 @@ main(int argc, char **argv)
|
||||
* Are we really growing ?
|
||||
*/
|
||||
if(osblock.fs_size >= sblock.fs_size) {
|
||||
fprintf(stderr, "we are not growing (%d->%d)\n",
|
||||
osblock.fs_size, sblock.fs_size);
|
||||
exit(-1);
|
||||
errx(1, "we are not growing (%d->%d)", osblock.fs_size,
|
||||
sblock.fs_size);
|
||||
}
|
||||
|
||||
|
||||
@ -2050,11 +2094,9 @@ main(int argc, char **argv)
|
||||
if(ExpertFlag == 0) {
|
||||
for(j=0; j<FSMAXSNAP; j++) {
|
||||
if(sblock.fs_snapinum[j]) {
|
||||
fprintf(stderr,
|
||||
"active snapshot found in filesystem\n"
|
||||
errx(1, "active snapshot found in filesystem\n"
|
||||
" please remove all snapshots before "
|
||||
"using growfs\n");
|
||||
exit(-1);
|
||||
}
|
||||
if(!sblock.fs_snapinum[j]) { /* list is dense */
|
||||
break;
|
||||
@ -2138,8 +2180,7 @@ main(int argc, char **argv)
|
||||
fragroundup(&sblock, sblock.fs_ncg * sizeof(struct csum));
|
||||
|
||||
if(osblock.fs_size >= sblock.fs_size) {
|
||||
fprintf(stderr, "not enough new space\n");
|
||||
exit(-1);
|
||||
errx(1, "not enough new space");
|
||||
}
|
||||
|
||||
DBG_PRINT0("sblock calculated\n");
|
||||
@ -2199,8 +2240,7 @@ return_disklabel(int fd, struct disklabel *lp, int Nflag)
|
||||
lp->d_checksum=sum;
|
||||
|
||||
if (ioctl(fd, DIOCWDINFO, (char *)lp) < 0) {
|
||||
fprintf(stderr, "DIOCWDINFO failed\n");
|
||||
exit(-1);
|
||||
errx(1, "DIOCWDINFO failed");
|
||||
}
|
||||
}
|
||||
free(lp);
|
||||
@ -2223,12 +2263,10 @@ get_disklabel(int fd)
|
||||
|
||||
lab=(struct disklabel *)malloc(sizeof(struct disklabel));
|
||||
if (!lab) {
|
||||
fprintf(stderr, "malloc failed\n");
|
||||
exit(-1);
|
||||
errx(1, "malloc failed");
|
||||
}
|
||||
if (ioctl(fd, DIOCGDINFO, (char *)lab) < 0) {
|
||||
fprintf(stderr, "DIOCGDINFO failed\n");
|
||||
exit(-1);
|
||||
errx(1, "DIOCGDINFO failed");
|
||||
}
|
||||
|
||||
DBG_LEAVE;
|
||||
@ -2241,22 +2279,16 @@ get_disklabel(int fd)
|
||||
* Dump a line of usage.
|
||||
*/
|
||||
static void
|
||||
usage(char *name)
|
||||
usage(void)
|
||||
{
|
||||
DBG_FUNC("usage")
|
||||
char *basename;
|
||||
|
||||
DBG_ENTER;
|
||||
|
||||
basename=strrchr(name, '/');
|
||||
if(!basename) {
|
||||
basename=name;
|
||||
} else {
|
||||
basename++;
|
||||
}
|
||||
fprintf(stderr, "usage: %s [-Ny] [-s size] special_file\n", basename);
|
||||
fprintf(stderr, "usage: growfs [-Ny] [-s size] special\n");
|
||||
|
||||
DBG_LEAVE;
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* *********************************************************** updclst ***** */
|
||||
@ -2344,7 +2376,9 @@ updrefs(int cg, ino_t in, struct gfs_bpp *bp, int fsi, int fso, int Nflag)
|
||||
DBG_LEAVE;
|
||||
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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user