All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lu Fengqi <lufq.fnst@cn.fujitsu.com>
To: Qu Wenruo <wqu@suse.com>, <linux-btrfs@vger.kernel.org>
Cc: <dsterba@suse.cz>
Subject: Re: [PATCH 5/8] btrfs-progs: ctree: Introduce function to create an empty tree
Date: Fri, 3 Nov 2017 17:12:55 +0800	[thread overview]
Message-ID: <c028b81d-99e3-0ad6-57c7-c926c45f0dca@cn.fujitsu.com> (raw)
In-Reply-To: <20171027072936.4697-6-wqu@suse.com>

On 10/27/2017 03:29 PM, Qu Wenruo wrote:
> Introduce a new function, btrfs_create_tree(), to create an empty tree.
> 
> Currently, there is only one caller to create new tree, namely
> data reloc tree in mkfs.
> However it's copying fs tree to create a new root.
> 
> This copy fs tree method is not a good idea if we only need an empty
> tree.
> 
> So here introduce a new function, btrfs_create_tree() to create new
> tree.
> Which will handle the following things:
> 1) New tree root leaf
>     Using generic tree allocation
> 
> 2) New root item in tree root
> 
> 3) Modify special tree root pointers in fs_info
>     Only quota_root is supported yet, but can be expended easily
> 
> This patch provides the basis to implement quota support in mkfs.
> 
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>   ctree.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   ctree.h |   2 ++
>   2 files changed, 111 insertions(+)
> 
> diff --git a/ctree.c b/ctree.c
> index 4fc33b14000a..c707be58c413 100644
> --- a/ctree.c
> +++ b/ctree.c
> @@ -22,6 +22,7 @@
>   #include "repair.h"
>   #include "internal.h"
>   #include "sizes.h"
> +#include "utils.h"
>   
>   static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
>   		      *root, struct btrfs_path *path, int level);
> @@ -136,6 +137,114 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
>   	return 0;
>   }
>   
> +/*
> + * Create a new tree root, with root objectid set to @objectid.
> + *
> + * NOTE: Doesn't support tree with non-zero offset, like tree reloc tree.
> + */
> +int btrfs_create_root(struct btrfs_trans_handle *trans,
> +		      struct btrfs_fs_info *fs_info, u64 objectid)
> +{
> +	struct extent_buffer *node;
> +	struct btrfs_root *new_root;
> +	struct btrfs_disk_key disk_key;
> +	struct btrfs_key location;
> +	struct btrfs_root_item root_item = { 0 };
> +	int ret;
> +
> +	new_root = malloc(sizeof(*new_root));
> +	if (!new_root)
> +		return -ENOMEM;
> +
> +	btrfs_setup_root(new_root, fs_info, objectid);
> +	if (!is_fstree(objectid))
> +		new_root->track_dirty = 1;
> +	add_root_to_dirty_list(new_root);

Since add_root_to_dirty_list only add root which track_dirty != 0 to 
dirty list, why not write like the following?

         if (!is_fstree(objectid)) {
                 new_root->track_dirty = 1;
                 add_root_to_dirty_list(new_root);
         }

> +
> +	new_root->objectid = objectid;
> +	new_root->root_key.objectid = objectid;

These have been initialized in btrfs_setup_root, so we don't need to 
initialize again.

> +	new_root->root_key.type = BTRFS_ROOT_ITEM_KEY;
> +	new_root->root_key.offset = 0;
> +
> +	node = btrfs_alloc_free_block(trans, new_root, fs_info->nodesize,
> +				      objectid, &disk_key, 0, 0, 0);
> +	if (IS_ERR(node)) {
> +		ret = PTR_ERR(node);
> +		error("failed to create root node for tree %llu: %d (%s)",
> +		      objectid, ret, strerror(-ret));
> +		return ret;
> +	}
> +	new_root->node = node;
> +
> +	btrfs_set_header_generation(node, trans->transid);
> +	btrfs_set_header_backref_rev(node, BTRFS_MIXED_BACKREF_REV);
> +	btrfs_clear_header_flag(node, BTRFS_HEADER_FLAG_RELOC |
> +				      BTRFS_HEADER_FLAG_WRITTEN);
> +	btrfs_set_header_owner(node, objectid);
> +	btrfs_set_header_nritems(node, 0);
> +	btrfs_set_header_level(node, 0);
> +	write_extent_buffer(node, fs_info->fsid, btrfs_header_fsid(),
> +			    BTRFS_FSID_SIZE);
> +	ret = btrfs_inc_ref(trans, new_root, node, 0);
> +	if (ret < 0)
> +		goto free;
> +
> +	/*
> +	 * Special tree roots may need to modify pointers in @fs_info
> +	 * Only quota is supported yet.
> +	 */
> +	switch (objectid) {
> +	case BTRFS_QUOTA_TREE_OBJECTID:
> +		if (fs_info->quota_root) {
> +			error("quota root already exists");
> +			ret = -EEXIST;
> +			goto free;
> +		}
> +		fs_info->quota_root = new_root;
> +		fs_info->quota_enabled = 1;
> +		break;
> +	/*
> +	 * Essential trees can't be created by this function, yet.
> +	 * As we expect such skeleton exists, or a lot of functions like
> +	 * btrfs_alloc_free_block() doesn't work at all
> +	 */
> +	case BTRFS_ROOT_TREE_OBJECTID:
> +	case BTRFS_EXTENT_TREE_OBJECTID:
> +	case BTRFS_CHUNK_TREE_OBJECTID:
> +	case BTRFS_FS_TREE_OBJECTID:
> +		ret = -EEXIST;
> +		goto free;
> +	default:
> +		/* Subvolume trees don't need special handles */
> +		if (is_fstree(objectid))
> +			break;
> +		/* Other special trees are not supported yet */
> +		ret = -ENOTTY;
> +		goto free;
> +	}
> +	btrfs_mark_buffer_dirty(node);
> +	btrfs_set_root_bytenr(&root_item, btrfs_header_bytenr(node));
> +	btrfs_set_root_level(&root_item, 0);
> +	btrfs_set_root_generation(&root_item, trans->transid);
> +	btrfs_set_root_dirid(&root_item, 0);
> +	btrfs_set_root_refs(&root_item, 1);
> +	btrfs_set_root_used(&root_item, fs_info->nodesize);
> +	location.objectid = objectid;
> +	location.type = BTRFS_ROOT_ITEM_KEY;
> +	location.offset = 0;
> +
> +	ret = btrfs_insert_root(trans, fs_info->tree_root, &location,
> +				&root_item);
> +	if (ret < 0)
> +		goto free;
> +	return ret;
> +
> +free:
> +	free_extent_buffer(node);
> +	free(new_root);
> +	return ret;
> +}
> +
>   /*
>    * check if the tree block can be shared by multiple trees
>    */
> diff --git a/ctree.h b/ctree.h
> index 506b76766579..ac8ce70a55e7 100644
> --- a/ctree.h
> +++ b/ctree.h
> @@ -2558,6 +2558,8 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
>   		      struct btrfs_root *root,
>   		      struct extent_buffer *buf,
>   		      struct extent_buffer **cow_ret, u64 new_root_objectid);
> +int btrfs_create_root(struct btrfs_trans_handle *trans,
> +		      struct btrfs_fs_info *fs_info, u64 objectid);
>   int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
>   		u32 data_size);
>   int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
> 


