From f07c8149718e2b841b91269cc2c0d5ed92df1bca Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Fri, 29 Jan 2016 13:03:22 +0800 Subject: btrfs-progs: Introduce function to create convert data chunks Introduce new function, make_convert_data_chunks(), to build up data chunks for convert. It will call a modified version of btrfs_alloc_data_chunk() to force data chunks to covert all known ext* data. Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- btrfs-convert.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'btrfs-convert.c') diff --git a/btrfs-convert.c b/btrfs-convert.c index 36ffba09..c826634f 100644 --- a/btrfs-convert.c +++ b/btrfs-convert.c @@ -1890,6 +1890,56 @@ static int create_subvol(struct btrfs_trans_handle *trans, return 0; } +/* + * New make_btrfs_v2() has handle system and meta chunks quite well. + * So only need to add remaining data chunks. + */ +static int make_convert_data_block_groups(struct btrfs_trans_handle *trans, + struct btrfs_fs_info *fs_info, + struct btrfs_mkfs_config *cfg, + struct btrfs_convert_context *cctx) +{ + struct btrfs_root *extent_root = fs_info->extent_root; + struct cache_tree *data_chunks = &cctx->data_chunks; + struct cache_extent *cache; + u64 max_chunk_size; + int ret = 0; + + /* + * Don't create data chunk over 10% of the convert device + * And for single chunk, don't create chunk larger than 1G. + */ + max_chunk_size = cfg->num_bytes / 10; + max_chunk_size = min((u64)(1024 * 1024 * 1024), max_chunk_size); + max_chunk_size = round_down(max_chunk_size, extent_root->sectorsize); + + for (cache = first_cache_extent(data_chunks); cache; + cache = next_cache_extent(cache)) { + u64 cur = cache->start; + + while (cur < cache->start + cache->size) { + u64 len; + u64 cur_backup = cur; + + len = min(max_chunk_size, + cache->start + cache->size - cur); + ret = btrfs_alloc_data_chunk(trans, extent_root, + &cur_backup, len, + BTRFS_BLOCK_GROUP_DATA, 1); + if (ret < 0) + break; + ret = btrfs_make_block_group(trans, extent_root, 0, + BTRFS_BLOCK_GROUP_DATA, + BTRFS_FIRST_CHUNK_TREE_OBJECTID, + cur, len); + if (ret < 0) + break; + cur += len; + } + } + return ret; +} + static int init_btrfs(struct btrfs_root *root) { int ret; -- cgit v1.2.3