Whamcloud - gitweb
util.c:
[tools/e2fsprogs.git] / e2fsck / pass1b.c
index e965217..957a9ee 100644 (file)
@@ -88,7 +88,7 @@ struct dup_inode {
 };
 
 static int process_pass1b_block(ext2_filsys fs, blk_t  *blocknr,
-                               int     blockcnt, void  *private);
+                               int     blockcnt, void  *priv_data);
 static void delete_file(e2fsck_t ctx, struct dup_inode *dp,
                        char *block_buf);
 static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf);
@@ -105,7 +105,7 @@ static ext2fs_inode_bitmap inode_dup_map;
 /*
  * Main procedure for handling duplicate blocks
  */
-void pass1_dupblocks(e2fsck_t ctx, char *block_buf)
+void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
 {
        ext2_filsys             fs = ctx->fs;
        struct dup_block        *p, *q, *next_p, *next_q;
@@ -118,7 +118,8 @@ void pass1_dupblocks(e2fsck_t ctx, char *block_buf)
                      "multiply claimed inode map", &inode_dup_map);
        if (pctx.errcode) {
                fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        
        pass1b(ctx, block_buf);
@@ -135,12 +136,12 @@ void pass1_dupblocks(e2fsck_t ctx, char *block_buf)
                next_p = p->next_block;
                for (q = p; q; q = next_q) {
                        next_q = q->next_inode;
-                       free(q);
+                       ext2fs_free_mem((void **) &q);
                }
        }
        for (r = dup_ino; r; r = next_r) {
                next_r = r->next;
-               free(r);
+               ext2fs_free_mem((void **) &r);
        }
 }
 
@@ -154,7 +155,7 @@ struct process_block_struct {
        struct problem_context *pctx;
 };
 
-void pass1b(e2fsck_t ctx, char *block_buf)
+static void pass1b(e2fsck_t ctx, char *block_buf)
 {
        ext2_filsys fs = ctx->fs;
        ino_t   ino;
@@ -172,12 +173,14 @@ void pass1b(e2fsck_t ctx, char *block_buf)
                                              &scan);
        if (pctx.errcode) {
                fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
        if (pctx.errcode) {
                fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
-               fatal_error(0);
+               ctx->flags |= E2F_FLAG_ABORT;
+               return;
        }
        ctx->stashed_inode = &inode;
        pb.ctx = ctx;
@@ -195,8 +198,9 @@ void pass1b(e2fsck_t ctx, char *block_buf)
                                              process_pass1b_block, &pb);
                if (pb.dup_blocks) {
                        end_problem_latch(ctx, PR_LATCH_DBLOCK);
-                       dp = allocate_memory(sizeof(struct dup_inode),
-                                            "duplicate inode record");
+                       dp = (struct dup_inode *) e2fsck_allocate_memory(ctx,
+                                   sizeof(struct dup_inode),
+                                   "duplicate inode record");
                        dp->ino = ino;
                        dp->dir = 0;
                        dp->inode = inode;
@@ -216,7 +220,8 @@ void pass1b(e2fsck_t ctx, char *block_buf)
                        goto next;
                if (pctx.errcode) {
                        fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
-                       fatal_error(0);
+                       ctx->flags |= E2F_FLAG_ABORT;
+                       return;
                }
        }
        ext2fs_close_inode_scan(scan);
