diff options
author | Theodore Ts'o <tytso@mit.edu> | 2001-01-16 07:47:31 +0000 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2001-01-16 07:47:31 +0000 |
commit | 16ed5b3af43c72f60991222b9d7ab65cf53f203d (patch) | |
tree | fd0f2439b29b07d173fcaee571bfbb401f370ac6 | |
parent | a112847b39386f9e7332ba5e5a0a5e54cfe301cc (diff) | |
download | e2fsprogs-16ed5b3af43c72f60991222b9d7ab65cf53f203d.tar.gz |
ChangeLog, Makefile.in, dumpe2fs.c, jfs_user.h, mke2fs.c, tune2fs.c:
tune2fs.c: Changed the external journal code so that it simply adds a
filesystem to a journal; the journal must have bene created via
"mke2fs -O journal_dev /dev/XXX".
mke2fs.c: Add support for creating an external journal device by using
the command "mke2fs -O journal_dev /dev/XXX". Also changed the
external journal code so -j device=/dev/XXX it simply adds a
filesystem to that journal; the journal must have been created via
separate step.
dumpe2fs.c (print_journal_information): Add support for dumping
information about an external journal device.
-rw-r--r-- | misc/ChangeLog | 15 | ||||
-rw-r--r-- | misc/Makefile.in | 4 | ||||
-rw-r--r-- | misc/dumpe2fs.c | 56 | ||||
-rw-r--r-- | misc/jfs_user.h | 9 | ||||
-rw-r--r-- | misc/mke2fs.c | 277 | ||||
-rw-r--r-- | misc/tune2fs.c | 16 |
6 files changed, 302 insertions, 75 deletions
diff --git a/misc/ChangeLog b/misc/ChangeLog index 8d85d4f7..a36582f9 100644 --- a/misc/ChangeLog +++ b/misc/ChangeLog @@ -1,3 +1,18 @@ +2001-01-15 Theodore Ts'o <tytso@valinux.com> + + * tune2fs.c: Changed the external journal code so that it simply + adds a filesystem to a journal; the journal must have bene + created via "mke2fs -O journal_dev /dev/XXX". + + * mke2fs.c: Add support for creating an external journal device by + using the command "mke2fs -O journal_dev /dev/XXX". Also + changed the external journal code so -j device=/dev/XXX it + simply adds a filesystem to that journal; the journal must + have been created via separate step. + + * dumpe2fs.c (print_journal_information): Add support for dumping + information about an external journal device. + 2001-01-14 Theodore Ts'o <tytso@valinux.com> * mke2fs.c: Add new filesystem types, largefile and largefile4, diff --git a/misc/Makefile.in b/misc/Makefile.in index bc76132c..02d1d16a 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -87,8 +87,8 @@ lsattr: $(LSATTR_OBJS) $(DEPLIBS_E2P) uuidgen: $(UUIDGEN_OBJS) $(DEPLIBUUID) $(CC) $(ALL_LDFLAGS) -o uuidgen $(UUIDGEN_OBJS) $(LIBUUID) -dumpe2fs: $(DUMPE2FS_OBJS) $(DEPLIBS_E2P) - $(CC) $(ALL_LDFLAGS) -o dumpe2fs $(DUMPE2FS_OBJS) $(LIBS_E2P) +dumpe2fs: $(DUMPE2FS_OBJS) $(DEPLIBS_E2P) $(DEPLIBUUID) + $(CC) $(ALL_LDFLAGS) -o dumpe2fs $(DUMPE2FS_OBJS) $(LIBS_E2P) $(LIBUUID) fsck: $(FSCK_OBJS) $(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBS) diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 17bf4c16..53ef32a3 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -36,6 +36,7 @@ extern int optind; #include "ext2fs/ext2fs.h" #include "e2p/e2p.h" +#include "jfs_user.h" #include "../version.h" #include "nls-enable.h" @@ -207,6 +208,46 @@ static int i386_byteorder(void) return (*cp == 1); } +static void print_journal_information(ext2_filsys fs) +{ + errcode_t retval; + char buf[1024]; + char str[80]; + int i; + journal_superblock_t *jsb; + + /* Get the journal superblock */ + if ((retval = io_channel_read_blk(fs->io, 1, -1024, buf))) { + com_err(program_name, retval, + _("while reading journal superblock")); + exit(1); + } + jsb = (journal_superblock_t *) buf; + if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) || + (jsb->s_header.h_blocktype != + (unsigned) ntohl(JFS_SUPERBLOCK_V2))) { + com_err(program_name, 0, + _("Couldn't find journal superblock magic numbers")); + exit(1); + } + + fputs("\n", stdout); + printf("Journal block size: %d\n", ntohl(jsb->s_blocksize)); + printf("Journal length: %d\n", ntohl(jsb->s_maxlen)); + printf("Journal first block: %d\n", ntohl(jsb->s_first)); + printf("Journal sequence: 0x%08x\n", ntohl(jsb->s_sequence)); + printf("Journal start: %d\n", ntohl(jsb->s_start)); + printf("Journal number of users: %d\n", ntohl(jsb->s_nr_users)); + for (i=0; i < ntohl(jsb->s_nr_users); i++) { + if (i) + printf(" "); + else + printf("Journal users: "); + uuid_unparse(&jsb->s_users[i*16], str); + printf("%s\n", str); + } +} + int main (int argc, char ** argv) { errcode_t retval; @@ -215,6 +256,7 @@ int main (int argc, char ** argv) int use_superblock = 0; int use_blocksize = 0; int force = 0; + int flags; int header_only = 0; int big_endian; int c; @@ -267,9 +309,11 @@ int main (int argc, char ** argv) device_name = argv[optind++]; if (use_superblock && !use_blocksize) use_blocksize = 1024; - retval = ext2fs_open (device_name, force ? EXT2_FLAG_FORCE : 0, - use_superblock, use_blocksize, - unix_io_manager, &fs); + flags = EXT2_FLAG_JOURNAL_DEV_OK; + if (force) + flags |= EXT2_FLAG_FORCE; + retval = ext2fs_open (device_name, flags, use_superblock, + use_blocksize, unix_io_manager, &fs); if (retval) { com_err (program_name, retval, _("while trying to open %s"), device_name); @@ -285,6 +329,12 @@ int main (int argc, char ** argv) if (big_endian) printf(_("Note: This is a byte-swapped filesystem\n")); list_super (fs->super); + if (fs->super->s_feature_incompat & + EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { + print_journal_information(fs); + ext2fs_close(fs); + exit(0); + } list_bad_blocks (fs); if (header_only) { ext2fs_close (fs); diff --git a/misc/jfs_user.h b/misc/jfs_user.h new file mode 100644 index 00000000..17a82c7b --- /dev/null +++ b/misc/jfs_user.h @@ -0,0 +1,9 @@ +#ifndef _JFS_USER_H +#define _JFS_USER_H + +typedef unsigned short kdev_t; + +#include <linux/jfs.h> + + +#endif /* _JFS_USER_H */ diff --git a/misc/mke2fs.c b/misc/mke2fs.c index b72ea1b2..a52d6324 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -67,22 +67,23 @@ const char * program_name = "mke2fs"; const char * device_name /* = NULL */; /* Command line options */ -int cflag /* = 0 */ ; -int verbose /* = 0 */ ; -int quiet /* = 0 */ ; -int super_only /* = 0 */ ; -int force /* = 0 */ ; -int noaction /* = 0 */ ; -int journal_size /* = 0 */ ; -int journal_flags /* = 0 */ ; -char *bad_blocks_filename /* = 0 */ ; -__u32 fs_stride /* = 0 */ ; +int cflag; +int verbose; +int quiet; +int super_only; +int force; +int noaction; +int journal_size; +int journal_flags; +char *bad_blocks_filename; +__u32 fs_stride; struct ext2_super_block param; -char *creator_os /* = NULL */ ; -char *volume_label /* = NULL */ ; -char *mount_dir /* = NULL */ ; -char *journal_device /* = NULL */ ; +char *creator_os; +char *volume_label; +char *mount_dir; +char *journal_device; +int sync_kludge; /* Set using the MKE2FS_SYNC env. option */ static void usage(void) { @@ -307,60 +308,143 @@ _("Warning: the backup superblock/group descriptors at block %d contain\n" badblocks_list_iterate_end(bb_iter); } -static void write_inode_tables(ext2_filsys fs) -{ - errcode_t retval; - blk_t blk; - int i, j, num, count; - char *buf; - char format[20], backup[80]; - int sync_kludge = 0; - char *mke2fs_sync; +/* + * These functions implement a generalized progress meter. + */ +struct progress_struct { + char format[20]; + char backup[80]; + __u32 max; +}; - mke2fs_sync = getenv("MKE2FS_SYNC"); - if (mke2fs_sync) - sync_kludge = atoi(mke2fs_sync); +static void progress_init(struct progress_struct *progress, + char *label,__u32 max) +{ + int i; - buf = malloc(fs->blocksize * STRIDE_LENGTH); - if (!buf) { - com_err("malloc", ENOMEM, - _("while allocating zeroizing buffer")); - exit(1); - } - memset(buf, 0, fs->blocksize * STRIDE_LENGTH); + memset(progress, 0, sizeof(struct progress_struct)); + if (quiet) + return; /* * Figure out how many digits we need */ - i = int_log10(fs->group_desc_count); - sprintf(format, "%%%dd/%%%dld", i, i); - memset(backup, '\b', sizeof(backup)-1); - backup[sizeof(backup)-1] = 0; - if ((2*i)+1 < sizeof(backup)) - backup[(2*i)+1] = 0; + i = int_log10(max); + sprintf(progress->format, "%%%dd/%%%dld", i, i); + memset(progress->backup, '\b', sizeof(progress->backup)-1); + progress->backup[sizeof(progress->backup)-1] = 0; + if ((2*i)+1 < sizeof(progress->backup)) + progress->backup[(2*i)+1] = 0; + progress->max = max; + + fputs(label, stdout); + fflush(stdout); +} + +static void progress_update(struct progress_struct *progress, __u32 val) +{ + if (progress->format[0] == 0) + return; + printf(progress->format, val, progress->max); + fputs(progress->backup, stdout); +} + +static void progress_close(struct progress_struct *progress) +{ + if (progress->format[0] == 0) + return; + fputs(_("done \n"), stdout); +} + + +/* + * Helper function which zeros out _num_ blocks starting at _blk_. In + * case of an error, the details of the error is returned via _ret_blk_ + * and _ret_count_ if they are non-NULL pointers. Returns 0 on + * success, and an error code on an error. + * + * As a special case, if the first argument is NULL, then it will + * attempt to free the static zeroizing buffer. (This is to keep + * programs that check for memory leaks happy.) + */ +static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num, + struct progress_struct *progress, + blk_t *ret_blk, int *ret_count) +{ + int j, count, next_update, next_update_incr; + static char *buf; + errcode_t retval; + + /* If fs is null, clean up the static buffer and return */ + if (!fs) { + if (buf) { + free(buf); + buf = 0; + } + return 0; + } + /* Allocate the zeroizing buffer if necessary */ + if (!buf) { + buf = malloc(fs->blocksize * STRIDE_LENGTH); + if (!buf) { + com_err("malloc", ENOMEM, + _("while allocating zeroizing buffer")); + exit(1); + } + memset(buf, 0, fs->blocksize * STRIDE_LENGTH); + } + /* OK, do the write loop */ + next_update = 0; + next_update_incr = num / 100; + if (next_update_incr < 1) + next_update_incr = 1; + for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { + if (num-j > STRIDE_LENGTH) + count = STRIDE_LENGTH; + else + count = num - j; + retval = io_channel_write_blk(fs->io, blk, count, buf); + if (retval) { + if (ret_count) + *ret_count = count; + if (ret_blk) + *ret_blk = blk; + return retval; + } + if (progress && j > next_update) { + next_update += num / 100; + progress_update(progress, blk); + } + } + return 0; +} + +static void write_inode_tables(ext2_filsys fs) +{ + errcode_t retval; + blk_t blk; + int i, num; + struct progress_struct progress; + + if (quiet) + memset(&progress, 0, sizeof(progress)); + else + progress_init(&progress, _("Writing inode tables: "), + fs->group_desc_count); - if (!quiet) - printf(_("Writing inode tables: ")); for (i = 0; i < fs->group_desc_count; i++) { - if (!quiet) - printf(format, i, fs->group_desc_count); + progress_update(&progress, i); blk = fs->group_desc[i].bg_inode_table; num = fs->inode_blocks_per_group; - - for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { - if (num-j > STRIDE_LENGTH) - count = STRIDE_LENGTH; - else - count = num - j; - retval = io_channel_write_blk(fs->io, blk, count, buf); - if (retval) - printf(_("Warning: could not write %d blocks " - "in inode table starting at %d: %s\n"), - count, blk, error_message(retval)); + + retval = zero_blocks(fs, blk, num, 0, &blk, &num); + if (retval) { + printf(_("\nCould not write %d blocks " + "in inode table starting at %d: %s\n"), + num, blk, error_message(retval)); + exit(1); } - if (!quiet) - fputs(backup, stdout); if (sync_kludge) { if (sync_kludge == 1) sync(); @@ -368,9 +452,8 @@ static void write_inode_tables(ext2_filsys fs) sync(); } } - free(buf); - if (!quiet) - fputs(_("done \n"), stdout); + zero_blocks(0, 0, 0, 0, 0, 0); + progress_close(&progress); } static void create_root_dir(ext2_filsys fs) @@ -480,7 +563,45 @@ static void zap_sector(ext2_filsys fs, int sect) printf(_("Warning: could not erase sector %d: %s\n"), sect, error_message(retval)); } - + +static void create_journal_dev(ext2_filsys fs) +{ + struct progress_struct progress; + errcode_t retval; + char *buf; + + if (quiet) + memset(&progress, 0, sizeof(progress)); + else + progress_init(&progress, _("Zeroing journal device: "), + fs->super->s_blocks_count); + +#if 0 + retval = zero_blocks(fs, 0, fs->super->s_blocks_count, + &progress, &blk, &count); + if (retval) { + com_err("create_journal_dev", retval, + "while zeroing journal device (block %u, count %d", + blk, count); + exit(1); + } + zero_blocks(0, 0, 0, 0, 0); +#endif + retval = ext2fs_create_journal_superblock(fs, + fs->super->s_blocks_count, 0, &buf); + if (retval) { + com_err("create_journal_dev", retval, + _("while initialization journal superblock")); + exit(1); + } + retval = io_channel_write_blk(fs->io, 1, 1, buf); + if (retval) { + com_err("create_journal_dev", retval, + _("while writing journal superblock")); + exit(1); + } + progress_close(&progress); +} static void show_stats(ext2_filsys fs) { @@ -622,7 +743,8 @@ static void parse_raid_opts(const char *opts) static __u32 ok_features[3] = { 0, /* Compat */ - EXT2_FEATURE_INCOMPAT_FILETYPE, /* Incompat */ + EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */ + EXT3_FEATURE_INCOMPAT_JOURNAL_DEV, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */ }; @@ -670,6 +792,10 @@ static void PRS(int argc, char *argv[]) } else putenv (PATH_SET); + tmp = getenv("MKE2FS_SYNC"); + if (tmp) + sync_kludge = atoi(tmp); + setbuf(stdout, NULL); setbuf(stderr, NULL); initialize_ext2_error_table(); @@ -1009,6 +1135,13 @@ int main (int argc, char *argv[]) if (noaction) exit(0); + if (fs->super->s_feature_incompat & + EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { + create_journal_dev(fs); + ext2fs_close(fs); + exit(0); + } + if (bad_blocks_filename) read_bb_file(fs, &bb_list, bad_blocks_filename); if (cflag) @@ -1037,25 +1170,35 @@ int main (int argc, char *argv[]) } journal_blocks = journal_size * 1024 / (fs->blocksize / 1024); - if (journal_device) { + if (journal_device) { + ext2_filsys jfs; + if (!force) check_plausibility(journal_device); check_mount(journal_device, force, _("journal")); + retval = ext2fs_open(journal_device, EXT2_FLAG_RW| + EXT2_FLAG_JOURNAL_DEV_OK, 0, + fs->blocksize, unix_io_manager, &jfs); + if (retval) { + com_err(program_name, retval, + _("while trying to open journal device %s\n"), + journal_device); + exit(1); + } if (!quiet) printf(_("Creating journal on device %s: "), journal_device); - retval = ext2fs_add_journal_device(fs, journal_device, - journal_blocks, - journal_flags); - if(retval) { + retval = ext2fs_add_journal_device(fs, jfs); + if(retval) { com_err (program_name, retval, - _("while trying to create journal on device %s"), + _("while trying to add journal to device %s"), journal_device); exit(1); } if (!quiet) printf(_("done\n")); + ext2fs_close(jfs); } else if (journal_size) { if (!quiet) printf(_("Creating journal (%d blocks): "), diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 81b06e0a..ebdc6ce7 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -192,6 +192,7 @@ static void add_journal(ext2_filsys fs) { unsigned long journal_blocks; errcode_t retval; + ext2_filsys jfs; if (fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) { @@ -203,12 +204,20 @@ static void add_journal(ext2_filsys fs) if (journal_device) { check_plausibility(journal_device); check_mount(journal_device, 0, _("journal")); + retval = ext2fs_open(journal_device, EXT2_FLAG_RW| + EXT2_FLAG_JOURNAL_DEV_OK, 0, + fs->blocksize, unix_io_manager, &jfs); + if (retval) { + com_err(program_name, retval, + _("while trying to open journal device %s\n"), + journal_device); + exit(1); + } printf(_("Creating journal on device %s: "), journal_device); fflush(stdout); - retval = ext2fs_add_journal_device(fs, journal_device, - journal_blocks, - journal_flags); + + retval = ext2fs_add_journal_device(fs, jfs); if (retval) { com_err (program_name, retval, _("while trying to create journal on device %s"), @@ -216,6 +225,7 @@ static void add_journal(ext2_filsys fs) exit(1); } printf(_("done\n")); + ext2fs_close(jfs); } else if (journal_size) { printf(_("Creating journal inode: ")); fflush(stdout); |