+Fri Feb 13 17:15:43 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * resize2fs.c, resize2fs.h, ext2_block_move.c, ext2_inode_move.c,
+ main.c: Reorganize how the progress functions are called.
+
Mon Jan 19 09:12:28 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
* resize2fs.h: If EXT2_FLAT_INCLUDES is defined, then assume all
char *block_buf = 0;
int size, c;
int to_move, moved;
- ext2_sim_progmeter progress = 0;
new_blk = fs->super->s_first_data_block;
if (!rfs->itable_buf) {
retval = ext2fs_iterate_extent(bmap, 0, 0, 0);
if (retval) goto errout;
- if (rfs->flags & RESIZE_PERCENT_COMPLETE) {
- retval = ext2fs_progress_init(&progress,
- "Relocating blocks", 30, 40, to_move, 0);
- if (retval)
- return retval;
- }
-
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS, 0, to_move);
+
while (1) {
retval = ext2fs_iterate_extent(bmap, &old_blk, &new_blk, &size);
if (retval) goto errout;
old_blk += c;
moved += c;
io_channel_flush(fs->io);
- if (progress)
- ext2fs_progress_update(progress, moved);
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_BLOCK_RELOC_PASS,
+ moved, to_move);
} while (size > 0);
io_channel_flush(fs->io);
}
- if (progress) {
- ext2fs_progress_close(progress);
- progress = 0;
- }
/*
* Step 3 is where we update the block pointers
retval = ext2fs_get_next_inode(scan, &ino, &inode);
if (retval) goto errout;
-
- if (rfs->flags & RESIZE_PERCENT_COMPLETE) {
- retval = ext2fs_progress_init(&progress,
- "Updating block references", 30, 40,
- old_fs->super->s_inodes_count, 0);
- if (retval)
- return retval;
- }
+
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_BLOCK_REF_UPD_PASS,
+ 0, old_fs->super->s_inodes_count);
while (ino) {
if ((inode.i_links_count == 0) ||
}
next:
- if (progress)
- ext2fs_progress_update(progress, ino);
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_BLOCK_REF_UPD_PASS,
+ ino, old_fs->super->s_inodes_count);
retval = ext2fs_get_next_inode(scan, &ino, &inode);
if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
goto next;
}
retval = 0;
errout:
- if (progress)
- ext2fs_progress_close(progress);
ext2fs_free_extent_table(bmap);
if (scan)
#include "resize2fs.h"
-/*
- * Progress callback
- */
-struct callback_info {
- ext2_sim_progmeter progress;
- int offset;
-};
-
-static errcode_t progress_callback(ext2_filsys fs, ext2_inode_scan scan,
- dgrp_t group, void * priv_data)
-{
- struct callback_info *cb = (struct callback_info *) priv_data;
-
- if (!cb->progress)
- return 0;
-
- ext2fs_progress_update(cb->progress, group - cb->offset + 1);
- return 0;
-}
-
-
struct istruct {
- ext2_sim_progmeter progress;
+ ext2_resize_t rfs;
+ unsigned long max;
ext2_extent imap;
int flags;
int num;
struct istruct *is = (struct istruct *) priv_data;
ino_t new_inode;
- if (is->progress && offset == 0) {
- ext2fs_progress_update(is->progress, ++is->num);
+ if (is->rfs->progress && offset == 0) {
+ (is->rfs->progress)(is->rfs, E2_RSZ_INODE_REF_UPD_PASS,
+ ++is->num, is->max);
}
if (!dirent->inode)
return ret;
}
-static errcode_t get_dblist(ext2_filsys fs, int flags)
+static errcode_t get_dblist(ext2_resize_t rfs)
{
ext2_inode_scan scan = 0;
errcode_t retval;
char *block_buf = 0;
struct process_block_struct pb;
- ext2_sim_progmeter progress = 0;
ino_t ino;
struct ext2_inode inode;
+ ext2_filsys fs = rfs->old_fs;
retval = ext2fs_open_inode_scan(fs, 0, &scan);
if (retval) goto errout;
retval = ext2fs_get_next_inode(scan, &ino, &inode);
if (retval) goto errout;
-
- if (flags & RESIZE_PERCENT_COMPLETE) {
- retval = ext2fs_progress_init(&progress,
- "Finding directories", 30, 40,
- fs->super->s_inodes_count, 0);
- if (retval)
- return retval;
- }
+
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_INODE_FIND_DIR_PASS,
+ 0, fs->super->s_inodes_count);
while (ino) {
if ((inode.i_links_count == 0) ||
}
next:
- if (progress)
- ext2fs_progress_update(progress, ino);
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_INODE_FIND_DIR_PASS,
+ ino, fs->super->s_inodes_count);
retval = ext2fs_get_next_inode(scan, &ino, &inode);
if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
goto next;
retval = 0;
errout:
- if (progress)
- ext2fs_progress_close(progress);
if (scan)
ext2fs_close_inode_scan(scan);
if (block_buf)
return retval;
}
+/*
+ * Progress callback
+ */
+struct callback_info {
+ ext2_resize_t rfs;
+ unsigned long max;
+ int offset;
+};
+
+static errcode_t progress_callback(ext2_filsys fs, ext2_inode_scan scan,
+ dgrp_t group, void * priv_data)
+{
+ struct callback_info *cb = (struct callback_info *) priv_data;
+
+ if (cb->rfs->progress)
+ (cb->rfs->progress)(cb->rfs, E2_RSZ_INODE_RELOC_PASS,
+ group - cb->offset + 1, cb->max);
+
+ return 0;
+}
errcode_t ext2fs_inode_move(ext2_resize_t rfs)
{
int group;
struct istruct is;
struct callback_info callback_info;
- ext2_sim_progmeter progress = 0;
if (rfs->old_fs->group_desc_count <=
rfs->new_fs->group_desc_count)
rfs->new_fs->group_desc_count);
if (retval) goto errout;
+ callback_info.offset = rfs->new_fs->group_desc_count;
+ callback_info.max = (rfs->old_fs->group_desc_count -
+ rfs->new_fs->group_desc_count);
+ callback_info.rfs = rfs;
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_INODE_RELOC_PASS,
+ 0, callback_info.max);
- if (rfs->flags & RESIZE_PERCENT_COMPLETE) {
- callback_info.offset = rfs->new_fs->group_desc_count;
-
- group = (rfs->old_fs->group_desc_count -
- rfs->new_fs->group_desc_count);
-
- retval = ext2fs_progress_init(&progress,
- "Moving inodes", 30, 40, group, 0);
- if (retval)
- return retval;
- ext2fs_set_inode_callback(scan, progress_callback,
- &callback_info);
- }
- callback_info.progress = progress;
+ ext2fs_set_inode_callback(scan, progress_callback,
+ &callback_info);
new_inode = EXT2_FIRST_INODE(rfs->new_fs->super);
/*
ext2fs_add_extent_entry(imap, ino, new_inode);
}
io_channel_flush(rfs->new_fs->io);
- if (progress) {
- ext2fs_progress_close(progress);
- progress = 0;
- }
/*
* Get the list of directory blocks, if necessary
*/
if (!rfs->old_fs->dblist) {
- retval = get_dblist(rfs->old_fs, rfs->flags);
+ retval = get_dblist(rfs);
if (retval) goto errout;
}
/*
* Now, we iterate over all of the directories to update the
* inode references
*/
- if (rfs->flags & RESIZE_PERCENT_COMPLETE) {
- retval = ext2fs_progress_init(&progress,
- "Updating inode references", 30, 40,
- ext2fs_dblist_count(rfs->old_fs->dblist), 0);
- if (retval)
- return retval;
- }
is.imap = imap;
is.flags = rfs->flags;
is.num = 0;
- is.progress = progress;
+ is.max = ext2fs_dblist_count(rfs->old_fs->dblist);
+ is.rfs = rfs;
+ if (rfs->progress)
+ (rfs->progress)(rfs, E2_RSZ_INODE_REF_UPD_PASS,
+ 0, is.max);
+
retval = ext2fs_dblist_dir_iterate(rfs->old_fs->dblist,
DIRENT_FLAG_INCLUDE_EMPTY, 0,
check_and_change_inodes, &is);
/* if (retval) goto errout; */
errout:
- if (progress)
- ext2fs_progress_close(progress);
ext2fs_free_extent_table(imap);
if (scan)
ext2fs_close_inode_scan(scan);
exit (1);
}
+static void resize_progress_func(ext2_resize_t rfs, int pass,
+ unsigned long cur, unsigned long max)
+{
+ ext2_sim_progmeter progress;
+ const char *label;
+ errcode_t retval;
+
+ progress = (ext2_sim_progmeter) rfs->prog_data;
+ if (cur == 0) {
+ if (progress)
+ ext2fs_progress_close(progress);
+ progress = 0;
+ switch (pass) {
+ case E2_RSZ_ADJUST_SUPERBLOCK_PASS:
+ label = "Initializing inode table";
+ break;
+ case E2_RSZ_BLOCK_RELOC_PASS:
+ label = "Relocating blocks";
+ break;
+ case E2_RSZ_BLOCK_REF_UPD_PASS:
+ label = "Updating block references";
+ break;
+ case E2_RSZ_INODE_FIND_DIR_PASS:
+ label = "Finding directories";
+ break;
+ case E2_RSZ_INODE_RELOC_PASS:
+ label = "Moving inodes";
+ break;
+ case E2_RSZ_INODE_REF_UPD_PASS:
+ label = "Updating inode references";
+ break;
+ case E2_RSZ_MOVE_ITABLE_PASS:
+ label = "Moving inode table";
+ break;
+ }
+ printf("Begin pass %d (max = %lu)\n", pass, max);
+ retval = ext2fs_progress_init(&progress, label, 30,
+ 40, max, 0);
+ if (retval)
+ progress = 0;
+ rfs->prog_data = (void *) progress;
+ }
+ if (progress)
+ ext2fs_progress_update(progress, cur);
+ if (cur >= max) {
+ if (progress)
+ ext2fs_progress_close(progress);
+ progress = 0;
+ rfs->prog_data = 0;
+ }
+}
+
void main (int argc, char ** argv)
{
errcode_t retval;
printf ("Couldn't find valid filesystem superblock.\n");
exit (1);
}
- retval = resize_fs(fs, new_size, flags);
+ retval = resize_fs(fs, new_size, flags, resize_progress_func);
if (retval) {
com_err(program_name, retval, "while trying to resize %s",
device_name);
blk_t blk, group_block;
unsigned long i, j;
int old_numblocks, numblocks, adjblocks;
- ext2_sim_progmeter progress = 0;
+ unsigned long max_group;
fs = rfs->new_fs;
fs->super->s_blocks_count = new_size;
group_block = fs->super->s_first_data_block +
rfs->old_fs->group_desc_count * fs->super->s_blocks_per_group;
- if (rfs->flags & RESIZE_PERCENT_COMPLETE) {
- adj = rfs->old_fs->group_desc_count;
- retval = ext2fs_progress_init(&progress,
- "Initializing inode table", 30, 40,
- fs->group_desc_count - adj, 0);
- if (retval) goto errout;
- }
+ adj = rfs->old_fs->group_desc_count;
+ max_group = fs->group_desc_count - adj;
+ if (rfs->progress)
+ rfs->progress(rfs, E2_RSZ_ADJUST_SUPERBLOCK_PASS,
+ 0, max_group);
for (i = rfs->old_fs->group_desc_count;
i < fs->group_desc_count; i++) {
memset(&fs->group_desc[i], 0,
if (retval) goto errout;
/* io_channel_flush(fs->io); */
- if (progress)
- ext2fs_progress_update(progress, i - adj + 1);
+ if (rfs->progress)
+ rfs->progress(rfs, E2_RSZ_ADJUST_SUPERBLOCK_PASS,
+ i - adj + 1, max_group);
group_block += fs->super->s_blocks_per_group;
}
retval = 0;
errout:
- if (progress)
- ext2fs_progress_close(progress);
return retval;
}
char *cp;
blk_t old_blk, new_blk;
errcode_t retval, err;
- ext2_sim_progmeter progress = 0;
int to_move, moved;
max = fs->group_desc_count;
if (to_move == 0)
return 0;
- if (rfs->flags & RESIZE_PERCENT_COMPLETE) {
- retval = ext2fs_progress_init(&progress,
- "Moving inode table", 30, 40, to_move, 0);
- if (retval)
- return retval;
- }
-
+ if (rfs->progress)
+ rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS, 0, to_move);
+
for (i=0; i < max; i++) {
old_blk = rfs->old_fs->group_desc[i].bg_inode_table;
new_blk = fs->group_desc[i].bg_inode_table;
goto backout;
}
io_channel_flush(fs->io);
- if (progress)
- ext2fs_progress_update(progress, ++moved);
+ if (rfs->progress)
+ rfs->progress(rfs, E2_RSZ_MOVE_ITABLE_PASS,
+ ++moved, to_move);
}
ext2fs_flush(rfs->new_fs);
io_channel_flush(fs->io);
if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
printf("Inode table move finished.\n");
#endif
- if (progress)
- ext2fs_progress_close(progress);
return 0;
backout:
- if (progress)
- ext2fs_progress_close(progress);
#ifdef RESIZE2FS_DEBUG
if (rfs->flags & RESIZE_DEBUG_ITABLEMOVE)
printf("Error: %s; now backing out!\n", error_message(retval));
return 0;
}
-
-
/*
* This is the top-level routine which does the dirty deed....
*/
-errcode_t resize_fs(ext2_filsys fs, blk_t new_size, int flags)
+errcode_t resize_fs(ext2_filsys fs, blk_t new_size, int flags,
+ void (*progress)(ext2_resize_t rfs, int pass,
+ unsigned long cur,
+ unsigned long max))
{
ext2_resize_t rfs;
errcode_t retval;
rfs->old_fs = fs;
rfs->flags = flags;
rfs->itable_buf = 0;
+ rfs->progress = progress;
retval = ext2fs_dup_handle(fs, &rfs->new_fs);
if (retval)
goto errout;
/*
* The core state structure for the ext2 resizer
*/
+typedef struct ext2_resize_struct *ext2_resize_t;
struct ext2_resize_struct {
ext2_filsys old_fs;
int needed_blocks;
int flags;
char *itable_buf;
+ void (*progress)(ext2_resize_t rfs, int pass,
+ unsigned long cur,
+ unsigned long max);
+ void *prog_data;
};
-typedef struct ext2_resize_struct *ext2_resize_t;
+/*
+ * Progress pass numbers...
+ */
+#define E2_RSZ_ADJUST_SUPERBLOCK_PASS 1
+#define E2_RSZ_BLOCK_RELOC_PASS 2
+#define E2_RSZ_BLOCK_REF_UPD_PASS 3
+#define E2_RSZ_INODE_FIND_DIR_PASS 4
+#define E2_RSZ_INODE_RELOC_PASS 5
+#define E2_RSZ_INODE_REF_UPD_PASS 6
+#define E2_RSZ_MOVE_ITABLE_PASS 7
+
/* prototypes */
-extern errcode_t resize_fs(ext2_filsys fs, blk_t new_size, int flags);
+extern errcode_t resize_fs(ext2_filsys fs, blk_t new_size, int flags,
+ void (*progress)(ext2_resize_t rfs, int pass,
+ unsigned long cur,
+ unsigned long max));
+
extern errcode_t ext2fs_inode_move(ext2_resize_t rfs);
extern errcode_t ext2fs_block_move(ext2_resize_t rfs);