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

mke2fs.c(main): Expand the -j option so that it parses option=argument
  	style options, and add support for creating filesystems with external
  	journals.
  mke2fs.8.in: Document new syntax for the -j option.
This commit is contained in:
Theodore Ts'o 2000-11-17 04:55:24 +00:00
parent 72ed126483
commit 8ddaa66bfe
3 changed files with 140 additions and 18 deletions

View File

@ -1,3 +1,11 @@
2000-11-16 Theodore Ts'o <tytso@valinux.com>
* mke2fs.c(main): Expand the -j option so that it parses
option=argument style options, and add support for
creating filesystems with external journals.
* mke2fs.8.in: Document new syntax for the -j option.
2000-11-05 <tytso@snap.thunk.org> 2000-11-05 <tytso@snap.thunk.org>
* e2image.c, Makefile.in: New program which saves ext2 metadata to * e2image.c, Makefile.in: New program which saves ext2 metadata to

View File

@ -30,7 +30,7 @@ mke2fs \- create a Linux second extended file system
] ]
[ [
.B \-j .B \-j
.I megabytes-for-journal .I journal-options
] ]
[ [
.B \-N .B \-N
@ -138,11 +138,26 @@ 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 filesystem after it is created, so be careful decided the correct
value for this parameter. value for this parameter.
.TP .TP
.BI \-j " megabytes-for-journal" .BI \-j " journal options"
Build the ext2 filesystem with the ext3 journaling feature enabled. Build the ext2 filesystem with the ext3 journaling feature enabled.
Megabyts-for-journal specifies the size of the journal in MB Journal options are comma
(1024*1024 bytes). Any size between 4MB and 100MB may be used. separated, and may take an argument using the equals ('=') sign.
Of course, the journal must be small enough to fit into the filesystem. Currently two options are supported,
.I size
and
.IR device .
One of these two options must be specified when building the journal.
The
.I size
option takes a numerical argument which specifies the size of the
journal in MB (1024*1024 bytes). Any size between 4MB and 100MB may be used.
Use of this option implies that the journal will be stored in the
filesystem, so it must be small enough to fit into the filesystem.
The
.I device
option takes a filename which specifies a block device which will contain
the journal. This option of course implies that the journal will be
stored external to the filesystem.
.TP .TP
.B \-n .B \-n
causes mke2fs to not actually create a filesystem, but display what it causes mke2fs to not actually create a filesystem, but display what it

View File

@ -87,8 +87,11 @@ struct ext2_super_block param;
char *creator_os = NULL; char *creator_os = NULL;
char *volume_label = NULL; char *volume_label = NULL;
char *mount_dir = NULL; char *mount_dir = NULL;
char *journal_device = NULL;
static void usage(NOARGS), check_plausibility(NOARGS), check_mount(NOARGS); static void usage(NOARGS);
static void check_plausibility(const char *device);
static void check_mount(const char *device);
static void usage(NOARGS) static void usage(NOARGS)
{ {
@ -142,7 +145,7 @@ static void proceed_question(NOARGS)
#define SCSI_BLK_MAJOR(M) ((M) == SCSI_DISK_MAJOR || (M) == SCSI_CDROM_MAJOR) #define SCSI_BLK_MAJOR(M) ((M) == SCSI_DISK_MAJOR || (M) == SCSI_CDROM_MAJOR)
#endif #endif
static void check_plausibility(NOARGS) static void check_plausibility(const char *device)
{ {
#ifdef HAVE_LINUX_MAJOR_H #ifdef HAVE_LINUX_MAJOR_H
#ifndef MAJOR #ifndef MAJOR
@ -153,18 +156,18 @@ static void check_plausibility(NOARGS)
int val; int val;
struct stat s; struct stat s;
val = stat(device_name, &s); val = stat(device, &s);
if(val == -1) { if(val == -1) {
fprintf(stderr, _("Could not stat %s --- %s\n"), fprintf(stderr, _("Could not stat %s --- %s\n"),
device_name, error_message(errno)); device, error_message(errno));
if (errno == ENOENT) if (errno == ENOENT)
fprintf(stderr, _("\nThe device apparently does " fprintf(stderr, _("\nThe device apparently does "
"not exist; did you specify it correctly?\n")); "not exist; did you specify it correctly?\n"));
exit(1); exit(1);
} }
if(!S_ISBLK(s.st_mode)) { if(!S_ISBLK(s.st_mode)) {
printf(_("%s is not a block special device.\n"), device_name); printf(_("%s is not a block special device.\n"), device);
proceed_question(); proceed_question();
return; return;
} else if ((MAJOR(s.st_rdev) == HD_MAJOR && } else if ((MAJOR(s.st_rdev) == HD_MAJOR &&
@ -172,28 +175,28 @@ static void check_plausibility(NOARGS)
(SCSI_BLK_MAJOR(MAJOR(s.st_rdev)) && (SCSI_BLK_MAJOR(MAJOR(s.st_rdev)) &&
MINOR(s.st_rdev)%16 == 0)) { MINOR(s.st_rdev)%16 == 0)) {
printf(_("%s is entire device, not just one partition!\n"), printf(_("%s is entire device, not just one partition!\n"),
device_name); device);
proceed_question(); proceed_question();
} }
#endif #endif
} }
static void check_mount(NOARGS) static void check_mount(const char *device)
{ {
errcode_t retval; errcode_t retval;
int mount_flags; int mount_flags;
retval = ext2fs_check_if_mounted(device_name, &mount_flags); retval = ext2fs_check_if_mounted(device, &mount_flags);
if (retval) { if (retval) {
com_err("ext2fs_check_if_mount", retval, com_err("ext2fs_check_if_mount", retval,
_("while determining whether %s is mounted."), _("while determining whether %s is mounted."),
device_name); device);
return; return;
} }
if (!(mount_flags & EXT2_MF_MOUNTED)) if (!(mount_flags & EXT2_MF_MOUNTED))
return; return;
fprintf(stderr, _("%s is mounted; "), device_name); fprintf(stderr, _("%s is mounted; "), device);
if (force) { if (force) {
fprintf(stderr, _("mke2fs forced anyway. " fprintf(stderr, _("mke2fs forced anyway. "
"Hope /etc/mtab is incorrect.\n")); "Hope /etc/mtab is incorrect.\n"));
@ -719,6 +722,76 @@ static void parse_raid_opts(const char *opts)
} }
} }
static void parse_journal_opts(const char *opts)
{
char *buf, *token, *next, *p, *arg;
int len;
int journal_usage = 0;
len = strlen(opts);
buf = malloc(len+1);
if (!buf) {
fprintf(stderr, _("Couldn't allocate memory to parse "
"journal options!\n"));
exit(1);
}
strcpy(buf, opts);
for (token = buf; token && *token; token = next) {
p = strchr(token, ',');
next = 0;
if (p) {
*p = 0;
next = p+1;
}
arg = strchr(token, '=');
if (arg) {
*arg = 0;
arg++;
}
printf("Journal option=%s, argument=%s\n", token,
arg ? arg : "NONE");
if (strcmp(token, "device") == 0) {
if (!arg) {
journal_usage++;
continue;
}
journal_device = arg;
} else if (strcmp(token, "size") == 0) {
if (!arg) {
journal_usage++;
continue;
}
journal_size = strtoul(arg, &p, 0);
journal_size_check:
if (*p || (journal_size < 4 || journal_size > 100)) {
fprintf(stderr,
_("Invalid journal size parameter - %s.\n"),
arg);
journal_usage++;
continue;
}
} else {
journal_size = strtoul(token, &p, 0);
if (*p)
journal_usage++;
else
goto journal_size_check;
}
}
if (journal_usage) {
fprintf(stderr, _("\nBad journal options specified.\n\n"
"Journal options are separated by commas, "
"and may take an argument which\n"
"\tis set off by an equals ('=') sign.\n\n"
"Valid raid options are:\n"
"\tsize=<journal size in megabytes>\n"
"\tdevice=<journal device>\n\n"
"Journal size must be between "
"4 and 100 megabytes.\n\n" ));
exit(1);
}
}
static __u32 ok_features[3] = { static __u32 ok_features[3] = {
0, /* Compat */ 0, /* Compat */
EXT2_FEATURE_INCOMPAT_FILETYPE, /* Incompat */ EXT2_FEATURE_INCOMPAT_FILETYPE, /* Incompat */
@ -741,6 +814,7 @@ static void PRS(int argc, char *argv[])
char * oldpath = getenv("PATH"); char * oldpath = getenv("PATH");
struct ext2fs_sb *param_ext2 = (struct ext2fs_sb *) &param; struct ext2fs_sb *param_ext2 = (struct ext2fs_sb *) &param;
char * raid_opts = 0; char * raid_opts = 0;
char * journal_opts = 0;
char * fs_type = 0; char * fs_type = 0;
const char * feature_set = "filetype"; const char * feature_set = "filetype";
blk_t dev_size; blk_t dev_size;
@ -833,12 +907,16 @@ static void PRS(int argc, char *argv[])
} }
break; break;
case 'j': case 'j':
journal_opts = optarg;
break;
#if 0
journal_size = strtoul(optarg, &tmp, 0); journal_size = strtoul(optarg, &tmp, 0);
if (journal_size < 4 || journal_size > 100 || *tmp) { if (journal_size < 4 || journal_size > 100 || *tmp) {
com_err(program_name, 0, com_err(program_name, 0,
_("bad journal size - %s"), optarg); _("bad journal size - %s"), optarg);
exit(1); exit(1);
} }
#endif
break; break;
case 'l': case 'l':
bad_blocks_filename = malloc(strlen(optarg)+1); bad_blocks_filename = malloc(strlen(optarg)+1);
@ -933,9 +1011,12 @@ static void PRS(int argc, char *argv[])
if (raid_opts) if (raid_opts)
parse_raid_opts(raid_opts); parse_raid_opts(raid_opts);
if (journal_opts)
parse_journal_opts(journal_opts);
if (!force) if (!force)
check_plausibility(); check_plausibility(device_name);
check_mount(); check_mount(device_name);
param.s_log_frag_size = param.s_log_block_size; param.s_log_frag_size = param.s_log_block_size;
@ -1125,7 +1206,25 @@ int main (int argc, char *argv[])
zap_sector(fs, 0); zap_sector(fs, 0);
#endif #endif
} }
if (journal_size) {
if (journal_device) {
if (!force)
check_plausibility(journal_device);
check_mount(journal_device);
if (!quiet)
printf(_("Creating journal on device %s: "),
journal_device);
retval = ext2fs_add_journal_device(fs, journal_device, 0);
if(retval) {
com_err (program_name, retval,
_("while trying to create journal on device %s"),
journal_device);
exit(1);
}
if (!quiet)
printf(_("done\n"));
} else if (journal_size) {
if (!quiet) if (!quiet)
printf(_("Creating journal: ")); printf(_("Creating journal: "));
journal_blocks = journal_size * 1024 / journal_blocks = journal_size * 1024 /