aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--e2fsck/ChangeLog15
-rw-r--r--e2fsck/e2fsck.c2
-rw-r--r--e2fsck/emptydir.c192
-rw-r--r--e2fsck/pass2.c5
-rw-r--r--e2fsck/pass3.c9
-rw-r--r--e2fsck/unix.c3
-rw-r--r--lib/ext2fs/ChangeLog6
-rw-r--r--lib/ext2fs/badblocks.c9
8 files changed, 229 insertions, 12 deletions
diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index 84d3e2ff..17f883b0 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,3 +1,18 @@
+1998-08-01 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * pass2.c (e2fsck_pass2): Fix the progress accounting so that we
+ get to 100%.
+
+ * pass3.c (e2fsck_pass3): Change progress accounting to be
+ consistent with the other e2fsck passes.
+
+ * e2fsck.c (e2fsck_run): At the end of each pass, call the
+ progress function with the pass number set to zero.
+
+ * unix.c (e2fsck_update_progress): If the pass number is zero,
+ ignore the call, since that indicates that we just want to
+ deallocate any progress structures.
+
1998-07-09 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs 1.12
diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
index 41195fe9..77e0e2e1 100644
--- a/e2fsck/e2fsck.c
+++ b/e2fsck/e2fsck.c
@@ -153,6 +153,8 @@ int e2fsck_run(e2fsck_t ctx)
if (ctx->flags & E2F_FLAG_RUN_RETURN)
break;
e2fsck_pass(ctx);
+ if (ctx->progress)
+ (void) (ctx->progress)(ctx, 0, 0, 0);
}
ctx->flags &= ~E2F_FLAG_SETJMP_OK;
diff --git a/e2fsck/emptydir.c b/e2fsck/emptydir.c
new file mode 100644
index 00000000..6229a6bf
--- /dev/null
+++ b/e2fsck/emptydir.c
@@ -0,0 +1,192 @@
+/*
+ * emptydir.c --- clear empty directory blocks
+ *
+ * Copyright (C) 1998 Theodore Ts'o
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ * This file has the necessary routines to search for empty directory
+ * blocks and get rid of them.
+ */
+
+#include "e2fsck.h"
+#include "problem.h"
+
+/*
+ * For e2fsck.h
+ */
+struct empty_dir_info_struct {
+ ext2_dblist empty_dblist;
+ ext2fs_block_bitmap empty_dir_blocks;
+ ext2fs_inode_bitmap dir_map;
+ char *block_buf;
+ ino_t ino;
+ struct ext2_inode inode;
+ blk_t logblk;
+ blk_t freed_blocks;
+};
+
+typedef struct empty_dir_info_struct *empty_dir_info;
+
+extern empty_dir_info init_empty_dir(e2fsck_t ctx);
+extern void free_empty_dirblock(empty_dir_info edi);
+extern void add_empty_dirblock(empty_dir_info edi,
+ struct ext2_db_entry *db);
+extern void process_empty_dirblock(e2fsck_t ctx, empty_dir_info edi);
+
+
+empty_dir_info init_empty_dir(e2fsck_t ctx)
+{
+ empty_dir_info edi;
+ errcode_t retval;
+
+ edi = malloc(sizeof(struct empty_dir_info_struct));
+ if (!edi)
+ return NULL;
+
+ memset(edi, 0, sizeof(struct empty_dir_info_struct));
+
+ retval = ext2fs_init_dblist(ctx->fs, &edi->empty_dblist);
+ if (retval)
+ goto errout;
+
+ retval = ext2fs_allocate_block_bitmap(ctx->fs, "empty dirblocks",
+ &edi->empty_dir_blocks);
+ if (retval)
+ goto errout;
+
+ retval = ext2fs_allocate_inode_bitmap(ctx->fs, "empty dir map",
+ &edi->dir_map);
+ if (retval)
+ goto errout;
+
+ return (edi);
+
+errout:
+ free_empty_dirblock(edi);
+ return NULL;
+}
+
+void free_empty_dirblock(empty_dir_info edi)
+{
+ if (!edi)
+ return;
+ if (edi->empty_dblist)
+ ext2fs_free_dblist(edi->empty_dblist);
+ if (edi->empty_dir_blocks)
+ ext2fs_free_block_bitmap(edi->empty_dir_blocks);
+ if (edi->dir_map)
+ ext2fs_free_inode_bitmap(edi->dir_map);
+
+ memset(edi, 0, sizeof(struct empty_dir_info_struct));
+ free(edi);
+}
+
+void add_empty_dirblock(empty_dir_info edi,
+ struct ext2_db_entry *db)
+{
+ if (!edi || !db)
+ return;
+
+ if (db->ino == 11)
+ return; /* Inode number 11 is usually lost+found */
+
+ printf("Empty directory block %d (#%d) in inode %d\n",
+ db->blk, db->blockcnt, db->ino);
+
+ ext2fs_mark_block_bitmap(edi->empty_dir_blocks, db->blk);
+ if (ext2fs_test_inode_bitmap(edi->dir_map, db->ino))
+ return;
+ ext2fs_mark_inode_bitmap(edi->dir_map, db->ino);
+
+ ext2fs_add_dir_block(edi->empty_dblist, db->ino,
+ db->blk, db->blockcnt);
+}
+
+/*
+ * Helper function used by fix_directory.
+ *
+ * XXX need to finish this. General approach is to use bmap to
+ * iterate over all of the logical blocks using the bmap function, and
+ * copy the block reference as necessary. Big question --- what do
+ * about error recovery?
+ *
+ * Also question --- how to free the indirect blocks.
+ */
+int empty_pass1(ext2_filsys fs, blk_t *block_nr, e2_blkcnt_t blockcnt,
+ blk_t ref_block, int ref_offset, void *priv_data)
+{
+ empty_dir_info edi = (empty_dir_info) priv_data;
+ blk_t block, new_block;
+ errcode_t retval;
+
+ if (blockcnt < 0)
+ return 0;
+ block = *block_nr;
+ do {
+ retval = ext2fs_bmap(fs, edi->ino, &edi->inode,
+ edi->block_buf, 0, edi->logblk,
+ &new_block);
+ if (retval)
+ return DIRENT_ABORT; /* XXX what to do? */
+ if (new_block == 0)
+ break;
+ edi->logblk++;
+ } while (ext2fs_test_block_bitmap(edi->empty_dir_blocks, new_block));
+
+ if (new_block == block)
+ return 0;
+ if (new_block == 0)
+ edi->freed_blocks++;
+ *block_nr = new_block;
+ return BLOCK_CHANGED;
+}
+
+static int fix_directory(ext2_filsys fs,
+ struct ext2_db_entry *db,
+ void *priv_data)
+{
+ errcode_t retval;
+
+ empty_dir_info edi = (empty_dir_info) priv_data;
+
+ edi->logblk = 0;
+ edi->freed_blocks = 0;
+ edi->ino = db->ino;
+
+ retval = ext2fs_read_inode(fs, db->ino, &edi->inode);
+ if (retval)
+ return 0;
+
+ retval = ext2fs_block_iterate2(fs, db->ino, 0, edi->block_buf,
+ empty_pass1, edi);
+ if (retval)
+ return 0;
+
+ if (edi->freed_blocks) {
+ edi->inode.i_size -= edi->freed_blocks * fs->blocksize;
+ edi->inode.i_blocks -= edi->freed_blocks *
+ (fs->blocksize / 512);
+ (void) ext2fs_write_inode(fs, db->ino, &edi->inode);
+ }
+ return 0;
+}
+
+void process_empty_dirblock(e2fsck_t ctx, empty_dir_info edi)
+{
+ if (!edi)
+ return;
+
+ edi->block_buf = malloc(ctx->fs->blocksize * 3);
+
+ if (edi->block_buf) {
+ (void) ext2fs_dblist_iterate(edi->empty_dblist,
+ fix_directory, &edi);
+ }
+ free(edi->block_buf);
+ free_empty_dirblock(edi);
+}
+
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index f52bc2ee..1767d00c 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -112,8 +112,11 @@ void e2fsck_pass2(e2fsck_t ctx)
cd.buf = buf;
cd.ctx = ctx;
- cd.count = 0;
+ cd.count = 1;
cd.max = ext2fs_dblist_count(fs->dblist);
+
+ if (ctx->progress)
+ (void) (ctx->progress)(ctx, 2, 0, cd.max);
cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
&cd);
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 733819ee..c87ebd9c 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -110,8 +110,12 @@ void e2fsck_pass3(e2fsck_t ctx)
ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
max = e2fsck_get_num_dirinfo(ctx);
- count = 0;
+ count = 1;
+ if (ctx->progress)
+ if ((ctx->progress)(ctx, 3, 0, max))
+ goto abort_exit;
+
for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
if (ctx->progress)
if ((ctx->progress)(ctx, 3, count++, max))
@@ -119,9 +123,6 @@ void e2fsck_pass3(e2fsck_t ctx)
if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
check_directory(ctx, dir, &pctx);
}
- if (ctx->progress)
- if ((ctx->progress)(ctx, 3, max, max))
- goto abort_exit;
abort_exit:
e2fsck_free_dir_info(ctx);
diff --git a/e2fsck/unix.c b/e2fsck/unix.c
index cd6c98d6..b4710a23 100644
--- a/e2fsck/unix.c
+++ b/e2fsck/unix.c
@@ -228,6 +228,9 @@ static int e2fsck_update_progress(e2fsck_t ctx, int pass,
{
const char spinner[] = "\\|/-";
char buf[80];
+
+ if (pass == 0)
+ return 0;
if (ctx->progress_fd) {
sprintf(buf, "%d %lu %lu\n", pass, cur, max);
diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog
index bd83ea2c..ddce36d9 100644
--- a/lib/ext2fs/ChangeLog
+++ b/lib/ext2fs/ChangeLog
@@ -1,3 +1,9 @@
+1998-07-27 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * badblocks.c (ext2fs_badblocks_list_add): Use a bigger increment
+ than 10 blocks when we need to expand the size of the
+ badblocks list.
+
1998-07-09 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs 1.12
diff --git a/lib/ext2fs/badblocks.c b/lib/ext2fs/badblocks.c
index 3851ccd6..e2f46f15 100644
--- a/lib/ext2fs/badblocks.c
+++ b/lib/ext2fs/badblocks.c
@@ -107,11 +107,11 @@ errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
if (bb->num >= bb->size) {
old_size = bb->size * sizeof(blk_t);
- bb->size += 10;
+ bb->size += 100;
retval = ext2fs_resize_mem(old_size, bb->size * sizeof(blk_t),
(void **) &bb->list);
if (retval) {
- bb->size -= 10;
+ bb->size -= 100;
return retval;
}
}
@@ -215,8 +215,3 @@ void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
iter->bb = 0;
ext2fs_free_mem((void **) &iter);
}
-
-
-
-
-