mirror of
https://github.com/kdave/btrfs-progs
synced 2025-01-31 01:41:41 +00:00
btrfs-progs: convert: Introduce functions to read used space
Before we do real convert, we need to read and build up used space cache tree for later data/meta separate chunk layout. This patch will iterate all used blocks in ext2 filesystem and record it into cctx->used cache tree, for later use. This provides the very basic of later btrfs-convert rework. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
de34a25eb3
commit
8031517744
@ -93,6 +93,7 @@ struct btrfs_convert_context;
|
||||
struct btrfs_convert_operations {
|
||||
const char *name;
|
||||
int (*open_fs)(struct btrfs_convert_context *cctx, const char *devname);
|
||||
int (*read_used_space)(struct btrfs_convert_context *cctx);
|
||||
int (*alloc_block)(struct btrfs_convert_context *cctx, u64 goal,
|
||||
u64 *block_ret);
|
||||
int (*alloc_block_range)(struct btrfs_convert_context *cctx, u64 goal,
|
||||
@ -257,6 +258,73 @@ fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __ext2_add_one_block(ext2_filsys fs, char *bitmap,
|
||||
unsigned long group_nr, struct cache_tree *used)
|
||||
{
|
||||
unsigned long offset;
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
offset = fs->super->s_first_data_block;
|
||||
offset /= EXT2FS_CLUSTER_RATIO(fs);
|
||||
offset += group_nr * EXT2_CLUSTERS_PER_GROUP(fs->super);
|
||||
for (i = 0; i < EXT2_CLUSTERS_PER_GROUP(fs->super); i++) {
|
||||
if (ext2fs_test_bit(i, bitmap)) {
|
||||
u64 start;
|
||||
|
||||
start = (i + offset) * EXT2FS_CLUSTER_RATIO(fs);
|
||||
start *= fs->blocksize;
|
||||
ret = add_merge_cache_extent(used, start,
|
||||
fs->blocksize);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read all used ext2 space into cctx->used cache tree
|
||||
*/
|
||||
static int ext2_read_used_space(struct btrfs_convert_context *cctx)
|
||||
{
|
||||
ext2_filsys fs = (ext2_filsys)cctx->fs_data;
|
||||
blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
|
||||
struct cache_tree *used_tree = &cctx->used;
|
||||
char *block_bitmap = NULL;
|
||||
unsigned long i;
|
||||
int block_nbytes;
|
||||
int ret = 0;
|
||||
|
||||
block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
|
||||
/* Shouldn't happen */
|
||||
BUG_ON(!fs->block_map);
|
||||
|
||||
block_bitmap = malloc(block_nbytes);
|
||||
if (!block_bitmap)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < fs->group_desc_count; i++) {
|
||||
ret = ext2fs_get_block_bitmap_range(fs->block_map, blk_itr,
|
||||
block_nbytes * 8, block_bitmap);
|
||||
if (ret) {
|
||||
error("fail to get bitmap from ext2, %s",
|
||||
strerror(-ret));
|
||||
break;
|
||||
}
|
||||
ret = __ext2_add_one_block(fs, block_bitmap, i, used_tree);
|
||||
if (ret < 0) {
|
||||
error("fail to build used space tree, %s",
|
||||
strerror(-ret));
|
||||
break;
|
||||
}
|
||||
blk_itr += EXT2_CLUSTERS_PER_GROUP(fs->super);
|
||||
}
|
||||
|
||||
free(block_bitmap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ext2_close_fs(struct btrfs_convert_context *cctx)
|
||||
{
|
||||
if (cctx->volume_name) {
|
||||
@ -2445,6 +2513,7 @@ err:
|
||||
static const struct btrfs_convert_operations ext2_convert_ops = {
|
||||
.name = "ext2",
|
||||
.open_fs = ext2_open_fs,
|
||||
.read_used_space = ext2_read_used_space,
|
||||
.alloc_block = ext2_alloc_block,
|
||||
.alloc_block_range = ext2_alloc_block_range,
|
||||
.copy_inodes = ext2_copy_inodes,
|
||||
@ -2478,6 +2547,14 @@ static int convert_open_fs(const char *devname,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read used space
|
||||
*/
|
||||
static int convert_read_used_space(struct btrfs_convert_context *cctx)
|
||||
{
|
||||
return cctx->convert_ops->read_used_space(cctx);
|
||||
}
|
||||
|
||||
static int do_convert(const char *devname, int datacsum, int packing, int noxattr,
|
||||
u32 nodesize, int copylabel, const char *fslabel, int progress,
|
||||
u64 features)
|
||||
@ -2499,6 +2576,9 @@ static int do_convert(const char *devname, int datacsum, int packing, int noxatt
|
||||
|
||||
init_convert_context(&cctx);
|
||||
ret = convert_open_fs(devname, &cctx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
ret = convert_read_used_space(&cctx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user