ChangeLog, fsck.8.in, fsck.c, fsck.h, mke2fs.8.in, mke2fs.c:

* mke2fs.c (PRS, set_fs_defaults): Add new option -T which allows the
  	user to specify the how the filesystem is to be used.  Mke2fs now
  	chooses the filesystem parameters automatically based on the size of
  	the filesystem and the intended use of the filesystem.  Add new option
  	-n which simply goes through the calculations to determine the
  	parameters of the filesystem the system would make.
  * fsck.c, fsck.h: Add support for new option -C.  This option will
  	automatically manage e2fsck processes so that they will print
  	completion/progress bars.  If multiple filesystems are being checked,
  	arrange to make sure that only one e2fsck process is displaying a
  	progress bar at a time.
bitmap-optimize
Theodore Ts'o 1999-07-19 15:30:21 +00:00
parent 5596defa1e
commit 50787ea22e
6 changed files with 252 additions and 110 deletions

View File

@ -1,4 +1,22 @@
1999-07-08 <tytso@rsts-11.mit.edu>
1999-07-18 <tytso@rsts-11.mit.edu>
* mke2fs.c (PRS, set_fs_defaults): Add new option -T which allows
the user to specify the how the filesystem is to be used.
Mke2fs now chooses the filesystem parameters automatically
based on the size of the filesystem and the intended use
of the filesystem. Add new option -n which simply goes
through the calculations to determine the parameters of
the filesystem the system would make.
1999-07-18 <tytso@valinux.com>
* fsck.c, fsck.h: Add support for new option -C. This option will
automatically manage e2fsck processes so that they will
print completion/progress bars. If multiple filesystems
are being checked, arrange to make sure that only one
e2fsck process is displaying a progress bar at a time.
1999-07-08 <tytso@valinux.com>
* badblocks.c (do_test): Don't complain if the write error occurs
on a non-block boundary. This is perfectly common when

View File

