Exemplo n.º 1
0
/*
 * Traverse back up to root fixing parents of current node as needed.
 *
 * If we changed start of first entry in a node, fix parent index start
 * and so on.
 *
 * Safe to call for any position in node; if not at the first entry,
 * will  simply return.
 */
errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle)
{
	int				retval = 0;
	int				orig_height;
	blk64_t				start;
	struct extent_path		*path;
	struct ext2fs_extent		extent;
	struct ext2_extent_info		info;

	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);

	if (!(handle->fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	if (!handle->path)
		return EXT2_ET_NO_CURRENT_NODE;

	path = handle->path + handle->level;
	if (!path->curr)
		return EXT2_ET_NO_CURRENT_NODE;

	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
	if (retval)
		goto done;

	/* modified node's start block */
	start = extent.e_lblk;

	if ((retval = ext2fs_extent_get_info(handle, &info)))
		return retval;
	orig_height = info.max_depth - info.curr_level;

	/* traverse up until index not first, or startblk matches, or top */
	while (handle->level > 0 &&
	       (path->left == path->entries - 1)) {
		retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent);
		if (retval)
			goto done;
		if (extent.e_lblk == start)
			break;
		path = handle->path + handle->level;
		extent.e_len += (extent.e_lblk - start);
		extent.e_lblk = start;
		retval = ext2fs_extent_replace(handle, 0, &extent);
		if (retval)
			goto done;
		update_path(handle);
	}

	/* put handle back to where we started */
	retval = ext2fs_extent_goto2(handle, orig_height, start);
done:
	return retval;
}
Exemplo n.º 2
0
static errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle)
{
	int				retval = 0;
	blk64_t				start;
	struct extent_path		*path;
	struct ext2fs_extent		extent;

	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);

	if (!(handle->fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	if (!handle->path)
		return EXT2_ET_NO_CURRENT_NODE;

	path = handle->path + handle->level;
	if (!path->curr)
		return EXT2_ET_NO_CURRENT_NODE;

	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
	if (retval)
		goto done;

	
	start = extent.e_lblk;

	
	while (handle->level > 0 &&
	       (path->left == path->entries - 1)) {
		retval = ext2fs_extent_get(handle, EXT2_EXTENT_UP, &extent);
		if (retval)
			goto done;
		if (extent.e_lblk == start)
			break;
		path = handle->path + handle->level;
		extent.e_len += (extent.e_lblk - start);
		extent.e_lblk = start;
		retval = ext2fs_extent_replace(handle, 0, &extent);
		if (retval)
			goto done;
		update_path(handle);
	}

	
	retval = ext2fs_extent_goto(handle, start);
done:
	return retval;
}
Exemplo n.º 3
0
void do_replace_node(int argc, char *argv[])
{
	const char	*usage = "[--uninit] <lblk> <len> <pblk>";
	errcode_t	retval;
	struct ext2fs_extent extent;
	int err;

	if (common_extent_args_process(argc, argv, 3, 5, "replace_node",
				       usage, CHECK_FS_RW | CHECK_FS_BITMAPS))
		return;

	extent.e_flags = 0;

	if (!strcmp(argv[1], "--uninit")) {
		argc--;
		argv++;
		extent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT;
	}

	if (argc != 4) {
		fprintf(stderr, "Usage: %s %s\n", argv[0], usage);
		return;
	}

	extent.e_lblk = parse_ulong(argv[1], argv[0], "logical block", &err);
	if (err)
		return;

	extent.e_len = parse_ulong(argv[2], argv[0], "logical block", &err);
	if (err)
		return;

	extent.e_pblk = parse_ulong(argv[3], argv[0], "logical block", &err);
	if (err)
		return;

	retval = ext2fs_extent_replace(current_handle, 0, &extent);
	if (retval) {
		com_err(argv[0], retval, 0);
		return;
	}
	generic_goto_node(NULL, argc, argv, EXT2_EXTENT_CURRENT);
}