linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH v2 15/25] btrfs-progs: Introduce function to create convert data chunks
Date: Tue,  1 Dec 2015 15:11:35 +0800	[thread overview]
Message-ID: <1448953905-28673-16-git-send-email-quwenruo@cn.fujitsu.com> (raw)
In-Reply-To: <1448953905-28673-1-git-send-email-quwenruo@cn.fujitsu.com>

Introduce new function, make_convert_data_chunks(), to build up data
chunks for convert.

It will call a modified verion of btrfs_alloc_data_chunk() to force
data chunks to cover all known ext* data.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 btrfs-convert.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 mkfs.c          |  2 +-
 volumes.c       | 46 ++++++++++++++++++++++++++++++++++------------
 volumes.h       |  2 +-
 4 files changed, 86 insertions(+), 14 deletions(-)

diff --git a/btrfs-convert.c b/btrfs-convert.c
index 1573e41..102953a 100644
--- a/btrfs-convert.c
+++ b/btrfs-convert.c
@@ -1863,6 +1863,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;
diff --git a/mkfs.c b/mkfs.c
index 3ef3890..9e5e66d 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -973,7 +973,7 @@ static int create_chunks(struct btrfs_trans_handle *trans,
 		size_of_data = minimum_data_chunk_size;
 
 	ret = btrfs_alloc_data_chunk(trans, root->fs_info->extent_root,
-				     &chunk_start, size_of_data, data_type);
+				     &chunk_start, size_of_data, data_type, 0);
 	BUG_ON(ret);
 	ret = btrfs_make_block_group(trans, root->fs_info->extent_root, 0,
 				     data_type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
diff --git a/volumes.c b/volumes.c
index 4e683bb..edc381e 100644
--- a/volumes.c
+++ b/volumes.c
@@ -399,7 +399,7 @@ static int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
 				  struct btrfs_device *device,
 				  u64 chunk_tree, u64 chunk_objectid,
 				  u64 chunk_offset,
-				  u64 num_bytes, u64 *start)
+				  u64 num_bytes, u64 *start, int convert)
 {
 	int ret;
 	struct btrfs_path *path;
@@ -412,9 +412,15 @@ static int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
 	if (!path)
 		return -ENOMEM;
 
-	ret = find_free_dev_extent(trans, device, path, num_bytes, start);
-	if (ret) {
-		goto err;
+	/*
+	 * For convert case, just skip search free dev_extent, as caller
+	 * is responsible to ensure it's free.
+	 */
+	if (!convert) {
+		ret = find_free_dev_extent(trans, device, path, num_bytes,
+					   start);
+		if (ret)
+			goto err;
 	}
 
 	key.objectid = device->devid;
@@ -973,7 +979,7 @@ again:
 		ret = btrfs_alloc_dev_extent(trans, device,
 			     info->chunk_root->root_key.objectid,
 			     BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset,
-			     calc_size, &dev_offset);
+			     calc_size, &dev_offset, 0);
 		BUG_ON(ret);
 
 		device->bytes_used += calc_size;
@@ -1029,9 +1035,17 @@ again:
 	return ret;
 }
 