@ -8,32 +8,26 @@ fsck \- check and repair a Linux file system
.SH SYNOPSIS
.B fsck
[
.B \-AVRTNP
]
[
.B \-s
.B \-sACVRTNP
]
[
.B \-t
.I fstype
]
[
.B fs-options
] -- [
.B fsck-options
]
.I filesys [ ... ]
.SH DESCRIPTION
.B fsck
is used to check and optionally repair a Linux file system.
is used to check and optionally repair a one or more Linux file systems.
.I filesys
is either the device name (e.g. /dev/hda1, /dev/sdb2) or the mount point
(e.g. /, /usr, /home) for the file system. If this invocation of
can be a device name (e.g. /dev/hda1, /dev/sdb2), a
mount point (e.g. /, /usr, /home), or an ext2 label or UUID specifier
(e.g., UUID=8868abf6-88c5-4a83-98b8-bfc24057f7bd or LABEL=root).
The
.B fsck
has several filesystems on different physical disk drives to check, then
.B fsck
will try to run them in parallel. This reduces the total amount time it
takes to check all of the filesystems, since
.B fsck
takes advantage of the parallelism of multiple disk spindles.
program will try to run filesystems on different physical disk drives
in parallel to reduce total amount time to check all of the filesystems.
.PP
The exit code returned by
.B fsck
@ -68,6 +62,48 @@ variable. Please see the file system-specific checker manual pages for
further details.
.SH OPTIONS
.TP
.B -s
Serialize
.B fsck
operations. This is a good idea if you checking multiple
filesystems and the checkers are in an interactive mode. (Note:
.BR e2fsck (8)
runs in an interactive mode by default. To make
.BR e2fsck (8)
run in a non-interactive mode, you must either specify the
.B -p
or
.B -a
option, if you wish for errors to be corrected automatically, or
the
.B -n
option if you do not.)
.TP
.BI -t \ fstype
Specifies the type of file system to be checked. When the
.B \-A
flag is specified, only filesystems that match
.I fstype
are checked. If
.I fstype
is prefixed with
.B no
then only filesystems whose type does not match
.I fstype
are checked.
.sp
Normally, the filesystem type is deduced by searching for
.I filesys
in the
.I /etc/fstab
file and using the corresponding entry.
If the type can not be deduced,
.B fsck
will use the type specified by the
.B \-t
option if it specifies a unique filesystem type. If this type is not
available, then the default file system type (currently ext2) is used.
.TP
.B -A
Walk through the
.I /etc/fstab
@ -103,13 +139,10 @@ checks running in parallel for some reason --- for example, if the
machine in question is short on memory so that
excessive paging is a concern.
.TP
.B -R
When checking all file systems with the
.B \-A
flag, skip the root file system (in case it's already mounted read-write).
.TP
.B -T
Don't show the title on startup.
.B -C
Display completion/progress bars for those filesystems checkers (currently
only for ext2) which support them. Fsck will manage the filesystem checkers
so that only one of them will display a progress bar at a time.
.TP
.B -N
Don't execute, just show what would be done.
@ -125,53 +158,19 @@ executable might be corrupted! This option is mainly provided
for those sysadmins who don't want to repartition the root
filesystem to be small and compact (which is really the right solution).
.TP
.B -s
Serialize
.B fsck
operations. This is a good idea if you checking multiple
filesystems and the checkers are in an interactive mode. (Note:
.BR e2fsck (8)
runs in an interactive mode by default. To make
.BR e2fsck (8)
run in a non-interactive mode, you must either specify the
.B -p
or
.B -a
option, if you wish for errors to be corrected automatically, or
the
.B -n
option if you do not.)
.B -R
When checking all file systems with the
.B \-A
flag, skip the root file system (in case it's already mounted read-write).
.TP
.B -T
Don't show the title on startup.
.TP
.B -V
Produce verbose output, including all file system-specific commands
that are executed.
.TP
.BI -t \ fstype
Specifies the type of file system to be checked. When the
.B \-A
flag is specified, only filesystems that match
.I fstype
are checked. If
.I fstype
is prefixed with
.B no
then only filesystems whose type does not match
.I fstype
are checked.
.sp
Normally, the filesystem type is deduced by searching for
.I filesys
in the
.I /etc/fstab
file and using the corresponding entry.
If the type can not be deduced,
.B fsck
will use the type specified by the
.B \-t
option if it specifies a unique filesystem type. If this type is not
available, then the default file system type (currently ext2) is used.
.TP
.B fs-options
.B fsck-options
Any options which are not understood by
.BR fsck ,
or which follow the

View File

@ -8,7 +8,7 @@
*
* Written by Theodore Ts'o, <tytso@mit.edu>
*
* Usage: fsck [-AVRNTM] [-s] [-t fstype] [fs-options] device
* Usage: fsck [-ACVRNTM] [-s] [-t fstype] [fs-options] device
*
* Miquel van Smoorenburg (miquels@drinkel.ow.org) 20-Oct-1994:
* o Changed -t fstype to behave like with mount when -A (all file
@ -18,7 +18,7 @@
* can be added without changing this front-end.
* o -R flag skip root file system.
*
* Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
* Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Public
@ -130,6 +130,7 @@ int skip_root = 0;
int like_mount = 0;
int notitle = 0;
int parallel_root = 0;
int progress = 0;
char *progname;
char *fstype = NULL;
struct fs_info *filesys_info;
@ -355,23 +356,49 @@ static char *find_fsck(char *type)
return(s ? prog : NULL);
}
static int progress_active()
{
struct fsck_instance *inst;
for (inst = instance_list; inst; inst = inst->next) {
if (inst->flags & FLAG_DONE)
continue;
if (inst->flags & FLAG_PROGRESS)
return 1;
}
return 0;
}
/*
* Execute a particular fsck program, and link it into the list of
* child processes we are waiting for.
*/
static int execute(char *prog, char *device, char *mntpt, int interactive)
static int execute(char *type, char *device, char *mntpt, int interactive)
{
char *s, *argv[80];
char *s, *argv[80], prog[80];
int argc, i;
struct fsck_instance *inst;
pid_t pid;
inst = malloc(sizeof(struct fsck_instance));
if (!inst)
return ENOMEM;
memset(inst, 0, sizeof(struct fsck_instance));
sprintf(prog, "fsck.%s", type);
argv[0] = string_copy(prog);
argc = 1;
for (i=0; i <num_args; i++)
argv[argc++] = string_copy(args[i]);
if (progress & !progress_active()) {
if (strcmp(type, "ext2") == 0) {
argv[argc++] = "-C0";
inst->flags |= FLAG_PROGRESS;
}
}
argv[argc++] = string_copy(device);
argv[argc] = 0;
@ -401,12 +428,10 @@ static int execute(char *prog, char *device, char *mntpt, int interactive)
perror(argv[0]);
exit(EXIT_ERROR);
}
inst = malloc(sizeof(struct fsck_instance));
if (!inst)
return ENOMEM;
memset(inst, 0, sizeof(struct fsck_instance));
inst->pid = pid;
inst->prog = string_copy(prog);
inst->type = string_copy(type);
inst->device = string_copy(device);
inst->next = instance_list;
instance_list = inst;
@ -422,7 +447,7 @@ static struct fsck_instance *wait_one(NOARGS)
{
int status;
int sig;
struct fsck_instance *inst, *prev;
struct fsck_instance *inst, *inst2, *prev;
pid_t pid;
if (!instance_list)
@ -482,6 +507,17 @@ retry:
prev->next = inst->next;
else
instance_list = inst->next;
if (progress && (inst->flags & FLAG_PROGRESS) &&
!progress_active()) {
for (inst2 = instance_list; inst2; inst2 = inst2->next) {
if (inst2->flags & FLAG_DONE)
continue;
if (strcmp(inst2->type, "ext2"))
continue;
kill(inst2->pid, SIGUSR1);
break;
}
}
return inst;
}
@ -516,10 +552,9 @@ static int wait_all(NOARGS)
*/
static void fsck_device(char *device, int interactive)
{
const char *type = 0;
char *type = 0;
struct fs_info *fsent;
int retval;
char prog[80];
if (fstype && strncmp(fstype, "no", 2) && !strchr(fstype, ','))
type = fstype;
@ -532,12 +567,11 @@ static void fsck_device(char *device, int interactive)
if (!type)
type = DEFAULT_FSTYPE;
sprintf(prog, "fsck.%s", type);
retval = execute(prog, device, fsent ? fsent->mountpt : 0,
retval = execute(type, device, fsent ? fsent->mountpt : 0,
interactive);
if (retval) {
fprintf(stderr, "%s: Error %d while executing %s for %s\n",
progname, retval, prog, device);
fprintf(stderr, "%s: Error %d while executing fsck.%s "
"for %s\n", progname, retval, type, device);
}
}
@ -632,15 +666,12 @@ static const char *base_device(char *device)
static int device_already_active(char *device)
{
struct fsck_instance *inst;
const char *base;
base = base_device(device);
const char *base = base_device(device);
for (inst = instance_list; inst; inst = inst->next) {
if (!strcmp(base, base_device(inst->device)))
return 1;
}
return 0;
}
@ -742,7 +773,7 @@ static int check_all(NOARGS)
static void usage(NOARGS)
{
fprintf(stderr,
"Usage: fsck [-AV] [-t fstype] [fs-options] filesys\n");
"Usage: fsck [-ACNPRTV] [-t fstype] [fs-options] filesys\n");
exit(EXIT_USAGE);
}
@ -794,6 +825,9 @@ static void PRS(int argc, char *argv[])
case 'A':
doall++;
break;
case 'C':
progress++;
break;
case 'V':
verbose++;
break;

View File

@ -40,6 +40,7 @@ struct fs_info {
};
#define FLAG_DONE 1
#define FLAG_PROGRESS 2
/*
* Structure to allow exit codes to be stored
@ -49,6 +50,7 @@ struct fsck_instance {
int flags;
int exit_status;
char * prog;
char * type;
char * device;
struct fsck_instance *next;
};

View File

@ -70,6 +70,10 @@ mke2fs \- create a Linux second extended file system
.B \-S
]
[
.B \-T
.I filesystem-type
]
[
.B \-V
]
.I device
@ -105,9 +109,13 @@ Specify the bytes/inode ratio.
.B mke2fs
creates an inode for every
.I bytes-per-inode
bytes of space on the disk. This value defaults to 4096 bytes.
.I bytes-per-inode
must be at least 1024.
bytes of space on the disk.
The larger the bytes-per-inode ratio, the fewer inodes will be created.
This value generally shouldn't be smaller than
the blocksize of the filesystem, since then too many inodes will be made.
Be warned that is not possible to expand the number of inodes on a
filesystem after it is created, so be careful decided the correct
value for this parameter.
.TP
.I -N number-of-inodes
overrides the default calculation of the number of inodes that should be
@ -189,8 +197,13 @@ and the block and inode bitmaps. The
program should be run immediately after this option is used, and there
is no guarantee that any data will be salvageable.
.TP
.I -T fs-type
Specify how the filesystem is going to be used, so that mke2fs can
automatically determine the optimal filesystem parameters. The only
filesystem type which is currently supported is "news".
.TP
.I -V
print the version number of
Print the version number of
.B mke2fs
and exit.
.SH AUTHOR

View File

@ -74,6 +74,7 @@ int verbose = 0;
int quiet = 0;
int super_only = 0;
int force = 0;
int noaction = 0;
char *bad_blocks_filename = 0;
__u32 fs_stride = 0;
@ -186,6 +187,59 @@ static void check_mount(NOARGS)
}
}
/*
* This function sets the default parameters for a filesystem
*
* The type is specified by the user. The size is minimum size for
* which a set of parameters applies, with a size of zero meaning that
* it is the default parameter for the type. Note that order is
* important in the table below.
*/
static char default_str[] = "default";
struct mke2fs_defaults {
char *type;
int size;
int blocksize;
int inode_ratio;
} settings[] = {
{ default_str, 0, 4096, 8192 },
{ default_str, 512, 1024, 4096 },
{ default_str, 3, 1024, 8192 },
{ "news", 0, 4096, 4096 },
{ 0, 0, 0, 0},
};
static void set_fs_defaults(char *fs_type, struct ext2fs_sb *param,
int blocksize, int *inode_ratio)
{
int megs;
int ratio = 0;
struct mke2fs_defaults *p;
megs = (param->s_blocks_count * (EXT2_BLOCK_SIZE(param) / 1024) /
1024);
if (inode_ratio)
ratio = *inode_ratio;
if (!fs_type)
fs_type = default_str;
for (p = settings; p->type; p++) {
if ((strcmp(p->type, fs_type) != 0) &&
(strcmp(p->type, default_str) != 0))
continue;
if ((p->size != 0) &&
(megs > p->size))
continue;
if (ratio == 0)
*inode_ratio = p->inode_ratio;
if (blocksize == 0) {
param->s_log_frag_size = param->s_log_block_size =
log2(p->blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
}
}
if (blocksize == 0)
param->s_blocks_count /= EXT2_BLOCK_SIZE(param) / 1024;
}
/*
* Helper function for read_bb_file and test_disk
*/
@ -420,6 +474,7 @@ static void create_lost_and_found(ext2_filsys fs)
ino_t ino;
const char *name = "lost+found";
int i;
int lpf_size = 0;
retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, 0, name);
if (retval) {
@ -434,6 +489,8 @@ static void create_lost_and_found(ext2_filsys fs)
}
for (i=1; i < EXT2_NDIR_BLOCKS; i++) {
if ((lpf_size += fs->blocksize) >= 16*1024)
break;
retval = ext2fs_expand_dir(fs, ino);
if (retval) {
com_err("ext2fs_expand_dir", retval,
@ -499,27 +556,28 @@ static void show_stats(ext2_filsys fs)
if (param.s_blocks_count != s->s_blocks_count)
printf("warning: %d blocks unused.\n\n",
param.s_blocks_count - s->s_blocks_count);
memset(buf, 0, sizeof(buf));
strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
printf("Filesystem label=%s\n", buf);
printf("OS type: ");
switch (fs->super->s_creator_os) {
case EXT2_OS_LINUX: printf ("Linux"); break;
case EXT2_OS_HURD: printf ("GNU/hurd"); break;
case EXT2_OS_MASIX: printf ("Masix"); break;
default: printf ("(unknown os)");
}
printf (" ext2 filesystem format\n");
memset(buf, 0, sizeof(buf));
strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
printf("Filesystem label=%s\n", buf);
printf("\n");
printf("Block size=%u (log=%u)\n", fs->blocksize,
s->s_log_block_size);
printf("Fragment size=%u (log=%u)\n", fs->fragsize,
s->s_log_frag_size);
printf("%u inodes, %u blocks\n", s->s_inodes_count,
s->s_blocks_count);
printf("%u blocks (%2.2f%%) reserved for the super user\n",
s->s_r_blocks_count,
100.0 * s->s_r_blocks_count / s->s_blocks_count);
printf("First data block=%u\n", s->s_first_data_block);
printf("Block size=%u (log=%u)\n", fs->blocksize,
s->s_log_block_size);
printf("Fragment size=%u (log=%u)\n", fs->fragsize,
s->s_log_frag_size);
printf("%lu block group%s\n", fs->group_desc_count,
(fs->group_desc_count > 1) ? "s" : "");
printf("%u blocks per group, %u fragments per group\n",
@ -647,14 +705,16 @@ static void PRS(int argc, char *argv[])
int size;
char * tmp;
blk_t max = 8192;
int inode_ratio = 4096;
int blocksize = 0;
int inode_ratio = 0;
int reserved_ratio = 5;
ino_t num_inodes = 0;
errcode_t retval;
int sparse_option = -1;
int sparse_option = 1;
char *oldpath = getenv("PATH");
struct ext2fs_sb *param_ext2 = (struct ext2fs_sb *) &param;
char *raid_opts = 0;
char *fs_type = 0;
blk_t dev_size;
/* Update our PATH to include /sbin */
@ -673,6 +733,7 @@ static void PRS(int argc, char *argv[])
setbuf(stderr, NULL);
initialize_ext2_error_table();
memset(&param, 0, sizeof(struct ext2_super_block));
param.s_rev_level = 1; /* Create revision 1 filesystems now */
fprintf (stderr, "mke2fs %s, %s for EXT2 FS %s, %s\n",
E2FSPROGS_VERSION, E2FSPROGS_DATE,
@ -680,18 +741,18 @@ static void PRS(int argc, char *argv[])
if (argc && *argv)
program_name = *argv;
while ((c = getopt (argc, argv,
"b:cf:g:i:l:m:o:qr:R:s:tvI:SFL:M:N:V")) != EOF)
"b:cf:g:i:l:m:no:qr:R:s:tvI:ST:FL:M:N:V")) != EOF)
switch (c) {
case 'b':
size = strtoul(optarg, &tmp, 0);
if (size < 1024 || size > 4096 || *tmp) {
blocksize = strtoul(optarg, &tmp, 0);
if (blocksize < 1024 || blocksize > 4096 || *tmp) {
com_err(program_name, 0, "bad block size - %s",
optarg);
exit(1);
}
param.s_log_block_size =
log2(size >> EXT2_MIN_BLOCK_LOG_SIZE);
max = size * 8;
log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
max = blocksize * 8;
break;
case 'c':
case 't': /* Check for bad blocks */
@ -749,6 +810,9 @@ static void PRS(int argc, char *argv[])
exit(1);
}
break;
case 'n':
noaction++;
break;
case 'o':
creator_os = optarg;
break;
@ -787,6 +851,9 @@ static void PRS(int argc, char *argv[])
case 'S':
super_only = 1;
break;
case 'T':
fs_type = optarg;
break;
case 'V':
/* Print version number and exit */
fprintf(stderr, "\tUsing %s\n",
@ -819,9 +886,13 @@ static void PRS(int argc, char *argv[])
param.s_log_frag_size = param.s_log_block_size;
retval = ext2fs_get_device_size(device_name,
EXT2_BLOCK_SIZE(&param),
&dev_size);
if (noaction && param.s_blocks_count) {
dev_size = param.s_blocks_count;
retval = 0;
} else
retval = ext2fs_get_device_size(device_name,
EXT2_BLOCK_SIZE(&param),
&dev_size);
if (retval && (retval != EXT2_ET_UNIMPLEMENTED)) {
com_err(program_name, retval,
"while trying to determine filesystem size");
@ -842,6 +913,8 @@ static void PRS(int argc, char *argv[])
proceed_question();
}
set_fs_defaults(fs_type, param_ext2, blocksize, &inode_ratio);
if (param.s_blocks_per_group) {
if (param.s_blocks_per_group < 256 ||
param.s_blocks_per_group > max || *tmp) {
@ -929,9 +1002,12 @@ int main (int argc, char *argv[])
sizeof(s->s_last_mounted));
}
if (!quiet)
if (!quiet || noaction)
show_stats(fs);
if (noaction)
exit(0);
if (bad_blocks_filename)
read_bb_file(fs, &bb_list, bad_blocks_filename);
if (cflag)