@@ -227,7 +232,7 @@ void pass1b(e2fsck_t ctx, char *block_buf)
 int process_pass1b_block(ext2_filsys fs,
                         blk_t  *block_nr,
                         int blockcnt,
-                        void *private)
+                        void *priv_data)
 {
        struct process_block_struct *p;
        struct dup_block *dp, *q, *r;
@@ -236,7 +241,7 @@ int process_pass1b_block(ext2_filsys fs,
 
        if (!*block_nr)
                return 0;
-       p = (struct process_block_struct *) private;
+       p = (struct process_block_struct *) priv_data;
        ctx = p->ctx;
        
        if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
@@ -248,8 +253,9 @@ int process_pass1b_block(ext2_filsys fs,
                p->dup_blocks++;
                ext2fs_mark_block_bitmap(ctx->block_dup_map, *block_nr);
                ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
-               dp = allocate_memory(sizeof(struct dup_block),
-                                     "duplicate block record");
+               dp = (struct dup_block *) e2fsck_allocate_memory(ctx,
+                                           sizeof(struct dup_block),
+                                           "duplicate block record");
                dp->block = *block_nr;
                dp->ino = p->ino;
                dp->num_bad = 0;
@@ -293,11 +299,13 @@ struct search_dir_struct {
 static int search_dirent_proc(ino_t dir, int entry,
                              struct ext2_dir_entry *dirent,
                              int offset, int blocksize,
-                             char *buf, void *private)
+                             char *buf, void *priv_data)
 {
-       struct search_dir_struct *sd = private;
+       struct search_dir_struct *sd;
        struct dup_inode        *p;
-       
+
+       sd = (struct search_dir_struct *) priv_data;
+
        if (dirent->inode > sd->max_inode)
                /* Should abort this inode, but not everything */
                return 0;       
@@ -322,7 +330,7 @@ static int search_dirent_proc(ino_t dir, int entry,
 }
 
 
-void pass1c(e2fsck_t ctx, char *block_buf)
+static void pass1c(e2fsck_t ctx, char *block_buf)
 {
        ext2_filsys fs = ctx->fs;
        struct dup_inode        *p;
@@ -371,12 +379,13 @@ static void pass1d(e2fsck_t ctx, char *block_buf)
        clear_problem_context(&pctx);
        
        fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
-       read_bitmaps(ctx);
+       e2fsck_read_bitmaps(ctx);
 
        pctx.num = dup_inode_count;
        fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
-       shared = allocate_memory(sizeof(ino_t) * dup_inode_count,
-                                "Shared inode list");
+       shared = (ino_t *) e2fsck_allocate_memory(ctx,
+                               sizeof(ino_t) * dup_inode_count,
+                               "Shared inode list");
        for (p = dup_ino; p; p = p->next) {
                shared_len = 0;
                file_ok = 1;
@@ -468,18 +477,19 @@ static void pass1d(e2fsck_t ctx, char *block_buf)
                else
                        ext2fs_unmark_valid(fs);
        }
-       free(shared);
+       ext2fs_free_mem((void **) &shared);
 }
 
 static int delete_file_block(ext2_filsys fs,
                             blk_t      *block_nr,
                             int blockcnt,
-                            void *private)
+                            void *priv_data)
 {
-       struct process_block_struct *pb = private;
+       struct process_block_struct *pb;
        struct dup_block *p;
        e2fsck_t ctx;
 
+       pb = (struct process_block_struct *) priv_data;
        ctx = pb->ctx;
 
        if (!*block_nr)
@@ -530,10 +540,10 @@ static void delete_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
        ext2fs_unmark_inode_bitmap(fs->inode_map, dp->ino);
        ext2fs_mark_ib_dirty(fs);
        ext2fs_mark_bb_dirty(fs);
-       e2fsck_read_inode(fs, dp->ino, &inode, "delete_file");
+       e2fsck_read_inode(ctx, dp->ino, &inode, "delete_file");
        inode.i_links_count = 0;
        inode.i_dtime = time(0);
-       e2fsck_write_inode(fs, dp->ino, &inode, "delete_file");
+       e2fsck_write_inode(ctx, dp->ino, &inode, "delete_file");
 }
 
 struct clone_struct {
@@ -546,12 +556,12 @@ struct clone_struct {
 static int clone_file_block(ext2_filsys fs,
                            blk_t       *block_nr,
                            int blockcnt,
-                           void *private)
+                           void *priv_data)
 {
        struct dup_block *p;
        blk_t   new_block;
        errcode_t       retval;
-       struct clone_struct *cs = (struct clone_struct *) private;
+       struct clone_struct *cs = (struct clone_struct *) priv_data;
        e2fsck_t ctx;
 
        ctx = cs->ctx;
@@ -591,7 +601,9 @@ static int clone_file_block(ext2_filsys fs,
                                return BLOCK_ABORT;
                        }
                        p->num_bad--;
-                       if (p->num_bad == 1)
+                       if (p->num_bad == 1 &&
+                           !ext2fs_test_block_bitmap(ctx->block_illegal_map,
+                                                     *block_nr))
                                ext2fs_unmark_block_bitmap(ctx->block_dup_map,
                                                           *block_nr);
                        *block_nr = new_block;
@@ -616,9 +628,9 @@ static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
        cs.errcode = 0;
        cs.dir = 0;
        cs.ctx = ctx;
-       cs.buf = malloc(fs->blocksize);
-       if (!cs.buf)
-               return ENOMEM;
+       retval = ext2fs_get_mem(fs->blocksize, (void **) &cs.buf);
+       if (retval)
+               return retval;
 
        if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dp->ino))
                cs.dir = dp->ino;
@@ -626,7 +638,7 @@ static int clone_file(e2fsck_t ctx, struct dup_inode *dp, char* block_buf)
        retval = ext2fs_block_iterate(fs, dp->ino, 0, block_buf,
                                      clone_file_block, &cs);
        ext2fs_mark_bb_dirty(fs);
-       free(cs.buf);
+       ext2fs_free_mem((void **) &cs.buf);
        if (retval) {
                com_err("clone_file", retval,
                        "while calling ext2fs_block_iterate for inode %d",