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 14/25] btrfs-progs: Introduce function to setup temporary extent tree
Date: Tue,  1 Dec 2015 15:11:34 +0800	[thread overview]
Message-ID: <1448953905-28673-15-git-send-email-quwenruo@cn.fujitsu.com> (raw)
In-Reply-To: <1448953905-28673-1-git-send-email-quwenruo@cn.fujitsu.com>

Introduce new function, setup_temporary_extent_tree() to build a
temporary extent tree for make_btrfs_v2().

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 utils.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 197 insertions(+), 1 deletion(-)

diff --git a/utils.c b/utils.c
index 43bc6cf..14f3e86 100644
--- a/utils.c
+++ b/utils.c
@@ -697,6 +697,194 @@ out:
 }
 
 /*
+ * Insert one temporary extent item.
+ *
+ * NOTE: if skinny_metadata is not enabled, this function must be called
+ * after all other trees are initialized.
+ * Or fs without skinny-metadata will be screwed up.
+ */
+static int insert_temp_extent_item(int fd, struct extent_buffer *buf,
+				   struct btrfs_mkfs_config *cfg,
+				   int *slot, u32 *itemoff, u64 bytenr,
+				   u64 ref_root)
+{
+	struct extent_buffer *tmp;
+	struct btrfs_extent_item *ei;
+	struct btrfs_extent_inline_ref *iref;
+	struct btrfs_disk_key disk_key;
+	struct btrfs_disk_key tree_info_key;
+	struct btrfs_tree_block_info *info;
+	int itemsize;
+	int skinny_metadata = cfg->features &
+			      BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA;
+	int ret;
+
+	if (skinny_metadata)
+		itemsize = sizeof(*ei) + sizeof(*iref);
+	else
+		itemsize = sizeof(*ei) + sizeof(*iref) +
+			   sizeof(struct btrfs_tree_block_info);
+
+	btrfs_set_header_nritems(buf, *slot + 1);
+	*(itemoff) -= itemsize;
+
+	if (skinny_metadata) {
+		btrfs_set_disk_key_type(&disk_key, BTRFS_METADATA_ITEM_KEY);
+		btrfs_set_disk_key_offset(&disk_key, 0);
+	} else {
+		btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY);
+		btrfs_set_disk_key_offset(&disk_key, cfg->nodesize);
+	}
+	btrfs_set_disk_key_objectid(&disk_key, bytenr);
+
+	btrfs_set_item_key(buf, &disk_key, *slot);
+	btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
+	btrfs_set_item_size(buf, btrfs_item_nr(*slot), itemsize);
+
+	ei = btrfs_item_ptr(buf, *slot, struct btrfs_extent_item);
+	btrfs_set_extent_refs(buf, ei, 1);
+	btrfs_set_extent_generation(buf, ei, 1);
+	btrfs_set_extent_flags(buf, ei, BTRFS_EXTENT_FLAG_TREE_BLOCK);
+
+	if (skinny_metadata) {
+		iref = (struct btrfs_extent_inline_ref *)(ei + 1);
+	} else {
+		info = (struct btrfs_tree_block_info *)(ei + 1);
+		iref = (struct btrfs_extent_inline_ref *)(info + 1);
+	}
+	btrfs_set_extent_inline_ref_type(buf, iref,
+					 BTRFS_TREE_BLOCK_REF_KEY);
+	btrfs_set_extent_inline_ref_offset(buf, iref, ref_root);
+
+	(*slot)++;
+	if (skinny_metadata)
+		return 0;
+
+	/*
+	 * Lastly, check the tree block key by read the tree block
+	 * Since we do 1:1 mapping for convert case, we can directly
+	 * read the bytenr from disk
+	 */
+	tmp = malloc(sizeof(*tmp) + cfg->nodesize);
+	if (!tmp)
+		return -ENOMEM;
+	ret = setup_temp_extent_buffer(tmp, cfg, bytenr, ref_root);
+	if (ret < 0)
+		goto out;
+	ret = pread(fd, tmp->data, cfg->nodesize, bytenr);
+	if (ret < cfg->nodesize) {
+		ret = (ret < 0 ? -errno : -EIO);
+		goto out;
+	}
+	if (btrfs_header_nritems(tmp) == 0) {
+		btrfs_set_disk_key_type(&tree_info_key, 0);
+		btrfs_set_disk_key_objectid(&tree_info_key, 0);
+		btrfs_set_disk_key_offset(&tree_info_key, 0);
+	} else {
+		btrfs_item_key(tmp, &tree_info_key, 0);
+	}
+	btrfs_set_tree_block_key(buf, info, &tree_info_key);
+
+out:
+	free(tmp);
+	return ret;
+}
+
+static void insert_temp_block_group(struct extent_buffer *buf,
+				   struct btrfs_mkfs_config *cfg,
+				   int *slot, u32 *itemoff,
+				   u64 bytenr, u64 len, u64 used, u64 flag)
+{
+	struct btrfs_block_group_item bgi;
+	struct btrfs_disk_key disk_key;
+
+	btrfs_set_header_nritems(buf, *slot + 1);
+	(*itemoff) -= sizeof(bgi);
+	btrfs_set_disk_key_type(&disk_key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+	btrfs_set_disk_key_objectid(&disk_key, bytenr);
+	btrfs_set_disk_key_offset(&disk_key, len);
+	btrfs_set_item_key(buf, &disk_key, *slot);
+	btrfs_set_item_offset(buf, btrfs_item_nr(*slot), *itemoff);
+	btrfs_set_item_size(buf, btrfs_item_nr(*slot), sizeof(bgi));
+
+	btrfs_set_block_group_flags(&bgi, flag);
+	btrfs_set_block_group_used(&bgi, used);
+	btrfs_set_block_group_chunk_objectid(&bgi,
+			BTRFS_FIRST_CHUNK_TREE_OBJECTID);
+	write_extent_buffer(buf, &bgi, btrfs_item_ptr_offset(buf, *slot),
+			    sizeof(bgi));
+	(*slot)++;
+}
+
+static int setup_temp_extent_tree(int fd, struct btrfs_mkfs_config *cfg,
+				  u64 chunk_bytenr, u64 root_bytenr,
+				  u64 extent_bytenr, u64 dev_bytenr,
+				  u64 fs_bytenr, u64 csum_bytenr)
+{
+	struct extent_buffer *buf = NULL;
+	u32 itemoff = __BTRFS_LEAF_DATA_SIZE(cfg->nodesize);
+	int slot = 0;
+	int ret;
+
+	/*
+	 * We must ensure provided bytenr are in ascending order,
+	 * or extent tree key order will be broken.
+	 */
+	BUG_ON(!(chunk_bytenr < root_bytenr && root_bytenr < extent_bytenr &&
+		 extent_bytenr < dev_bytenr && dev_bytenr < fs_bytenr &&
+		 fs_bytenr < csum_bytenr));
+	buf = malloc(sizeof(*buf) + cfg->nodesize);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = setup_temp_extent_buffer(buf, cfg, extent_bytenr,
+				       BTRFS_EXTENT_TREE_OBJECTID);
+	if (ret < 0)
+		goto out;
+
+	ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
+			chunk_bytenr, BTRFS_CHUNK_TREE_OBJECTID);
+	if (ret < 0)
+		goto out;
+
+	insert_temp_block_group(buf, cfg, &slot, &itemoff, chunk_bytenr,
+			BTRFS_MKFS_SYSTEM_GROUP_SIZE, cfg->nodesize,
+			BTRFS_BLOCK_GROUP_SYSTEM);
+
+	ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
+			root_bytenr, BTRFS_ROOT_TREE_OBJECTID);
+	if (ret < 0)
+		goto out;
+
+	/* 5 tree block used, root, extent, dev, fs and csum*/
+	insert_temp_block_group(buf, cfg, &slot, &itemoff, root_bytenr,
+			BTRFS_CONVERT_META_GROUP_SIZE, cfg->nodesize * 5,
+			BTRFS_BLOCK_GROUP_METADATA);
+
+	ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
+			extent_bytenr, BTRFS_EXTENT_TREE_OBJECTID);
+	if (ret < 0)
+		goto out;
+	ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
+			dev_bytenr, BTRFS_DEV_TREE_OBJECTID);
+	if (ret < 0)
+		goto out;
+	ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
+			fs_bytenr, BTRFS_FS_TREE_OBJECTID);
+	if (ret < 0)
+		goto out;
+	ret = insert_temp_extent_item(fd, buf, cfg, &slot, &itemoff,
+			csum_bytenr, BTRFS_CSUM_TREE_OBJECTID);
+	if (ret < 0)
+		goto out;
+
+	ret = write_temp_extent_buffer(fd, buf, extent_bytenr);
+out:
+	free(buf);
+	return ret;
+}
+
+/*
  * Improved version of make_btrfs().
  *
  * This one will
@@ -798,7 +986,15 @@ static int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
 	if (ret < 0)
 		goto out;
 	ret = setup_temp_csum_tree(fd, cfg, csum_bytenr);
-
+	if (ret < 0)
+		goto out;
+	/*
+	 * Setup extent tree lastly, since it may need to read tree block key
+	 * for non-skinny metadata case.
+	 */
+	ret = setup_temp_extent_tree(fd, cfg, chunk_bytenr, root_bytenr,
+				     extent_bytenr, dev_bytenr, fs_bytenr,
+				     csum_bytenr);
 out:
 	return ret;
 }
-- 
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 ` Qu Wenruo [this message]
2015-12-01  7:11 ` [PATCH v2 15/25] btrfs-progs: Introduce function to create convert data chunks Qu Wenruo
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-15-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).