Ejemplo n.º 1
0
void e2fsck_rehash_directories(e2fsck_t ctx)
{
	struct problem_context	pctx;
#ifdef RESOURCE_TRACK
	struct resource_track	rtrack;
#endif
	struct dir_info		*dir;
	ext2_u32_iterate 	iter;
	struct dir_info_iter *	dirinfo_iter = 0;
	ext2_ino_t		ino;
	errcode_t		retval;
	int			cur, max, all_dirs, first = 1;

	init_resource_track(&rtrack, ctx->fs->io);
	all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;

	if (!ctx->dirs_to_hash && !all_dirs)
		return;

	(void) e2fsck_get_lost_and_found(ctx, 0);

	clear_problem_context(&pctx);

	cur = 0;
	if (all_dirs) {
		dirinfo_iter = e2fsck_dir_info_iter_begin(ctx);
		max = e2fsck_get_num_dirinfo(ctx);
	} else {
		retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
						       &iter);
		if (retval) {
			pctx.errcode = retval;
			fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
			return;
		}
		max = ext2fs_u32_list_count(ctx->dirs_to_hash);
	}
	while (1) {
		if (all_dirs) {
			if ((dir = e2fsck_dir_info_iter(ctx,
							dirinfo_iter)) == 0)
				break;
			ino = dir->ino;
		} else {
			if (!ext2fs_u32_list_iterate(iter, &ino))
				break;
		}

		pctx.dir = ino;
		if (first) {
			fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
			first = 0;
		}
#if 0
		fix_problem(ctx, PR_3A_OPTIMIZE_DIR, &pctx);
#endif
		pctx.errcode = e2fsck_rehash_dir(ctx, ino, &pctx);
		if (pctx.errcode) {
			end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
			fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
		}
		if (ctx->progress && !ctx->progress_fd)
			e2fsck_simple_progress(ctx, "Rebuilding directory",
			       100.0 * (float) (++cur) / (float) max, ino);
	}
	end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
	if (all_dirs)
		e2fsck_dir_info_iter_end(ctx, dirinfo_iter);
	else
		ext2fs_u32_list_iterate_end(iter);

	if (ctx->dirs_to_hash)
		ext2fs_u32_list_free(ctx->dirs_to_hash);
	ctx->dirs_to_hash = 0;

	print_resource_track(ctx, "Pass 3A", &rtrack, ctx->fs->io);
}
Ejemplo n.º 2
0
void e2fsck_pass3(e2fsck_t ctx)
{
	ext2_filsys fs = ctx->fs;
	struct dir_info_iter *iter;
#ifdef RESOURCE_TRACK
	struct resource_track	rtrack;
#endif
	struct problem_context	pctx;
	struct dir_info	*dir;
	unsigned long maxdirs, count;

	init_resource_track(&rtrack, ctx->fs->io);
	clear_problem_context(&pctx);

#ifdef MTRACE
	mtrace_print("Pass 3");
#endif

	if (!(ctx->options & E2F_OPT_PREEN))
		fix_problem(ctx, PR_3_PASS_HEADER, &pctx);

	/*
	 * Allocate some bitmaps to do loop detection.
	 */
	pctx.errcode = e2fsck_allocate_inode_bitmap(fs, _("inode done bitmap"),
					EXT2FS_BMAP64_AUTODIR,
					"inode_done_map", &inode_done_map);
	if (pctx.errcode) {
		pctx.num = 2;
		fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
		ctx->flags |= E2F_FLAG_ABORT;
		goto abort_exit;
	}
	print_resource_track(ctx, _("Peak memory"), &ctx->global_rtrack, NULL);

	check_root(ctx);
	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
		goto abort_exit;

	ext2fs_mark_inode_bitmap2(inode_done_map, EXT2_ROOT_INO);

	maxdirs = e2fsck_get_num_dirinfo(ctx);
	count = 1;

	if (ctx->progress)
		if ((ctx->progress)(ctx, 3, 0, maxdirs))
			goto abort_exit;

	iter = e2fsck_dir_info_iter_begin(ctx);
	while ((dir = e2fsck_dir_info_iter(ctx, iter)) != 0) {
		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
			goto abort_exit;
		if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
			goto abort_exit;
		if (ext2fs_test_inode_bitmap2(ctx->inode_dir_map, dir->ino))
			if (check_directory(ctx, dir->ino, &pctx))
				goto abort_exit;
	}
	e2fsck_dir_info_iter_end(ctx, iter);

	/*
	 * Force the creation of /lost+found if not present
	 */
	if ((ctx->flags & E2F_OPT_READONLY) == 0)
		e2fsck_get_lost_and_found(ctx, 1);

	/*
	 * If there are any directories that need to be indexed or
	 * optimized, do it here.
	 */
	e2fsck_rehash_directories(ctx);

abort_exit:
	e2fsck_free_dir_info(ctx);
	if (inode_loop_detect) {
		ext2fs_free_inode_bitmap(inode_loop_detect);
		inode_loop_detect = 0;
	}
	if (inode_done_map) {
		ext2fs_free_inode_bitmap(inode_done_map);
		inode_done_map = 0;
	}

	print_resource_track(ctx, _("Pass 3"), &rtrack, ctx->fs->io);
}