-- 
Thanks,
Lu



  reply	other threads:[~2017-11-03  9:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-27  7:29 [PATCH 0/8] mkfs: Quota support Qu Wenruo
2017-10-27  7:29 ` [PATCH 1/8] btrfs-progs: qgroup-verify: Also repair qgroup status version Qu Wenruo
2017-10-27  7:29 ` [PATCH 2/8] btrfs-progs: qgroup-verify: Use fs_info->readonly to check if we should repair qgroups Qu Wenruo
2017-10-27  7:29 ` [PATCH 3/8] btrfs-progs: qgroup-verify: Move qgroup classification out of report_qgroups Qu Wenruo
2017-11-04 14:20   ` Lu Fengqi
2017-10-27  7:29 ` [PATCH 4/8] btrfs-progs: qgroup-verify: Allow repair_qgroups function to do silent repair Qu Wenruo
2017-10-27  7:29 ` [PATCH 5/8] btrfs-progs: ctree: Introduce function to create an empty tree Qu Wenruo
2017-11-03  9:12   ` Lu Fengqi [this message]
2017-10-27  7:29 ` [PATCH 6/8] btrfs-progs: mkfs: Introduce function to insert qgroup info and limit items Qu Wenruo
2017-10-27  7:29 ` [PATCH 7/8] btrfs-progs: mkfs: Introduce option to enable quota at mkfs time Qu Wenruo
2017-10-27  7:29 ` [PATCH 8/8] btrfs-progs: test/mkfs: Add test case for --enable-quota option Qu Wenruo
2017-10-27 17:37 ` [PATCH 0/8] mkfs: Quota support David Sterba
2017-10-27 23:57   ` Qu Wenruo
2017-11-01  7:18   ` Qu Wenruo
2017-11-04 14:28 ` Lu Fengqi

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=c028b81d-99e3-0ad6-57c7-c926c45f0dca@cn.fujitsu.com \
    --to=lufq.fnst@cn.fujitsu.com \
    --cc=dsterba@suse.cz \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=wqu@suse.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.