+/*
+ * Alloc a DATA chunk with SINGLE profile.
+ *
+ * If 'convert' is set, it will alloc a chunk with 1:1 mapping
+ * (btrfs logical bytenr == on-disk bytenr)
+ * For that case, caller must ensure the chunk and dev_extent is not
+ * occupied.
+ */
 int btrfs_alloc_data_chunk(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *extent_root, u64 *start,
-			   u64 num_bytes, u64 type)
+			   u64 num_bytes, u64 type, int convert)
 {
 	u64 dev_offset;
 	struct btrfs_fs_info *info = extent_root->fs_info;
@@ -1052,10 +1066,17 @@ int btrfs_alloc_data_chunk(struct btrfs_trans_handle *trans,
 
 	key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
 	key.type = BTRFS_CHUNK_ITEM_KEY;
-	ret = find_next_chunk(chunk_root, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
-			      &key.offset);
-	if (ret)
-		return ret;
+	if (convert) {
+		BUG_ON(*start != round_down(*start, extent_root->sectorsize));
+		key.offset = *start;
+		dev_offset = *start;
+	} else {
+		ret = find_next_chunk(chunk_root,
+				      BTRFS_FIRST_CHUNK_TREE_OBJECTID,
+				      &key.offset);
+		if (ret)
+			return ret;
+	}
 
 	chunk = kmalloc(btrfs_chunk_item_size(num_stripes), GFP_NOFS);
 	if (!chunk)
@@ -1080,7 +1101,7 @@ int btrfs_alloc_data_chunk(struct btrfs_trans_handle *trans,
 		ret = btrfs_alloc_dev_extent(trans, device,
 			     info->chunk_root->root_key.objectid,
 			     BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset,
-			     calc_size, &dev_offset);
+			     calc_size, &dev_offset, convert);
 		BUG_ON(ret);
 
 		device->bytes_used += calc_size;
@@ -1117,7 +1138,8 @@ int btrfs_alloc_data_chunk(struct btrfs_trans_handle *trans,
 	ret = btrfs_insert_item(trans, chunk_root, &key, chunk,
 				btrfs_chunk_item_size(num_stripes));
 	BUG_ON(ret);
-	*start = key.offset;
+	if (!convert)
+		*start = key.offset;
 
 	map->ce.start = key.offset;
 	map->ce.size = num_bytes;
diff --git a/volumes.h b/volumes.h
index eb434f1..fccd964 100644
--- a/volumes.h
+++ b/volumes.h
@@ -191,7 +191,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 		      u64 *num_bytes, u64 type);
 int btrfs_alloc_data_chunk(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *extent_root, u64 *start,
-			   u64 num_bytes, u64 type);
+			   u64 num_bytes, u64 type, int convert);
 int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf);
 int btrfs_add_device(struct btrfs_trans_handle *trans,
 		     struct btrfs_root *root,
-- 
2.6.2




  parent reply	other threads:[~2015-12-01  7:14 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-01  7:11 [PATCH v2 00/25] Btrfs-convert rework to support separate chunk type Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 01/25] btrfs-progs: extent-cache: Add comments for search/lookup functions Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 02/25] btrfs-progs: extent-tree: Add add_merge_cache_extent function Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 03/25] btrfs-progs: Introduce new members for btrfs_convert_context Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 04/25] btrfs-progs: convert: Introduce functions to read used space Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 05/25] btrfs-progs: convert: Introduce new function to remove reserved ranges Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 06/25] btrfs-progs: convert: Introduce function to calculate the available space Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 07/25] btrfs-progs: utils: Introduce new function for convert Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 08/25] btrfs-progs: Introduce function to setup temporary superblock Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 09/25] btrfs-progs: Introduce function to setup temporary tree root Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 10/25] btrfs-progs: Introduce function to setup temporary chunk root Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 11/25] btrfs-progs: Introduce function to initialize device tree Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 12/25] btrfs-progs: Introduce function to initialize fs tree Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 13/25] btrfs-progs: Introduce function to initialize csum tree Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 14/25] btrfs-progs: Introduce function to setup temporary extent tree Qu Wenruo
2015-12-01  7:11 ` Qu Wenruo [this message]
2015-12-01  7:11 ` [PATCH v2 16/25] btrfs-progs: extent-tree: Introduce function to find the first overlap extent Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 17/25] btrfs-progs: extent-tree: Enhance btrfs_record_file_extent Qu Wenruo
2016-01-12 10:17   ` David Sterba
2016-01-13  0:33     ` Qu Wenruo
2016-01-13  8:55       ` David Sterba
2015-12-01  7:11 ` [PATCH v2 18/25] btrfs-progs: convert: Introduce new function to create converted image Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 19/25] btrfs-progs: convert: Introduce function to migrate reserved ranges Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 20/25] btrfs-progs: convert: Enhance record_file_blocks to handle " Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 21/25] btrfs-progs: convert: Introduce init_btrfs_v2 function Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 22/25] btrfs-progs: Introduce do_convert_v2 function Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 23/25] btrfs-progs: Convert: Add support for rollback new convert behavior Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 24/25] btrfs-progs: convert: Strictly avoid meta or system chunk allocation Qu Wenruo
2015-12-01  7:11 ` [PATCH v2 25/25] btrfs-progs: Cleanup old btrfs-convert Qu Wenruo
2015-12-07 15:20 ` [PATCH v2 00/25] Btrfs-convert rework to support separate chunk type David Sterba
2015-12-08  1:50   ` Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1448953905-28673-16-git-send-email-quwenruo@cn.fujitsu.com \
    --to=quwenruo@cn.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).