Whamcloud - gitweb
ChangeLog, e2fsck.c, pass2.c, pass3.c, unix.c:
authorTheodore Ts'o <tytso@mit.edu>
Sat, 1 Aug 1998 04:18:06 +0000 (04:18 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 1 Aug 1998 04:18:06 +0000 (04:18 +0000)
  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.
emptydir.c:
  Commit partially done file.
ChangeLog, badblocks.c:
  badblocks.c (ext2fs_badblocks_list_add): Use a bigger increment than
   10 blocks when we need to expand the size of the badblocks list.

e2fsck/ChangeLog
e2fsck/e2fsck.c
e2fsck/emptydir.c [new file with mode: 0644]
e2fsck/pass2.c
e2fsck/pass3.c
e2fsck/unix.c
lib/ext2fs/ChangeLog
lib/ext2fs/badblocks.c

index 84d3e2f..17f883b 100644 (file)
@@ -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
index 41195fe..77e0e2e 100644 (file)
@@ -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 (file)
index 0000000..6229a6b
--- /dev/null
@@ -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);
+}
+
index f52bc2e..1767d00 100644 (file)
@@ -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);
index 733819e..c87ebd9 100644 (file)
@@ -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);
index cd6c98d..b4710a2 100644 (file)
@@ -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);
index bd83ea2..ddce36d 100644 (file)
@@ -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
index 3851ccd..e2f46f1 100644 (file)
@@ -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);
 }
-
-
-
-
-