linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: <fdmanana@kernel.org>, <linux-btrfs@vger.kernel.org>
Cc: Filipe Manana <fdmanana@suse.com>
Subject: Re: [PATCH 2/2 v3] Btrfs: fix regression running delayed references when using qgroups
Date: Mon, 26 Oct 2015 16:32:08 +0800	[thread overview]
Message-ID: <562DE508.3060103@cn.fujitsu.com> (raw)
In-Reply-To: <1445799103-13601-1-git-send-email-fdmanana@kernel.org>



  wrote on 2015/10/25 18:51 +0000:
> From: Filipe Manana <fdmanana@suse.com>
>
> In the kernel 4.2 merge window we had a big changes to the implementation
> of delayed references and qgroups which made the no_quota field of delayed
> references not used anymore. More specifically the no_quota field is not
> used anymore as of:
>
>    commit 0ed4792af0e8 ("btrfs: qgroup: Switch to new extent-oriented qgroup mechanism.")
>
> Leaving the no_quota field actually prevents delayed references from
> getting merged, which in turn cause the following BUG_ON(), at
> fs/btrfs/extent-tree.c, to be hit when qgroups are enabled:
>
>    static int run_delayed_tree_ref(...)
>    {
>       (...)
>       BUG_ON(node->ref_mod != 1);
>       (...)
>    }
>
> This happens on a scenario like the following:
>
>    1) Ref1 bytenr X, action = BTRFS_ADD_DELAYED_REF, no_quota = 1, added.
>
>    2) Ref2 bytenr X, action = BTRFS_DROP_DELAYED_REF, no_quota = 0, added.
>       It's not merged with Ref1 because Ref1->no_quota != Ref2->no_quota.
>
>    3) Ref3 bytenr X, action = BTRFS_ADD_DELAYED_REF, no_quota = 1, added.
>       It's not merged with the reference at the tail of the list of refs
>       for bytenr X because the reference at the tail, Ref2 is incompatible
>       due to Ref2->no_quota != Ref3->no_quota.
>
>    4) Ref4 bytenr X, action = BTRFS_DROP_DELAYED_REF, no_quota = 0, added.
>       It's not merged with the reference at the tail of the list of refs
>       for bytenr X because the reference at the tail, Ref3 is incompatible
>       due to Ref3->no_quota != Ref4->no_quota.
>
>    5) We run delayed references, trigger merging of delayed references,
>       through __btrfs_run_delayed_refs() -> btrfs_merge_delayed_refs().
>
>    6) Ref1 and Ref3 are merged as Ref1->no_quota = Ref3->no_quota and
>       all other conditions are satisfied too. So Ref1 gets a ref_mod
>       value of 2.
>
>    7) Ref2 and Ref4 are merged as Ref2->no_quota = Ref4->no_quota and
>       all other conditions are satisfied too. So Ref2 gets a ref_mod
>       value of 2.
>
>    8) Ref1 and Ref2 aren't merged, because they have different values
>       for their no_quota field.
>
>    9) Delayed reference Ref1 is picked for running (select_delayed_ref()
>       always prefers references with an action == BTRFS_ADD_DELAYED_REF).
>       So run_delayed_tree_ref() is called for Ref1 which triggers the
>       BUG_ON because Ref1->red_mod != 1 (equals 2).
>
> So fix this by removing the no_quota field, as it's not used anymore as
> of commit 0ed4792af0e8 ("btrfs: qgroup: Switch to new extent-oriented
> qgroup mechanism.").
>
> The use of no_quota was also buggy in at least two places:
>
> 1) At delayed-refs.c:btrfs_add_delayed_tree_ref() - we were setting
>     no_quota to 0 instead of 1 when the following condition was true:
>     is_fstree(ref_root) || !fs_info->quota_enabled
>
> 2) At extent-tree.c:__btrfs_inc_extent_ref() - we were attempting to
>     reset a node's no_quota when the condition "!is_fstree(root_objectid)
>     || !root->fs_info->quota_enabled" was true but we did it only in
>     an unused local stack variable, that is, we never reset the no_quota
>     value in the node itself.
>
> This fixes the remainder of problems several people have been having when
> running delayed references, mostly while a balance is running in parallel,
> on a 4.2+ kernel.
>
> Very special thanks to Stéphane Lesimple for helping debugging this issue
> and testing this fix on his multi terabyte filesystem (which took more
> than one day to balance alone, plus fsck, etc).
>
> Also, this fixes deadlock issue when using the clone ioctl with qgroups
> enabled, as reported by Elias Probst in the mailing list. The deadlock
> happens because after calling btrfs_insert_empty_item we have our path
> holding a write lock on a leaf of the fs/subvol tree and then before
> releasing the path we called check_ref() which did backref walking, when
> qgroups are enabled, and tried to read lock the same leaf. The trace for
> this case is the following:
>
>    INFO: task systemd-nspawn:6095 blocked for more than 120 seconds.
>    (...)
>    Call Trace:
>      [<ffffffff86999201>] schedule+0x74/0x83
>      [<ffffffff863ef64c>] btrfs_tree_read_lock+0xc0/0xea
>      [<ffffffff86137ed7>] ? wait_woken+0x74/0x74
>      [<ffffffff8639f0a7>] btrfs_search_old_slot+0x51a/0x810
>      [<ffffffff863a129b>] btrfs_next_old_leaf+0xdf/0x3ce
>      [<ffffffff86413a00>] ? ulist_add_merge+0x1b/0x127
>      [<ffffffff86411688>] __resolve_indirect_refs+0x62a/0x667
>      [<ffffffff863ef546>] ? btrfs_clear_lock_blocking_rw+0x78/0xbe
>      [<ffffffff864122d3>] find_parent_nodes+0xaf3/0xfc6
>      [<ffffffff86412838>] __btrfs_find_all_roots+0x92/0xf0
>      [<ffffffff864128f2>] btrfs_find_all_roots+0x45/0x65
>      [<ffffffff8639a75b>] ? btrfs_get_tree_mod_seq+0x2b/0x88
>      [<ffffffff863e852e>] check_ref+0x64/0xc4
>      [<ffffffff863e9e01>] btrfs_clone+0x66e/0xb5d
>      [<ffffffff863ea77f>] btrfs_ioctl_clone+0x48f/0x5bb
>      [<ffffffff86048a68>] ? native_sched_clock+0x28/0x77
>      [<ffffffff863ed9b0>] btrfs_ioctl+0xabc/0x25cb
>    (...)
>
> Reported-by: Stéphane Lesimple <stephane_btrfs@lesimple.fr>
> Tested-by: Stéphane Lesimple <stephane_btrfs@lesimple.fr>
> Reported-by: Elias Probst <mail@eliasprobst.eu>
> Reported-by: Peter Becker <floyd.net@gmail.com>
> Reported-by: Malte Schröder <malte@tnxip.de>
> Reported-by: Derek Dongray <derek@valedon.co.uk>
> Reported-by: Erkki Seppala <flux-btrfs@inside.org>
> Cc: stable@vger.kernel.org  # 4.2+
> Signed-off-by: Filipe Manana <fdmanana@suse.com>

