Пример #1
0
void do_goto_block(int argc, char **argv)
{
	errcode_t		retval;
	blk64_t			blk;
	int			level = 0, err;

	if (common_extent_args_process(argc, argv, 2, 3, "goto_block",
				       "block [level]", 0))
		return;

	if (strtoblk(argv[0], argv[1], &blk))
		return;

	if (argc == 3) {
		level = parse_ulong(argv[2], argv[0], "level", &err);
		if (err)
			return;
	}

	retval = ext2fs_extent_goto2(current_handle, level, (blk64_t) blk);

	if (retval) {
		com_err(argv[0], retval,
			"while trying to go to block %llu, level %d",
			(unsigned long long) blk, level);
		return;
	}

	generic_goto_node(NULL, argc, argv, EXT2_EXTENT_CURRENT);
}
Пример #2
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;
}
Пример #3
0
blk64_t ext2fs_find_inode_goal(ext2_filsys fs, ext2_ino_t ino,
			       struct ext2_inode *inode, blk64_t lblk)
{
	dgrp_t			group;
	__u8			log_flex;
	struct ext2fs_extent	extent;
	ext2_extent_handle_t	handle = NULL;
	errcode_t		err;

	if (inode == NULL || ext2fs_inode_data_blocks2(fs, inode) == 0)
		goto no_blocks;

	if (inode->i_flags & EXT4_INLINE_DATA_FL)
		goto no_blocks;

	if (inode->i_flags & EXT4_EXTENTS_FL) {
		err = ext2fs_extent_open2(fs, ino, inode, &handle);
		if (err)
			goto no_blocks;
		err = ext2fs_extent_goto2(handle, 0, lblk);
		if (err)
			goto no_blocks;
		err = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
		if (err)
			goto no_blocks;
		ext2fs_extent_free(handle);
		return extent.e_pblk + (lblk - extent.e_lblk);
	}

	/* block mapped file; see if block zero is mapped? */
	if (inode->i_block[0])
		return inode->i_block[0];

no_blocks:
	ext2fs_extent_free(handle);
	log_flex = fs->super->s_log_groups_per_flex;
	group = ext2fs_group_of_ino(fs, ino);
	if (log_flex)
		group = group & ~((1 << (log_flex)) - 1);
	return ext2fs_group_first_block2(fs, group);
}
Пример #4
0
errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
			     blk64_t blk)
{
	return ext2fs_extent_goto2(handle, 0, blk);
}