extern void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
struct ext2_inode *inode, int restart_flag,
const char *source);
+extern void e2fsck_intercept_block_allocations(e2fsck_t ctx);
/* pass2.c */
extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
"block interate buffer");
e2fsck_use_inode_shortcuts(ctx, 1);
+ e2fsck_intercept_block_allocations(ctx);
old_op = ehandler_operation(_("opening inode scan"));
pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
&scan);
}
if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
- ext2fs_block_bitmap save_bmap;
-
- save_bmap = fs->block_map;
- fs->block_map = ctx->block_found_map;
clear_problem_context(&pctx);
pctx.errcode = ext2fs_create_resize_inode(fs);
if (pctx.errcode) {
e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
"recreate inode");
}
- fs->block_map = save_bmap;
ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
}
fs->read_inode = pass1_read_inode;
fs->write_inode = pass1_write_inode;
ctx->stashed_ino = 0;
- ext2fs_set_alloc_block_callback(fs, e2fsck_get_alloc_block,
- 0);
- ext2fs_set_block_alloc_stats_callback(fs,
- e2fsck_block_alloc_stats,
- 0);
} else {
fs->get_blocks = 0;
fs->check_directory = 0;
fs->write_inode = 0;
}
}
+
+void e2fsck_intercept_block_allocations(e2fsck_t ctx)
+{
+ ext2fs_set_alloc_block_callback(ctx->fs, e2fsck_get_alloc_block, 0);
+ ext2fs_set_block_alloc_stats_callback(ctx->fs,
+ e2fsck_block_alloc_stats, 0);
+}
_("internal error: can't find dup_blk for %llu\n"),
*block_nr);
} else {
- ext2fs_unmark_block_bitmap2(ctx->block_found_map, *block_nr);
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
pb->dup_blocks++;
}
if ((*block_nr < fs->super->s_first_data_block) ||
(*block_nr >= ext2fs_blocks_count(fs->super)))
return 0;
- ext2fs_unmark_block_bitmap2(p->ctx->block_found_map, *block_nr);
ext2fs_block_alloc_stats2(fs, *block_nr, -1);
p->num++;
return 0;
return;
}
if (count == 0) {
- ext2fs_unmark_block_bitmap2(ctx->block_found_map,
- ext2fs_file_acl_block(fs, &inode));
ext2fs_block_alloc_stats2(fs,
ext2fs_file_acl_block(fs, &inode), -1);
}
return BLOCK_CHANGED;
}
-/*
- * Ensure that all blocks are marked in the block_found_map, since it's
- * possible that the library allocated an extent node block or a block map
- * block during the directory rebuilding; these new allocations are not
- * captured in block_found_map. This is bad since we could later use
- * block_found_map to allocate more blocks.
- */
-static int find_new_blocks_proc(ext2_filsys fs,
- blk64_t *blocknr,
- e2_blkcnt_t blockcnt,
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *priv_data)
-{
- struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
- e2fsck_t ctx = es->ctx;
-
- ext2fs_mark_block_bitmap2(ctx->block_found_map, *blocknr);
- return 0;
-}
-
errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
int num, int guaranteed_size)
{
es.newblocks = 0;
es.ctx = ctx;
- before = ext2fs_free_blocks_count(fs->super);
retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
0, expand_dir_proc, &es);
if (es.err)
return es.err;
- after = ext2fs_free_blocks_count(fs->super);
-
- /*
- * If the free block count has dropped by more than the blocks we
- * allocated ourselves, then we must've allocated some extent/map
- * blocks. Therefore, we must iterate this dir's blocks again to
- * ensure that all newly allocated blocks are captured in
- * block_found_map.
- */
- if ((before - after) > es.newblocks) {
- retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_READ_ONLY,
- 0, find_new_blocks_proc, &es);
- if (es.err)
- return es.err;
- }
/*
* Update the size and block count fields in the inode.
* once.
*/
if (blk % EXT2FS_CLUSTER_RATIO(fs) == 0) {
- ext2fs_unmark_block_bitmap2(wd->ctx->block_found_map,
- blk);
ext2fs_block_alloc_stats2(fs, blk, -1);
wd->cleared++;
}