Reviewed-by: Qu Wenruo <quwenruo@cn.fujitsu.com>

Thanks,
Qu

> ---
>
> V2: There was no v1. But since the first patch in the series became
>      a v2, made this one a v2 from the start.
> V3: Updated changelog to point out the clone ioctl deadlock when
>      qgroups are enabled, and 2 bugs of no_quota field usage.
>
>   fs/btrfs/ctree.h       |  4 ++--
>   fs/btrfs/delayed-ref.c | 28 +++++++----------------
>   fs/btrfs/delayed-ref.h |  7 ++----
>   fs/btrfs/extent-tree.c | 45 +++++++++++++-----------------------
>   fs/btrfs/file.c        | 10 ++++----
>   fs/btrfs/inode.c       |  4 ++--
>   fs/btrfs/ioctl.c       | 62 +-------------------------------------------------
>   fs/btrfs/relocation.c  | 16 ++++++-------
>   fs/btrfs/tree-log.c    |  2 +-
>   9 files changed, 44 insertions(+), 134 deletions(-)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index bc3c711..3fa3c3b 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -3422,7 +3422,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
>   int btrfs_free_extent(struct btrfs_trans_handle *trans,
>   		      struct btrfs_root *root,
>   		      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
> -		      u64 owner, u64 offset, int no_quota);
> +		      u64 owner, u64 offset);
>
>   int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len,
>   			       int delalloc);
> @@ -3435,7 +3435,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
>   int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>   			 struct btrfs_root *root,
>   			 u64 bytenr, u64 num_bytes, u64 parent,
> -			 u64 root_objectid, u64 owner, u64 offset, int no_quota);
> +			 u64 root_objectid, u64 owner, u64 offset);
>
>   int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
>   				   struct btrfs_root *root);
> diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
> index 2f41580..1c3588a 100644
> --- a/fs/btrfs/delayed-ref.c
> +++ b/fs/btrfs/delayed-ref.c
> @@ -220,7 +220,7 @@ static bool merge_ref(struct btrfs_trans_handle *trans,
>   		if (seq && next->seq >= seq)
>   			goto next;
>
> -		if (next->type != ref->type || next->no_quota != ref->no_quota)
> +		if (next->type != ref->type)
>   			goto next;
>
>   		if ((ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
> @@ -405,8 +405,7 @@ add_delayed_ref_tail_merge(struct btrfs_trans_handle *trans,
>   	exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node,
>   			   list);
>   	/* No need to compare bytenr nor is_head */
> -	if (exist->type != ref->type || exist->no_quota != ref->no_quota ||
> -	    exist->seq != ref->seq)
> +	if (exist->type != ref->type || exist->seq != ref->seq)
>   		goto add_tail;
>
>   	if ((exist->type == BTRFS_TREE_BLOCK_REF_KEY ||
> @@ -639,7 +638,7 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
>   		     struct btrfs_delayed_ref_head *head_ref,
>   		     struct btrfs_delayed_ref_node *ref, u64 bytenr,
>   		     u64 num_bytes, u64 parent, u64 ref_root, int level,
> -		     int action, int no_quota)
> +		     int action)
>   {
>   	struct btrfs_delayed_tree_ref *full_ref;
>   	struct btrfs_delayed_ref_root *delayed_refs;
> @@ -661,7 +660,6 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
>   	ref->action = action;
>   	ref->is_head = 0;
>   	ref->in_tree = 1;
> -	ref->no_quota = no_quota;
>   	ref->seq = seq;
>
>   	full_ref = btrfs_delayed_node_to_tree_ref(ref);
> @@ -694,7 +692,7 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
>   		     struct btrfs_delayed_ref_head *head_ref,
>   		     struct btrfs_delayed_ref_node *ref, u64 bytenr,
>   		     u64 num_bytes, u64 parent, u64 ref_root, u64 owner,
> -		     u64 offset, int action, int no_quota)
> +		     u64 offset, int action)
>   {
>   	struct btrfs_delayed_data_ref *full_ref;
>   	struct btrfs_delayed_ref_root *delayed_refs;
> @@ -717,7 +715,6 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
>   	ref->action = action;
>   	ref->is_head = 0;
>   	ref->in_tree = 1;
> -	ref->no_quota = no_quota;
>   	ref->seq = seq;
>
>   	full_ref = btrfs_delayed_node_to_data_ref(ref);
> @@ -748,17 +745,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
>   			       struct btrfs_trans_handle *trans,
>   			       u64 bytenr, u64 num_bytes, u64 parent,
>   			       u64 ref_root,  int level, int action,
> -			       struct btrfs_delayed_extent_op *extent_op,
> -			       int no_quota)
> +			       struct btrfs_delayed_extent_op *extent_op)
>   {
>   	struct btrfs_delayed_tree_ref *ref;
>   	struct btrfs_delayed_ref_head *head_ref;
>   	struct btrfs_delayed_ref_root *delayed_refs;
>   	struct btrfs_qgroup_extent_record *record = NULL;
>
> -	if (!is_fstree(ref_root) || !fs_info->quota_enabled)
> -		no_quota = 0;
> -
>   	BUG_ON(extent_op && extent_op->is_data);
>   	ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
>   	if (!ref)
> @@ -787,8 +780,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
>   					bytenr, num_bytes, action, 0);
>
>   	add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
> -				   num_bytes, parent, ref_root, level, action,
> -				   no_quota);
> +			     num_bytes, parent, ref_root, level, action);
>   	spin_unlock(&delayed_refs->lock);
>
>   	return 0;
> @@ -809,17 +801,13 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
>   			       u64 bytenr, u64 num_bytes,
>   			       u64 parent, u64 ref_root,
>   			       u64 owner, u64 offset, int action,
> -			       struct btrfs_delayed_extent_op *extent_op,
> -			       int no_quota)
> +			       struct btrfs_delayed_extent_op *extent_op)
>   {
>   	struct btrfs_delayed_data_ref *ref;
>   	struct btrfs_delayed_ref_head *head_ref;
>   	struct btrfs_delayed_ref_root *delayed_refs;
>   	struct btrfs_qgroup_extent_record *record = NULL;
>
> -	if (!is_fstree(ref_root) || !fs_info->quota_enabled)
> -		no_quota = 0;
> -
>   	BUG_ON(extent_op && !extent_op->is_data);
>   	ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
>   	if (!ref)
> @@ -855,7 +843,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
>
>   	add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
>   				   num_bytes, parent, ref_root, owner, offset,
> -				   action, no_quota);
> +				   action);
>   	spin_unlock(&delayed_refs->lock);
>
>   	return 0;
> diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
> index d4c41e2..f9cf234 100644
> --- a/fs/btrfs/delayed-ref.h
> +++ b/fs/btrfs/delayed-ref.h
> @@ -68,7 +68,6 @@ struct btrfs_delayed_ref_node {
>
>   	unsigned int action:8;
>   	unsigned int type:8;
> -	unsigned int no_quota:1;
>   	/* is this node still in the rbtree? */
>   	unsigned int is_head:1;
>   	unsigned int in_tree:1;
> @@ -244,15 +243,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
>   			       struct btrfs_trans_handle *trans,
>   			       u64 bytenr, u64 num_bytes, u64 parent,
>   			       u64 ref_root, int level, int action,
> -			       struct btrfs_delayed_extent_op *extent_op,
> -			       int no_quota);
> +			       struct btrfs_delayed_extent_op *extent_op);
>   int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
>   			       struct btrfs_trans_handle *trans,
>   			       u64 bytenr, u64 num_bytes,
>   			       u64 parent, u64 ref_root,
>   			       u64 owner, u64 offset, int action,
> -			       struct btrfs_delayed_extent_op *extent_op,
> -			       int no_quota);
> +			       struct btrfs_delayed_extent_op *extent_op);
>   int btrfs_add_delayed_qgroup_reserve(struct btrfs_fs_info *fs_info,
>   				     struct btrfs_trans_handle *trans,
>   				     u64 ref_root, u64 bytenr, u64 num_bytes);
> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
> index c0f30f5..c1f8c7e 100644
> --- a/fs/btrfs/extent-tree.c
> +++ b/fs/btrfs/extent-tree.c
> @@ -95,8 +95,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
>   				     struct btrfs_root *root,
>   				     u64 parent, u64 root_objectid,
>   				     u64 flags, struct btrfs_disk_key *key,
> -				     int level, struct btrfs_key *ins,
> -				     int no_quota);
> +				     int level, struct btrfs_key *ins);
>   static int do_chunk_alloc(struct btrfs_trans_handle *trans,
>   			  struct btrfs_root *extent_root, u64 flags,
>   			  int force);
> @@ -2073,8 +2072,7 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
>   int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>   			 struct btrfs_root *root,
>   			 u64 bytenr, u64 num_bytes, u64 parent,
> -			 u64 root_objectid, u64 owner, u64 offset,
> -			 int no_quota)
> +			 u64 root_objectid, u64 owner, u64 offset)
>   {
>   	int ret;
>   	struct btrfs_fs_info *fs_info = root->fs_info;
> @@ -2086,12 +2084,12 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>   		ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
>   					num_bytes,
>   					parent, root_objectid, (int)owner,
> -					BTRFS_ADD_DELAYED_REF, NULL, no_quota);
> +					BTRFS_ADD_DELAYED_REF, NULL);
>   	} else {
>   		ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
>   					num_bytes,
>   					parent, root_objectid, owner, offset,
> -					BTRFS_ADD_DELAYED_REF, NULL, no_quota);
> +					BTRFS_ADD_DELAYED_REF, NULL);
>   	}
>   	return ret;
>   }
> @@ -2112,15 +2110,11 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
>   	u64 num_bytes = node->num_bytes;
>   	u64 refs;
>   	int ret;
> -	int no_quota = node->no_quota;
>
>   	path = btrfs_alloc_path();
>   	if (!path)
>   		return -ENOMEM;
>
> -	if (!is_fstree(root_objectid) || !root->fs_info->quota_enabled)
> -		no_quota = 1;
> -
>   	path->reada = 1;
>   	path->leave_spinning = 1;
>   	/* this will setup the path even if it fails to insert the back ref */
> @@ -2355,8 +2349,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
>   						parent, ref_root,
>   						extent_op->flags_to_set,
>   						&extent_op->key,
> -						ref->level, &ins,
> -						node->no_quota);
> +						ref->level, &ins);
>   	} else if (node->action == BTRFS_ADD_DELAYED_REF) {
>   		ret = __btrfs_inc_extent_ref(trans, root, node,
>   					     parent, ref_root,
> @@ -3192,7 +3185,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
>   	int level;
>   	int ret = 0;
>   	int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
> -			    u64, u64, u64, u64, u64, u64, int);
> +			    u64, u64, u64, u64, u64, u64);
>
>
>   	if (btrfs_test_is_dummy_root(root))
> @@ -3233,15 +3226,14 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
>   			key.offset -= btrfs_file_extent_offset(buf, fi);
>   			ret = process_func(trans, root, bytenr, num_bytes,
>   					   parent, ref_root, key.objectid,
> -					   key.offset, 1);
> +					   key.offset);
>   			if (ret)
>   				goto fail;
>   		} else {
>   			bytenr = btrfs_node_blockptr(buf, i);
>   			num_bytes = root->nodesize;
>   			ret = process_func(trans, root, bytenr, num_bytes,
> -					   parent, ref_root, level - 1, 0,
> -					   1);
> +					   parent, ref_root, level - 1, 0);
>   			if (ret)
>   				goto fail;
>   		}
> @@ -6431,7 +6423,6 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
>   	int extent_slot = 0;
>   	int found_extent = 0;
>   	int num_to_del = 1;
> -	int no_quota = node->no_quota;
>   	u32 item_size;
>   	u64 refs;
>   	u64 bytenr = node->bytenr;
> @@ -6440,9 +6431,6 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
>   	bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
>   						 SKINNY_METADATA);
>
> -	if (!info->quota_enabled || !is_fstree(root_objectid))
> -		no_quota = 1;
> -
>   	path = btrfs_alloc_path();
>   	if (!path)
>   		return -ENOMEM;
> @@ -6768,7 +6756,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
>   					buf->start, buf->len,
>   					parent, root->root_key.objectid,
>   					btrfs_header_level(buf),
> -					BTRFS_DROP_DELAYED_REF, NULL, 0);
> +					BTRFS_DROP_DELAYED_REF, NULL);
>   		BUG_ON(ret); /* -ENOMEM */
>   	}
>
> @@ -6816,7 +6804,7 @@ out:
>   /* Can return -ENOMEM */
>   int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
>   		      u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
> -		      u64 owner, u64 offset, int no_quota)
> +		      u64 owner, u64 offset)
>   {
>   	int ret;
>   	struct btrfs_fs_info *fs_info = root->fs_info;
> @@ -6839,13 +6827,13 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
>   		ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
>   					num_bytes,
>   					parent, root_objectid, (int)owner,
> -					BTRFS_DROP_DELAYED_REF, NULL, no_quota);
> +					BTRFS_DROP_DELAYED_REF, NULL);
>   	} else {
>   		ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
>   						num_bytes,
>   						parent, root_objectid, owner,
>   						offset, BTRFS_DROP_DELAYED_REF,
> -						NULL, no_quota);
> +						NULL);
>   	}
>   	return ret;
>   }
> @@ -7690,8 +7678,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
>   				     struct btrfs_root *root,
>   				     u64 parent, u64 root_objectid,
>   				     u64 flags, struct btrfs_disk_key *key,
> -				     int level, struct btrfs_key *ins,
> -				     int no_quota)
> +				     int level, struct btrfs_key *ins)
>   {
>   	int ret;
>   	struct btrfs_fs_info *fs_info = root->fs_info;
> @@ -7781,7 +7768,7 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
>   	ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid,
>   					 ins->offset, 0,
>   					 root_objectid, owner, offset,
> -					 BTRFS_ADD_DELAYED_EXTENT, NULL, 0);
> +					 BTRFS_ADD_DELAYED_EXTENT, NULL);
>   	return ret;
>   }
>
> @@ -7995,7 +7982,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
>   						 ins.objectid, ins.offset,
>   						 parent, root_objectid, level,
>   						 BTRFS_ADD_DELAYED_EXTENT,
> -						 extent_op, 0);
> +						 extent_op);
>   		if (ret)
>   			goto out_free_delayed;
>   	}
> @@ -8544,7 +8531,7 @@ skip:
>   			}
>   		}
>   		ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
> -				root->root_key.objectid, level - 1, 0, 0);
> +				root->root_key.objectid, level - 1, 0);
>   		BUG_ON(ret); /* -ENOMEM */
>   	}
>   	btrfs_tree_unlock(next);
> diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
> index 1243205..381be79 100644
> --- a/fs/btrfs/file.c
> +++ b/fs/btrfs/file.c
> @@ -847,7 +847,7 @@ next_slot:
>   						disk_bytenr, num_bytes, 0,
>   						root->root_key.objectid,
>   						new_key.objectid,
> -						start - extent_offset, 1);
> +						start - extent_offset);
>   				BUG_ON(ret); /* -ENOMEM */
>   			}
>   			key.offset = start;
> @@ -925,7 +925,7 @@ delete_extent_item:
>   						disk_bytenr, num_bytes, 0,
>   						root->root_key.objectid,
>   						key.objectid, key.offset -
> -						extent_offset, 0);
> +						extent_offset);
>   				BUG_ON(ret); /* -ENOMEM */
>   				inode_sub_bytes(inode,
>   						extent_end - key.offset);
> @@ -1204,7 +1204,7 @@ again:
>
>   		ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0,
>   					   root->root_key.objectid,
> -					   ino, orig_offset, 1);
> +					   ino, orig_offset);
>   		BUG_ON(ret); /* -ENOMEM */
>
>   		if (split == start) {
> @@ -1231,7 +1231,7 @@ again:
>   		del_nr++;
>   		ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
>   					0, root->root_key.objectid,
> -					ino, orig_offset, 0);
> +					ino, orig_offset);
>   		BUG_ON(ret); /* -ENOMEM */
>   	}
>   	other_start = 0;
> @@ -1248,7 +1248,7 @@ again:
>   		del_nr++;
>   		ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
>   					0, root->root_key.objectid,
> -					ino, orig_offset, 0);
> +					ino, orig_offset);
>   		BUG_ON(ret); /* -ENOMEM */
>   	}
>   	if (del_nr == 0) {
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index a018e47..6f030c2 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -2595,7 +2595,7 @@ again:
>   	ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
>   			new->disk_len, 0,
>   			backref->root_id, backref->inum,
> -			new->file_pos, 0);	/* start - extent_offset */
> +			new->file_pos);	/* start - extent_offset */
>   	if (ret) {
>   		btrfs_abort_transaction(trans, root, ret);
>   		goto out_free_path;
> @@ -4541,7 +4541,7 @@ delete:
>   			ret = btrfs_free_extent(trans, root, extent_start,
>   						extent_num_bytes, 0,
>   						btrfs_header_owner(leaf),
> -						ino, extent_offset, 0);
> +						ino, extent_offset);
>   			BUG_ON(ret);
>   			if (btrfs_should_throttle_delayed_refs(trans, root))
>   				btrfs_async_run_delayed_refs(root,
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 7ed033a..4df0f2b 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -3206,41 +3206,6 @@ out:
>   	return ret;
>   }
>
> -/* Helper to check and see if this root currently has a ref on the given disk
> - * bytenr.  If it does then we need to update the quota for this root.  This
> - * doesn't do anything if quotas aren't enabled.
> - */
> -static int check_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
> -		     u64 disko)
> -{
> -	struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem);
> -	struct ulist *roots;
> -	struct ulist_iterator uiter;
> -	struct ulist_node *root_node = NULL;
> -	int ret;
> -
> -	if (!root->fs_info->quota_enabled)
> -		return 1;
> -
> -	btrfs_get_tree_mod_seq(root->fs_info, &tree_mod_seq_elem);
> -	ret = btrfs_find_all_roots(trans, root->fs_info, disko,
> -				   tree_mod_seq_elem.seq, &roots);
> -	if (ret < 0)
> -		goto out;
> -	ret = 0;
> -	ULIST_ITER_INIT(&uiter);
> -	while ((root_node = ulist_next(roots, &uiter))) {
> -		if (root_node->val == root->objectid) {
> -			ret = 1;
> -			break;
> -		}
> -	}
> -	ulist_free(roots);
> -out:
> -	btrfs_put_tree_mod_seq(root->fs_info, &tree_mod_seq_elem);
> -	return ret;
> -}
> -
>   static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
>   				     struct inode *inode,
>   				     u64 endoff,
> @@ -3499,9 +3464,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
>   	u32 nritems;
>   	int slot;
>   	int ret;
> -	int no_quota;
>   	const u64 len = olen_aligned;
> -	u64 last_disko = 0;
>   	u64 last_dest_end = destoff;
>
>   	ret = -ENOMEM;
> @@ -3547,7 +3510,6 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
>
>   		nritems = btrfs_header_nritems(path->nodes[0]);
>   process_slot:
> -		no_quota = 1;
>   		if (path->slots[0] >= nritems) {
>   			ret = btrfs_next_leaf(BTRFS_I(src)->root, path);
>   			if (ret < 0)
> @@ -3699,35 +3661,13 @@ process_slot:
>   				btrfs_set_file_extent_num_bytes(leaf, extent,
>   								datal);
>
> -				/*
> -				 * We need to look up the roots that point at
> -				 * this bytenr and see if the new root does.  If
> -				 * it does not we need to make sure we update
> -				 * quotas appropriately.
> -				 */
> -				if (disko && root != BTRFS_I(src)->root &&
> -				    disko != last_disko) {
> -					no_quota = check_ref(trans, root,
> -							     disko);
> -					if (no_quota < 0) {
> -						btrfs_abort_transaction(trans,
> -									root,
> -									ret);
> -						btrfs_end_transaction(trans,
> -								      root);
> -						ret = no_quota;
> -						goto out;
> -					}
> -				}
> -
>   				if (disko) {
>   					inode_add_bytes(inode, datal);
>   					ret = btrfs_inc_extent_ref(trans, root,
>   							disko, diskl, 0,
>   							root->root_key.objectid,
>   							btrfs_ino(inode),
> -							new_key.offset - datao,
> -							no_quota);
> +							new_key.offset - datao);
>   					if (ret) {
>   						btrfs_abort_transaction(trans,
>   									root,
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index a7dc456..b4ca545 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -1716,7 +1716,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
>   		ret = btrfs_inc_extent_ref(trans, root, new_bytenr,
>   					   num_bytes, parent,
>   					   btrfs_header_owner(leaf),
> -					   key.objectid, key.offset, 1);
> +					   key.objectid, key.offset);
>   		if (ret) {
>   			btrfs_abort_transaction(trans, root, ret);
>   			break;
> @@ -1724,7 +1724,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
>
>   		ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
>   					parent, btrfs_header_owner(leaf),
> -					key.objectid, key.offset, 1);
> +					key.objectid, key.offset);
>   		if (ret) {
>   			btrfs_abort_transaction(trans, root, ret);
>   			break;
> @@ -1900,23 +1900,21 @@ again:
>
>   		ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize,
>   					path->nodes[level]->start,
> -					src->root_key.objectid, level - 1, 0,
> -					1);
> +					src->root_key.objectid, level - 1, 0);
>   		BUG_ON(ret);
>   		ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize,
>   					0, dest->root_key.objectid, level - 1,
> -					0, 1);
> +					0);
>   		BUG_ON(ret);
>
>   		ret = btrfs_free_extent(trans, src, new_bytenr, blocksize,
>   					path->nodes[level]->start,
> -					src->root_key.objectid, level - 1, 0,
> -					1);
> +					src->root_key.objectid, level - 1, 0);
>   		BUG_ON(ret);
>
>   		ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize,
>   					0, dest->root_key.objectid, level - 1,
> -					0, 1);
> +					0);
>   		BUG_ON(ret);
>
>   		btrfs_unlock_up_safe(path, 0);
> @@ -2745,7 +2743,7 @@ static int do_relocation(struct btrfs_trans_handle *trans,
>   						node->eb->start, blocksize,
>   						upper->eb->start,
>   						btrfs_header_owner(upper->eb),
> -						node->level, 0, 1);
> +						node->level, 0);
>   			BUG_ON(ret);
>
>   			ret = btrfs_drop_subtree(trans, root, eb, upper->eb);
> diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
> index 1fffe88..323e12c 100644
> --- a/fs/btrfs/tree-log.c
> +++ b/fs/btrfs/tree-log.c
> @@ -693,7 +693,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
>   				ret = btrfs_inc_extent_ref(trans, root,
>   						ins.objectid, ins.offset,
>   						0, root->root_key.objectid,
> -						key->objectid, offset, 0);
> +						key->objectid, offset);
>   				if (ret)
>   					goto out;
>   			} else {
>

  reply	other threads:[~2015-10-26  8:32 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-25 10:04 [PATCH 1/2 v2] Btrfs: fix regression when running delayed references fdmanana
2015-10-25 10:04 ` [PATCH 2/2 v2] Btrfs: fix regression running delayed references when using qgroups fdmanana
2015-10-25 18:51   ` [PATCH 2/2 v3] " fdmanana
2015-10-26  8:32     ` Qu Wenruo [this message]
2015-10-25 18:51 ` [PATCH 1/2 v3] Btrfs: fix regression when running delayed references fdmanana
2015-12-13 10:51   ` Alex Lyakas
2015-12-13 15:43     ` Filipe Manana
2015-12-13 16:09       ` Alex Lyakas
2015-10-26  9:22 ` [PATCH 1/2 v2] " Liu Bo
2015-10-26  9:27   ` Filipe Manana

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=562DE508.3060103@cn.fujitsu.com \
    --to=quwenruo@cn.fujitsu.com \
    --cc=fdmanana@kernel.org \
    --cc=fdmanana@suse.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).