Home Home > GIT Browse > SLE15-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-05-15 15:04:31 +0200
committerTakashi Iwai <tiwai@suse.de>2019-05-15 15:04:31 +0200
commit9fbb4234d7f2a8b569a0327c54ca5522d87ea2be (patch)
tree4fb21f95c07b066ecb9e031a728db439403e5043
parent967f2f7a96e4e09e10eaa9a0f0652f3811058e1a (diff)
parent81e469327a35bba822048364477c9276e853f236 (diff)
Merge branch 'users/wqu/SLE15/for-next' into SLE15
Pull btrfs fixes from Qu Wenruo
-rw-r--r--patches.suse/0001-btrfs-extent-tree-Fix-a-bug-that-btrfs-is-unable-to-.patch87
-rw-r--r--patches.suse/0003-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch213
-rw-r--r--patches.suse/0004-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch124
-rw-r--r--patches.suse/0006-btrfs-extent-tree-Use-btrfs_ref-to-refactor-add_pinn.patch70
-rw-r--r--patches.suse/0007-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_in.patch370
-rw-r--r--patches.suse/0008-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_fr.patch257
-rw-r--r--patches.suse/0009-btrfs-qgroup-Don-t-scan-leaf-if-we-re-modifying-relo.patch68
-rw-r--r--patches.suse/revert-btrfs-qgroup-move-half-of-the-qgroup-accounting-time-out-of-commit-trans.patch24
-rw-r--r--series.conf7
9 files changed, 1208 insertions, 12 deletions
diff --git a/patches.suse/0001-btrfs-extent-tree-Fix-a-bug-that-btrfs-is-unable-to-.patch b/patches.suse/0001-btrfs-extent-tree-Fix-a-bug-that-btrfs-is-unable-to-.patch
new file mode 100644
index 0000000000..6eac1cfa99
--- /dev/null
+++ b/patches.suse/0001-btrfs-extent-tree-Fix-a-bug-that-btrfs-is-unable-to-.patch
@@ -0,0 +1,87 @@
+From 965fe8a6e29ede784cb38b97bb894aac1e8337a6 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 10 May 2019 12:45:05 +0800
+Patch-mainline: Submitted, 10 May 2019
+References: bsc#1063638 bsc#1128052 bsc#1108838
+Subject: [PATCH] btrfs: extent-tree: Fix a bug that btrfs is unable to add
+ pinned bytes
+
+Commit ddf30cf03fb5 ("btrfs: extent-tree: Use btrfs_ref to refactor
+add_pinned_bytes()") refactored add_pinned_bytes(), but during that
+refactor, there are two callers which add the pinned bytes instead
+of subtracting.
+
+That refactor misses those two caller, causing incorrect pinned bytes
+calculation and resulting unexpected ENOSPC error.
+
+Fix it by refactoring add_pinned_bytes() to add_pinned_bytes() and
+sub_pinned_bytes() to explicitly show what we're doing.
+
+Reported-by: kernel test robot <rong.a.chen@intel.com>
+Fixes: ddf30cf03fb5 ("btrfs: extent-tree: Use btrfs_ref to refactor add_pinned_bytes()")
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/extent-tree.c | 36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -767,25 +767,37 @@ static struct btrfs_space_info *__find_s
+ return NULL;
+ }
+
++static u64 generic_ref_to_space_flags(struct btrfs_ref *ref)
++{
++ if (ref->type == BTRFS_REF_METADATA) {
++ if (ref->tree_ref.root == BTRFS_CHUNK_TREE_OBJECTID)
++ return BTRFS_BLOCK_GROUP_SYSTEM;
++ else
++ return BTRFS_BLOCK_GROUP_METADATA;
++ }
++ return BTRFS_BLOCK_GROUP_DATA;
++}
++
+ static void add_pinned_bytes(struct btrfs_fs_info *fs_info,
+ struct btrfs_ref *ref)
+ {
+ struct btrfs_space_info *space_info;
+- s64 num_bytes = -ref->len;
+- u64 flags;
++ u64 flags = generic_ref_to_space_flags(ref);
+
+- if (ref->type == BTRFS_REF_METADATA) {
+- if (ref->tree_ref.root == BTRFS_CHUNK_TREE_OBJECTID)
+- flags = BTRFS_BLOCK_GROUP_SYSTEM;
+- else
+- flags = BTRFS_BLOCK_GROUP_METADATA;
+- } else {
+- flags = BTRFS_BLOCK_GROUP_DATA;
+- }
++ space_info = __find_space_info(fs_info, flags);
++ ASSERT(space_info);
++ percpu_counter_add(&space_info->total_bytes_pinned, ref->len);
++}
++
++static void sub_pinned_bytes(struct btrfs_fs_info *fs_info,
++ struct btrfs_ref *ref)
++{
++ struct btrfs_space_info *space_info;
++ u64 flags = generic_ref_to_space_flags(ref);
+
+ space_info = __find_space_info(fs_info, flags);
+ ASSERT(space_info);
+- percpu_counter_add(&space_info->total_bytes_pinned, num_bytes);
++ percpu_counter_add(&space_info->total_bytes_pinned, -ref->len);
+ }
+
+ /*
+@@ -2129,7 +2141,7 @@ int btrfs_inc_extent_ref(struct btrfs_tr
+ &old_ref_mod, &new_ref_mod);
+
+ if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0)
+- add_pinned_bytes(fs_info, generic_ref);
++ sub_pinned_bytes(fs_info, generic_ref);
+
+ return ret;
+ }
diff --git a/patches.suse/0003-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch b/patches.suse/0003-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch
new file mode 100644
index 0000000000..7b7a9005e9
--- /dev/null
+++ b/patches.suse/0003-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch
@@ -0,0 +1,213 @@
+From ed4f255b9bacb774c99ded17647f138c3f61546d Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 4 Apr 2019 14:45:31 +0800
+Git-commit: ed4f255b9bacb774c99ded17647f138c3f61546d
+References: bsc#1063638 bsc#1128052 bsc#1108838
+Patch-mainline: v5.2-rc1
+Subject: [PATCH 3/9] btrfs: delayed-ref: Use btrfs_ref to refactor
+ btrfs_add_delayed_tree_ref()
+
+btrfs_add_delayed_tree_ref() has a longer and longer parameter list, and
+some callers like btrfs_inc_extent_ref() are using @owner as level for
+delayed tree ref.
+
+Instead of making the parameter list longer, use btrfs_ref to refactor
+it, so each parameter assignment should be self-explaining without dirty
+level/owner trick, and provides the basis for later refactoring.
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/delayed-ref.c | 24 +++++++++++++++++-------
+ fs/btrfs/delayed-ref.h | 3 +--
+ fs/btrfs/extent-tree.c | 48 ++++++++++++++++++++++++++++--------------------
+ 3 files changed, 46 insertions(+), 29 deletions(-)
+
+--- a/fs/btrfs/delayed-ref.c
++++ b/fs/btrfs/delayed-ref.c
+@@ -723,8 +723,7 @@ static void init_delayed_ref_common(stru
+ */
+ 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_ref *generic_ref,
+ struct btrfs_delayed_extent_op *extent_op,
+ int *old_ref_mod, int *new_ref_mod)
+ {
+@@ -733,10 +732,18 @@ int btrfs_add_delayed_tree_ref(struct bt
+ struct btrfs_delayed_ref_root *delayed_refs;
+ struct btrfs_qgroup_extent_record *record = NULL;
+ int qrecord_inserted;
+- bool is_system = (ref_root == BTRFS_CHUNK_TREE_OBJECTID);
++ bool is_system;
++ int action = generic_ref->action;
++ int level = generic_ref->tree_ref.level;
+ int ret;
++ u64 bytenr = generic_ref->bytenr;
++ u64 num_bytes = generic_ref->len;
++ u64 parent = generic_ref->parent;
+ u8 ref_type;
+
++ is_system = (generic_ref->real_root == BTRFS_CHUNK_TREE_OBJECTID);
++
++ ASSERT(generic_ref->type == BTRFS_REF_METADATA && generic_ref->action);
+ BUG_ON(extent_op && extent_op->is_data);
+ ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
+ if (!ref)
+@@ -747,8 +754,8 @@ int btrfs_add_delayed_tree_ref(struct bt
+ else
+ ref_type = BTRFS_TREE_BLOCK_REF_KEY;
+ init_delayed_ref_common(fs_info, &ref->node, bytenr, num_bytes,
+- ref_root, action, ref_type);
+- ref->root = ref_root;
++ generic_ref->tree_ref.root, action, ref_type);
++ ref->root = generic_ref->tree_ref.root;
+ ref->parent = parent;
+ ref->level = level;
+
+@@ -757,14 +764,17 @@ int btrfs_add_delayed_tree_ref(struct bt
+ goto free_ref;
+
+ if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
+- is_fstree(ref_root)) {
++ is_fstree(generic_ref->real_root) &&
++ is_fstree(generic_ref->tree_ref.root) &&
++ !generic_ref->skip_qgroup) {
+ record = kzalloc(sizeof(*record), GFP_NOFS);
+ if (!record)
+ goto free_head_ref;
+ }
+
+ init_delayed_ref_head(head_ref, record, bytenr, num_bytes,
+- ref_root, 0, action, false, is_system);
++ generic_ref->tree_ref.root, 0, action, false,
++ is_system);
+ head_ref->extent_op = extent_op;
+
+ delayed_refs = &trans->transaction->delayed_refs;
+--- a/fs/btrfs/delayed-ref.h
++++ b/fs/btrfs/delayed-ref.h
+@@ -346,8 +346,7 @@ static inline void btrfs_put_delayed_ref
+
+ 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_ref *generic_ref,
+ struct btrfs_delayed_extent_op *extent_op,
+ int *old_ref_mod, int *new_ref_mod);
+ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -2113,18 +2113,20 @@ int btrfs_inc_extent_ref(struct btrfs_tr
+ u64 bytenr, u64 num_bytes, u64 parent,
+ u64 root_objectid, u64 owner, u64 offset)
+ {
++ struct btrfs_ref generic_ref = { 0 };
+ int old_ref_mod, new_ref_mod;
+ int ret;
+
+ BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID &&
+ root_objectid == BTRFS_TREE_LOG_OBJECTID);
+
++ btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_REF, bytenr,
++ num_bytes, parent);
++ generic_ref.real_root = root_objectid;
+ if (owner < BTRFS_FIRST_FREE_OBJECTID) {
+- ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
+- num_bytes, parent,
+- root_objectid, (int)owner,
+- BTRFS_ADD_DELAYED_REF, NULL,
+- &old_ref_mod, &new_ref_mod);
++ btrfs_init_tree_ref(&generic_ref, (int)owner, root_objectid);
++ ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref,
++ NULL, &old_ref_mod, &new_ref_mod);
+ } else {
+ ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
+ num_bytes, parent,
+@@ -7121,18 +7123,20 @@ void btrfs_free_tree_block(struct btrfs_
+ u64 parent, int last_ref)
+ {
+ struct btrfs_fs_info *fs_info = root->fs_info;
++ struct btrfs_ref generic_ref = { 0 };
+ int pin = 1;
+ int ret;
+
++ btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF,
++ buf->start, buf->len, parent);
++ btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf),
++ root->root_key.objectid);
++
+ if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
+ int old_ref_mod, new_ref_mod;
+
+- ret = btrfs_add_delayed_tree_ref(fs_info, trans, buf->start,
+- buf->len, parent,
+- root->root_key.objectid,
+- btrfs_header_level(buf),
+- BTRFS_DROP_DELAYED_REF, NULL,
+- &old_ref_mod, &new_ref_mod);
++ ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref, NULL,
++ &old_ref_mod, &new_ref_mod);
+ BUG_ON(ret); /* -ENOMEM */
+ pin = old_ref_mod >= 0 && new_ref_mod < 0;
+ }
+@@ -7183,6 +7187,7 @@ int btrfs_free_extent(struct btrfs_trans
+ u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
+ u64 owner, u64 offset)
+ {
++ struct btrfs_ref generic_ref = { 0 };
+ int old_ref_mod, new_ref_mod;
+ int ret;
+
+@@ -7190,6 +7195,9 @@ int btrfs_free_extent(struct btrfs_trans
+ return 0;
+
+
++ btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF, bytenr,
++ num_bytes, parent);
++ generic_ref.real_root = root_objectid;
+ /*
+ * tree log blocks never actually go into the extent allocation
+ * tree, just update pinning info and exit early.
+@@ -7201,11 +7209,9 @@ int btrfs_free_extent(struct btrfs_trans
+ old_ref_mod = new_ref_mod = 0;
+ ret = 0;
+ } else if (owner < BTRFS_FIRST_FREE_OBJECTID) {
+- ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
+- num_bytes, parent,
+- root_objectid, (int)owner,
+- BTRFS_DROP_DELAYED_REF, NULL,
+- &old_ref_mod, &new_ref_mod);
++ btrfs_init_tree_ref(&generic_ref, (int)owner, root_objectid);
++ ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref,
++ NULL, &old_ref_mod, &new_ref_mod);
+ } else {
+ ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
+ num_bytes, parent,
+@@ -8335,6 +8341,7 @@ struct extent_buffer *btrfs_alloc_tree_b
+ struct btrfs_block_rsv *block_rsv;
+ struct extent_buffer *buf;
+ struct btrfs_delayed_extent_op *extent_op;
++ struct btrfs_ref generic_ref = { 0 };
+ u64 flags = 0;
+ int ret;
+ u32 blocksize = fs_info->nodesize;
+@@ -8388,10 +8395,11 @@ struct extent_buffer *btrfs_alloc_tree_b
+ extent_op->is_data = false;
+ extent_op->level = level;
+
+- ret = btrfs_add_delayed_tree_ref(fs_info, trans, ins.objectid,
+- ins.offset, parent,
+- root_objectid, level,
+- BTRFS_ADD_DELAYED_EXTENT,
++ btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_EXTENT,
++ ins.objectid, ins.offset, parent);
++ generic_ref.real_root = root->root_key.objectid;
++ btrfs_init_tree_ref(&generic_ref, level, root_objectid);
++ ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref,
+ extent_op, NULL, NULL);
+ if (ret)
+ goto out_free_delayed;
diff --git a/patches.suse/0004-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch b/patches.suse/0004-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch
new file mode 100644
index 0000000000..cefdb23914
--- /dev/null
+++ b/patches.suse/0004-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch
@@ -0,0 +1,124 @@
+From 76675593b69f2fcd57e24d9dd2a9b278f0130d0b Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 4 Apr 2019 14:45:32 +0800
+Git-commit: 76675593b69f2fcd57e24d9dd2a9b278f0130d0b
+References: bsc#1063638 bsc#1128052 bsc#1108838
+Patch-mainline: v5.2-rc1
+Subject: [PATCH 4/9] btrfs: delayed-ref: Use btrfs_ref to refactor
+ btrfs_add_delayed_data_ref()
+
+Just like btrfs_add_delayed_tree_ref(), use btrfs_ref to refactor
+btrfs_add_delayed_data_ref().
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/delayed-ref.c | 16 ++++++++++++----
+ fs/btrfs/delayed-ref.h | 4 +---
+ fs/btrfs/extent-tree.c | 22 ++++++++++------------
+ 3 files changed, 23 insertions(+), 19 deletions(-)
+
+--- a/fs/btrfs/delayed-ref.c
++++ b/fs/btrfs/delayed-ref.c
+@@ -815,9 +815,7 @@ free_ref:
+ */
+ 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, u64 reserved, int action,
++ struct btrfs_ref *generic_ref, u64 reserved,
+ int *old_ref_mod, int *new_ref_mod)
+ {
+ struct btrfs_delayed_data_ref *ref;
+@@ -825,9 +823,17 @@ int btrfs_add_delayed_data_ref(struct bt
+ struct btrfs_delayed_ref_root *delayed_refs;
+ struct btrfs_qgroup_extent_record *record = NULL;
+ int qrecord_inserted;
++ int action = generic_ref->action;
+ int ret;
++ u64 bytenr = generic_ref->bytenr;
++ u64 num_bytes = generic_ref->len;
++ u64 parent = generic_ref->parent;
++ u64 ref_root = generic_ref->data_ref.ref_root;
++ u64 owner = generic_ref->data_ref.ino;
++ u64 offset = generic_ref->data_ref.offset;
+ u8 ref_type;
+
++ ASSERT(generic_ref->type == BTRFS_REF_DATA && action);
+ ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
+ if (!ref)
+ return -ENOMEM;
+@@ -851,7 +857,9 @@ int btrfs_add_delayed_data_ref(struct bt
+ }
+
+ if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
+- is_fstree(ref_root)) {
++ is_fstree(ref_root) &&
++ is_fstree(generic_ref->real_root) &&
++ !generic_ref->skip_qgroup) {
+ record = kzalloc(sizeof(*record), GFP_NOFS);
+ if (!record) {
+ kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
+--- a/fs/btrfs/delayed-ref.h
++++ b/fs/btrfs/delayed-ref.h
+@@ -351,9 +351,7 @@ int btrfs_add_delayed_tree_ref(struct bt
+ int *old_ref_mod, int *new_ref_mod);
+ 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, u64 reserved, int action,
++ struct btrfs_ref *generic_ref, u64 reserved,
+ int *old_ref_mod, int *new_ref_mod);
+ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
+ struct btrfs_trans_handle *trans,
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -2128,10 +2128,8 @@ int btrfs_inc_extent_ref(struct btrfs_tr
+ ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref,
+ NULL, &old_ref_mod, &new_ref_mod);
+ } else {
+- ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
+- num_bytes, parent,
+- root_objectid, owner, offset,
+- 0, BTRFS_ADD_DELAYED_REF,
++ btrfs_init_data_ref(&generic_ref, root_objectid, owner, offset);
++ ret = btrfs_add_delayed_data_ref(fs_info, trans, &generic_ref, 0,
+ &old_ref_mod, &new_ref_mod);
+ }
+
+@@ -7213,10 +7211,8 @@ int btrfs_free_extent(struct btrfs_trans
+ ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref,
+ NULL, &old_ref_mod, &new_ref_mod);
+ } else {
+- ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
+- num_bytes, parent,
+- root_objectid, owner, offset,
+- 0, BTRFS_DROP_DELAYED_REF,
++ btrfs_init_data_ref(&generic_ref, root_objectid, owner, offset);
++ ret = btrfs_add_delayed_data_ref(fs_info, trans, &generic_ref, 0,
+ &old_ref_mod, &new_ref_mod);
+ }
+
+@@ -8167,14 +8163,16 @@ int btrfs_alloc_reserved_file_extent(str
+ struct btrfs_key *ins)
+ {
+ struct btrfs_fs_info *fs_info = trans->fs_info;
++ struct btrfs_ref generic_ref = { 0 };
+ int ret;
+
+ BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID);
+
+- ret = btrfs_add_delayed_data_ref(fs_info, trans, ins->objectid,
+- ins->offset, 0, root_objectid, owner,
+- offset, ram_bytes,
+- BTRFS_ADD_DELAYED_EXTENT, NULL, NULL);
++ btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_EXTENT,
++ ins->objectid, ins->offset, 0);
++ btrfs_init_data_ref(&generic_ref, root_objectid, owner, offset);
++ ret = btrfs_add_delayed_data_ref(fs_info, trans, &generic_ref,
++ ram_bytes, NULL, NULL);
+ return ret;
+ }
+
diff --git a/patches.suse/0006-btrfs-extent-tree-Use-btrfs_ref-to-refactor-add_pinn.patch b/patches.suse/0006-btrfs-extent-tree-Use-btrfs_ref-to-refactor-add_pinn.patch
new file mode 100644
index 0000000000..7eaad9adcd
--- /dev/null
+++ b/patches.suse/0006-btrfs-extent-tree-Use-btrfs_ref-to-refactor-add_pinn.patch
@@ -0,0 +1,70 @@
+From ddf30cf03fb53b9a0ad0f355a69dbedf416edde9 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 4 Apr 2019 14:45:34 +0800
+Git-commit: ddf30cf03fb53b9a0ad0f355a69dbedf416edde9
+References: bsc#1063638 bsc#1128052 bsc#1108838
+Patch-mainline: v5.2-rc1
+Subject: [PATCH 6/9] btrfs: extent-tree: Use btrfs_ref to refactor
+ add_pinned_bytes()
+
+Since add_pinned_bytes() only needs to know if the extent is metadata
+and if it's a chunk tree extent, btrfs_ref is a perfect match for it, as
+we don't need various owner/level trick to determine extent type.
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/extent-tree.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -767,14 +767,15 @@ static struct btrfs_space_info *__find_s
+ return NULL;
+ }
+
+-static void add_pinned_bytes(struct btrfs_fs_info *fs_info, s64 num_bytes,
+- u64 owner, u64 root_objectid)
++static void add_pinned_bytes(struct btrfs_fs_info *fs_info,
++ struct btrfs_ref *ref)
+ {
+ struct btrfs_space_info *space_info;
++ s64 num_bytes = -ref->len;
+ u64 flags;
+
+- if (owner < BTRFS_FIRST_FREE_OBJECTID) {
+- if (root_objectid == BTRFS_CHUNK_TREE_OBJECTID)
++ if (ref->type == BTRFS_REF_METADATA) {
++ if (ref->tree_ref.root == BTRFS_CHUNK_TREE_OBJECTID)
+ flags = BTRFS_BLOCK_GROUP_SYSTEM;
+ else
+ flags = BTRFS_BLOCK_GROUP_METADATA;
+@@ -2134,7 +2135,7 @@ int btrfs_inc_extent_ref(struct btrfs_tr
+ }
+
+ if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0)
+- add_pinned_bytes(fs_info, -num_bytes, owner, root_objectid);
++ add_pinned_bytes(fs_info, &generic_ref);
+
+ return ret;
+ }
+@@ -7167,8 +7168,7 @@ void btrfs_free_tree_block(struct btrfs_
+ }
+ out:
+ if (pin)
+- add_pinned_bytes(fs_info, buf->len, btrfs_header_level(buf),
+- root->root_key.objectid);
++ add_pinned_bytes(fs_info, &generic_ref);
+
+ if (last_ref) {
+ /*
+@@ -7217,7 +7217,7 @@ int btrfs_free_extent(struct btrfs_trans
+ }
+
+ if (ret == 0 && old_ref_mod >= 0 && new_ref_mod < 0)
+- add_pinned_bytes(fs_info, num_bytes, owner, root_objectid);
++ add_pinned_bytes(fs_info, &generic_ref);
+
+ return ret;
+ }
diff --git a/patches.suse/0007-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_in.patch b/patches.suse/0007-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_in.patch
new file mode 100644
index 0000000000..4920713e43
--- /dev/null
+++ b/patches.suse/0007-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_in.patch
@@ -0,0 +1,370 @@
+From 82fa113fccc41fe5204b4ce35341d69ebde0020f Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 4 Apr 2019 14:45:35 +0800
+Git-commit: 82fa113fccc41fe5204b4ce35341d69ebde0020f
+References: bsc#1063638 bsc#1128052 bsc#1108838
+Patch-mainline: v5.2-rc1
+Subject: [PATCH 7/9] btrfs: extent-tree: Use btrfs_ref to refactor
+ btrfs_inc_extent_ref()
+
+Use the new btrfs_ref structure and replace parameter list to clean up
+the usage of owner and level to distinguish the extent types.
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/ctree.h | 4 +--
+ fs/btrfs/extent-tree.c | 54 +++++++++++++++++++++++++++++--------------------
+ fs/btrfs/file.c | 18 +++++++++++-----
+ fs/btrfs/inode.c | 10 +++++----
+ fs/btrfs/ioctl.c | 15 +++++++++----
+ fs/btrfs/relocation.c | 41 ++++++++++++++++++++++++-------------
+ fs/btrfs/tree-log.c | 12 ++++++++--
+ 7 files changed, 99 insertions(+), 55 deletions(-)
+
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -53,6 +53,7 @@ extern struct kmem_cache *btrfs_bit_radi
+ extern struct kmem_cache *btrfs_path_cachep;
+ extern struct kmem_cache *btrfs_free_space_cachep;
+ struct btrfs_ordered_sum;
++struct btrfs_ref;
+
+ #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
+ #define STATIC noinline
+@@ -2731,8 +2732,7 @@ int btrfs_finish_extent_commit(struct bt
+ struct btrfs_fs_info *fs_info);
+ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info,
+- u64 bytenr, u64 num_bytes, u64 parent,
+- u64 root_objectid, u64 owner, u64 offset);
++ struct btrfs_ref *generic_ref);
+
+ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info);
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -2111,31 +2111,25 @@ int btrfs_discard_extent(struct btrfs_fs
+ /* Can return -ENOMEM */
+ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info,
+- u64 bytenr, u64 num_bytes, u64 parent,
+- u64 root_objectid, u64 owner, u64 offset)
++ struct btrfs_ref *generic_ref)
+ {
+- struct btrfs_ref generic_ref = { 0 };
+ int old_ref_mod, new_ref_mod;
+ int ret;
+
+- BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID &&
+- root_objectid == BTRFS_TREE_LOG_OBJECTID);
++ ASSERT(generic_ref->type != BTRFS_REF_NOT_SET &&
++ generic_ref->action);
++ BUG_ON(generic_ref->type == BTRFS_REF_METADATA &&
++ generic_ref->tree_ref.root == BTRFS_TREE_LOG_OBJECTID);
+
+- btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_REF, bytenr,
+- num_bytes, parent);
+- generic_ref.real_root = root_objectid;
+- if (owner < BTRFS_FIRST_FREE_OBJECTID) {
+- btrfs_init_tree_ref(&generic_ref, (int)owner, root_objectid);
+- ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref,
++ if (generic_ref->type == BTRFS_REF_METADATA)
++ ret = btrfs_add_delayed_tree_ref(fs_info, trans, generic_ref,
+ NULL, &old_ref_mod, &new_ref_mod);
+- } else {
+- btrfs_init_data_ref(&generic_ref, root_objectid, owner, offset);
+- ret = btrfs_add_delayed_data_ref(fs_info, trans, &generic_ref, 0,
++ else
++ ret = btrfs_add_delayed_data_ref(fs_info, trans, generic_ref, 0,
+ &old_ref_mod, &new_ref_mod);
+- }
+
+ if (ret == 0 && old_ref_mod < 0 && new_ref_mod >= 0)
+- add_pinned_bytes(fs_info, &generic_ref);
++ add_pinned_bytes(fs_info, generic_ref);
+
+ return ret;
+ }
+@@ -3254,7 +3248,10 @@ static int __btrfs_mod_ref(struct btrfs_
+ u32 nritems;
+ struct btrfs_key key;
+ struct btrfs_file_extent_item *fi;
++ struct btrfs_ref generic_ref = { 0 };
++ bool for_reloc = btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC);
+ int i;
++ int action;
+ int level;
+ int ret = 0;
+
+@@ -3272,6 +3269,10 @@ static int __btrfs_mod_ref(struct btrfs_
+ parent = buf->start;
+ else
+ parent = 0;
++ if (inc)
++ action = BTRFS_ADD_DELAYED_REF;
++ else
++ action = BTRFS_DROP_DELAYED_REF;
+
+ for (i = 0; i < nritems; i++) {
+ if (level == 0) {
+@@ -3289,10 +3290,15 @@ static int __btrfs_mod_ref(struct btrfs_
+
+ num_bytes = btrfs_file_extent_disk_num_bytes(buf, fi);
+ key.offset -= btrfs_file_extent_offset(buf, fi);
++ btrfs_init_generic_ref(&generic_ref, action, bytenr,
++ num_bytes, parent);
++ btrfs_init_data_ref(&generic_ref, ref_root, key.objectid,
++ key.offset);
++ generic_ref.real_root = root->root_key.objectid;
++ generic_ref.skip_qgroup = for_reloc;
+ if (inc)
+- ret = btrfs_inc_extent_ref(trans, fs_info, bytenr,
+- num_bytes, parent, ref_root,
+- key.objectid, key.offset);
++ ret = btrfs_inc_extent_ref(trans, fs_info,
++ &generic_ref);
+ else
+ ret = btrfs_free_extent(trans, fs_info, bytenr,
+ num_bytes, parent, ref_root,
+@@ -3302,10 +3308,14 @@ static int __btrfs_mod_ref(struct btrfs_
+ } else {
+ bytenr = btrfs_node_blockptr(buf, i);
+ num_bytes = fs_info->nodesize;
++ btrfs_init_generic_ref(&generic_ref, action, bytenr,
++ num_bytes, parent);
++ generic_ref.real_root = root->root_key.objectid;
++ btrfs_init_tree_ref(&generic_ref, level - 1, ref_root);
++ generic_ref.skip_qgroup = for_reloc;
+ if (inc)
+- ret = btrfs_inc_extent_ref(trans, fs_info, bytenr,
+- num_bytes, parent, ref_root,
+- level - 1, 0);
++ ret = btrfs_inc_extent_ref(trans, fs_info,
++ &generic_ref);
+ else
+ ret = btrfs_free_extent(trans, fs_info, bytenr,
+ num_bytes, parent, ref_root,
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -762,6 +762,7 @@ int __btrfs_drop_extents(struct btrfs_tr
+ struct btrfs_fs_info *fs_info = root->fs_info;
+ struct extent_buffer *leaf;
+ struct btrfs_file_extent_item *fi;
++ struct btrfs_ref ref = { 0 };
+ struct btrfs_key key;
+ struct btrfs_key new_key;
+ u64 ino = btrfs_ino(BTRFS_I(inode));
+@@ -918,11 +919,15 @@ next_slot:
+ btrfs_mark_buffer_dirty(leaf);
+
+ if (update_refs && disk_bytenr > 0) {
+- ret = btrfs_inc_extent_ref(trans, fs_info,
+- disk_bytenr, num_bytes, 0,
++ btrfs_init_generic_ref(&ref,
++ BTRFS_ADD_DELAYED_REF,
++ disk_bytenr, num_bytes, 0);
++ btrfs_init_data_ref(&ref,
+ root->root_key.objectid,
+ new_key.objectid,
+ start - extent_offset);
++ ret = btrfs_inc_extent_ref(trans, fs_info,
++ &ref);
+ BUG_ON(ret); /* -ENOMEM */
+ }
+ key.offset = start;
+@@ -1151,6 +1156,7 @@ int btrfs_mark_extent_written(struct btr
+ struct extent_buffer *leaf;
+ struct btrfs_path *path;
+ struct btrfs_file_extent_item *fi;
++ struct btrfs_ref ref = { 0 };
+ struct btrfs_key key;
+ struct btrfs_key new_key;
+ u64 bytenr;
+@@ -1296,9 +1302,11 @@ again:
+ extent_end - split);
+ btrfs_mark_buffer_dirty(leaf);
+
+- ret = btrfs_inc_extent_ref(trans, fs_info, bytenr, num_bytes,
+- 0, root->root_key.objectid,
+- ino, orig_offset);
++ btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, bytenr,
++ num_bytes, 0);
++ btrfs_init_data_ref(&ref, root->root_key.objectid, ino,
++ orig_offset);
++ ret = btrfs_inc_extent_ref(trans, fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto out;
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -2519,6 +2519,7 @@ static noinline int relink_extent_backre
+ struct btrfs_file_extent_item *item;
+ struct btrfs_ordered_extent *ordered;
+ struct btrfs_trans_handle *trans;
++ struct btrfs_ref ref = { 0 };
+ struct btrfs_root *root;
+ struct btrfs_key key;
+ struct extent_buffer *leaf;
+@@ -2689,10 +2690,11 @@ again:
+ inode_add_bytes(inode, len);
+ btrfs_release_path(path);
+
+- ret = btrfs_inc_extent_ref(trans, fs_info, new->bytenr,
+- new->disk_len, 0,
+- backref->root_id, backref->inum,
+- new->file_pos); /* start - extent_offset */
++ btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new->bytenr,
++ new->disk_len, 0);
++ btrfs_init_data_ref(&ref, backref->root_id, backref->inum,
++ new->file_pos); /* start - extent_offset */
++ ret = btrfs_inc_extent_ref(trans, fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto out_free_path;
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3774,13 +3774,18 @@ process_slot:
+ datal);
+
+ if (disko) {
++ struct btrfs_ref ref = { 0 };
++
+ inode_add_bytes(inode, datal);
++ btrfs_init_generic_ref(&ref,
++ BTRFS_ADD_DELAYED_REF, disko,
++ diskl, 0);
++ btrfs_init_data_ref(&ref,
++ root->root_key.objectid,
++ btrfs_ino(BTRFS_I(inode)),
++ new_key.offset - datao);
+ ret = btrfs_inc_extent_ref(trans,
+- fs_info,
+- disko, diskl, 0,
+- root->root_key.objectid,
+- btrfs_ino(BTRFS_I(inode)),
+- new_key.offset - datao);
++ fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans,
+ ret);
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1679,6 +1679,8 @@ int replace_file_extents(struct btrfs_tr
+
+ nritems = btrfs_header_nritems(leaf);
+ for (i = 0; i < nritems; i++) {
++ struct btrfs_ref ref = { 0 };
++
+ cond_resched();
+ btrfs_item_key_to_cpu(leaf, &key, i);
+ if (key.type != BTRFS_EXTENT_DATA_KEY)
+@@ -1739,10 +1741,12 @@ int replace_file_extents(struct btrfs_tr
+ dirty = 1;
+
+ key.offset -= btrfs_file_extent_offset(leaf, fi);
+- ret = btrfs_inc_extent_ref(trans, fs_info, new_bytenr,
+- num_bytes, parent,
+- btrfs_header_owner(leaf),
+- key.objectid, key.offset);
++ btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
++ num_bytes, parent);
++ ref.real_root = root->root_key.objectid;
++ btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
++ key.objectid, key.offset);
++ ret = btrfs_inc_extent_ref(trans, fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ break;
+@@ -1792,6 +1796,7 @@ int replace_path(struct btrfs_trans_hand
+ struct btrfs_fs_info *fs_info = dest->fs_info;
+ struct extent_buffer *eb;
+ struct extent_buffer *parent;
++ struct btrfs_ref ref = { 0 };
+ struct btrfs_key key;
+ u64 old_bytenr;
+ u64 new_bytenr;
+@@ -1950,13 +1955,17 @@ again:
+ path->slots[level], old_ptr_gen);
+ btrfs_mark_buffer_dirty(path->nodes[level]);
+
+- ret = btrfs_inc_extent_ref(trans, fs_info, old_bytenr,
+- blocksize, path->nodes[level]->start,
+- src->root_key.objectid, level - 1, 0);
++ btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, old_bytenr,
++ blocksize, path->nodes[level]->start);
++ ref.skip_qgroup = true;
++ btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid);
++ ret = btrfs_inc_extent_ref(trans, fs_info, &ref);
+ BUG_ON(ret);
+- ret = btrfs_inc_extent_ref(trans, fs_info, new_bytenr,
+- blocksize, 0, dest->root_key.objectid,
+- level - 1, 0);
++ btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF, new_bytenr,
++ blocksize, 0);
++ ref.skip_qgroup = true;
++ btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid);
++ ret = btrfs_inc_extent_ref(trans, fs_info, &ref);
+ BUG_ON(ret);
+
+ ret = btrfs_free_extent(trans, fs_info, new_bytenr, blocksize,
+@@ -2756,6 +2765,7 @@ static int do_relocation(struct btrfs_tr
+ rc->backref_cache.path[node->level] = node;
+ list_for_each_entry(edge, &node->upper, list[LOWER]) {
+ struct btrfs_key first_key;
++ struct btrfs_ref ref = { 0 };
+
+ cond_resched();
+
+@@ -2853,11 +2863,14 @@ static int do_relocation(struct btrfs_tr
+ trans->transid);
+ btrfs_mark_buffer_dirty(upper->eb);
+
++ btrfs_init_generic_ref(&ref, BTRFS_ADD_DELAYED_REF,
++ node->eb->start, blocksize,
++ upper->eb->start);
++ ref.real_root = root->root_key.objectid;
++ btrfs_init_tree_ref(&ref, node->level,
++ btrfs_header_owner(upper->eb));
+ ret = btrfs_inc_extent_ref(trans, root->fs_info,
+- node->eb->start, blocksize,
+- upper->eb->start,
+- btrfs_header_owner(upper->eb),
+- node->level, 0);
++ &ref);
+ BUG_ON(ret);
+
+ ret = btrfs_drop_subtree(trans, root, eb, upper->eb);
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -717,9 +717,11 @@ static noinline int replay_one_extent(st
+ goto out;
+
+ if (ins.objectid > 0) {
++ struct btrfs_ref ref = { 0 };
+ u64 csum_start;
+ u64 csum_end;
+ LIST_HEAD(ordered_sums);
++
+ /*
+ * is this extent already allocated in the extent
+ * allocation tree? If so, just add a reference
+@@ -727,10 +729,14 @@ static noinline int replay_one_extent(st
+ ret = btrfs_lookup_data_extent(fs_info, ins.objectid,
+ ins.offset);
+ if (ret == 0) {
+- ret = btrfs_inc_extent_ref(trans, fs_info,
+- ins.objectid, ins.offset,
+- 0, root->root_key.objectid,
++ btrfs_init_generic_ref(&ref,
++ BTRFS_ADD_DELAYED_REF,
++ ins.objectid, ins.offset, 0);
++ btrfs_init_data_ref(&ref,
++ root->root_key.objectid,
+ key->objectid, offset);
++ ret = btrfs_inc_extent_ref(trans, fs_info,
++ &ref);
+ if (ret)
+ goto out;
+ } else {
diff --git a/patches.suse/0008-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_fr.patch b/patches.suse/0008-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_fr.patch
new file mode 100644
index 0000000000..26e00ced78
--- /dev/null
+++ b/patches.suse/0008-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_fr.patch
@@ -0,0 +1,257 @@
+From ffd4bb2a19cd29681f5b70a200654ab92619de8a Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 4 Apr 2019 14:45:36 +0800
+Git-commit: ffd4bb2a19cd29681f5b70a200654ab92619de8a
+References: bsc#1063638 bsc#1128052 bsc#1108838
+Patch-mainline: v5.2-rc1
+Subject: [PATCH 8/9] btrfs: extent-tree: Use btrfs_ref to refactor
+ btrfs_free_extent()
+
+Similar to btrfs_inc_extent_ref(), use btrfs_ref to replace the long
+parameter list and the confusing @owner parameter.
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/ctree.h | 3 +--
+ fs/btrfs/extent-tree.c | 44 +++++++++++++++++++-------------------------
+ fs/btrfs/file.c | 23 +++++++++++++----------
+ fs/btrfs/inode.c | 13 +++++++++----
+ fs/btrfs/relocation.c | 25 ++++++++++++++++---------
+ 5 files changed, 58 insertions(+), 50 deletions(-)
+
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -2720,8 +2720,7 @@ int btrfs_set_disk_extent_flags(struct b
+ int level, int is_data);
+ int btrfs_free_extent(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info,
+- u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
+- u64 owner, u64 offset);
++ struct btrfs_ref *ref);
+
+ int btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info,
+ u64 start, u64 len, int delalloc);
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -3298,9 +3298,8 @@ static int __btrfs_mod_ref(struct btrfs_
+ ret = btrfs_inc_extent_ref(trans, fs_info,
+ &generic_ref);
+ else
+- ret = btrfs_free_extent(trans, fs_info, bytenr,
+- num_bytes, parent, ref_root,
+- key.objectid, key.offset);
++ ret = btrfs_free_extent(trans, fs_info,
++ &generic_ref);
+ if (ret)
+ goto fail;
+ } else {
+@@ -3315,9 +3314,8 @@ static int __btrfs_mod_ref(struct btrfs_
+ ret = btrfs_inc_extent_ref(trans, fs_info,
+ &generic_ref);
+ else
+- ret = btrfs_free_extent(trans, fs_info, bytenr,
+- num_bytes, parent, ref_root,
+- level - 1, 0);
++ ret = btrfs_free_extent(trans, fs_info,
++ &generic_ref);
+ if (ret)
+ goto fail;
+ }
+@@ -7190,42 +7188,36 @@ out:
+ /* Can return -ENOMEM */
+ int btrfs_free_extent(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info,
+- u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
+- u64 owner, u64 offset)
++ struct btrfs_ref *ref)
+ {
+- struct btrfs_ref generic_ref = { 0 };
+ int old_ref_mod, new_ref_mod;
+ int ret;
+
+ if (btrfs_is_testing(fs_info))
+ return 0;
+
+-
+- btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF, bytenr,
+- num_bytes, parent);
+- generic_ref.real_root = root_objectid;
+ /*
+ * tree log blocks never actually go into the extent allocation
+ * tree, just update pinning info and exit early.
+ */
+- if (root_objectid == BTRFS_TREE_LOG_OBJECTID) {
+- WARN_ON(owner >= BTRFS_FIRST_FREE_OBJECTID);
++ if ((ref->type == BTRFS_REF_METADATA &&
++ ref->tree_ref.root == BTRFS_TREE_LOG_OBJECTID) ||
++ (ref->type == BTRFS_REF_DATA &&
++ ref->data_ref.ref_root == BTRFS_TREE_LOG_OBJECTID)) {
+ /* unlocks the pinned mutex */
+- btrfs_pin_extent(fs_info, bytenr, num_bytes, 1);
++ btrfs_pin_extent(fs_info, ref->bytenr, ref->len, 1);
+ old_ref_mod = new_ref_mod = 0;
+ ret = 0;
+- } else if (owner < BTRFS_FIRST_FREE_OBJECTID) {
+- btrfs_init_tree_ref(&generic_ref, (int)owner, root_objectid);
+- ret = btrfs_add_delayed_tree_ref(fs_info, trans, &generic_ref,
++ } else if (ref->type == BTRFS_REF_METADATA) {
++ ret = btrfs_add_delayed_tree_ref(fs_info, trans, ref,
+ NULL, &old_ref_mod, &new_ref_mod);
+ } else {
+- btrfs_init_data_ref(&generic_ref, root_objectid, owner, offset);
+- ret = btrfs_add_delayed_data_ref(fs_info, trans, &generic_ref, 0,
++ ret = btrfs_add_delayed_data_ref(fs_info, trans, ref, 0,
+ &old_ref_mod, &new_ref_mod);
+ }
+
+ if (ret == 0 && old_ref_mod >= 0 && new_ref_mod < 0)
+- add_pinned_bytes(fs_info, &generic_ref);
++ add_pinned_bytes(fs_info, ref);
+
+ return ret;
+ }
+@@ -8652,6 +8644,7 @@ static noinline int do_walk_down(struct
+ u32 blocksize;
+ struct btrfs_key key;
+ struct btrfs_key first_key;
++ struct btrfs_ref ref = { 0 };
+ struct extent_buffer *next;
+ int level = wc->level;
+ int reada = 0;
+@@ -8825,9 +8818,10 @@ skip:
+ wc->drop_level = level;
+ find_next_key(path, level, &wc->drop_progress);
+
+- ret = btrfs_free_extent(trans, fs_info, bytenr, blocksize,
+- parent, root->root_key.objectid,
+- level - 1, 0);
++ btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, bytenr,
++ fs_info->nodesize, parent);
++ btrfs_init_tree_ref(&ref, level - 1, root->root_key.objectid);
++ ret = btrfs_free_extent(trans, fs_info, &ref);
+ if (ret)
+ goto out_unlock;
+ }
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1007,11 +1007,15 @@ delete_extent_item:
+ extent_end = ALIGN(extent_end,
+ fs_info->sectorsize);
+ } else if (update_refs && disk_bytenr > 0) {
+- ret = btrfs_free_extent(trans, fs_info,
+- disk_bytenr, num_bytes, 0,
++ btrfs_init_generic_ref(&ref,
++ BTRFS_DROP_DELAYED_REF,
++ disk_bytenr, num_bytes, 0);
++ btrfs_init_data_ref(&ref,
+ root->root_key.objectid,
+- key.objectid, key.offset -
+- extent_offset);
++ key.objectid,
++ key.offset - extent_offset);
++ ret = btrfs_free_extent(trans, fs_info,
++ &ref);
+ BUG_ON(ret); /* -ENOMEM */
+ inode_sub_bytes(inode,
+ extent_end - key.offset);
+@@ -1328,6 +1332,9 @@ again:
+
+ other_start = end;
+ other_end = 0;
++ btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, bytenr,
++ num_bytes, 0);
++ btrfs_init_data_ref(&ref, root->root_key.objectid, ino, orig_offset);
+ if (extent_mergeable(leaf, path->slots[0] + 1,
+ ino, bytenr, orig_offset,
+ &other_start, &other_end)) {
+@@ -1338,9 +1345,7 @@ again:
+ extent_end = other_end;
+ del_slot = path->slots[0] + 1;
+ del_nr++;
+- ret = btrfs_free_extent(trans, fs_info, bytenr, num_bytes,
+- 0, root->root_key.objectid,
+- ino, orig_offset);
++ ret = btrfs_free_extent(trans, fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto out;
+@@ -1358,9 +1363,7 @@ again:
+ key.offset = other_start;
+ del_slot = path->slots[0];
+ del_nr++;
+- ret = btrfs_free_extent(trans, fs_info, bytenr, num_bytes,
+- 0, root->root_key.objectid,
+- ino, orig_offset);
++ ret = btrfs_free_extent(trans, fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto out;
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4476,12 +4476,17 @@ delete:
+ if (found_extent &&
+ (test_bit(BTRFS_ROOT_REF_COWS, &root->state) ||
+ root == fs_info->tree_root)) {
++ struct btrfs_ref ref = { 0 };
++
+ btrfs_set_path_blocking(path);
+ bytes_deleted += extent_num_bytes;
+- ret = btrfs_free_extent(trans, fs_info, extent_start,
+- extent_num_bytes, 0,
+- btrfs_header_owner(leaf),
+- ino, extent_offset);
++
++ btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF,
++ extent_start, extent_num_bytes, 0);
++ ref.real_root = root->root_key.objectid;
++ btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
++ ino, extent_offset);
++ ret = btrfs_free_extent(trans, fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ break;
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1752,9 +1752,12 @@ int replace_file_extents(struct btrfs_tr
+ break;
+ }
+
+- ret = btrfs_free_extent(trans, fs_info, bytenr, num_bytes,
+- parent, btrfs_header_owner(leaf),
+- key.objectid, key.offset);
++ btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, bytenr,
++ num_bytes, parent);
++ ref.real_root = root->root_key.objectid;
++ btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
++ key.objectid, key.offset);
++ ret = btrfs_free_extent(trans, fs_info, &ref);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ break;
+@@ -1968,14 +1971,18 @@ again:
+ ret = btrfs_inc_extent_ref(trans, fs_info, &ref);
+ BUG_ON(ret);
+
+- ret = btrfs_free_extent(trans, fs_info, new_bytenr, blocksize,
+- path->nodes[level]->start,
+- src->root_key.objectid, level - 1, 0);
++ btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, new_bytenr,
++ blocksize, path->nodes[level]->start);
++ btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid);
++ ref.skip_qgroup = true;
++ ret = btrfs_free_extent(trans, fs_info, &ref);
+ BUG_ON(ret);
+
+- ret = btrfs_free_extent(trans, fs_info, old_bytenr, blocksize,
+- 0, dest->root_key.objectid, level - 1,
+- 0);
++ btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, old_bytenr,
++ blocksize, 0);
++ btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid);
++ ref.skip_qgroup = true;
++ ret = btrfs_free_extent(trans, fs_info, &ref);
+ BUG_ON(ret);
+
+ btrfs_unlock_up_safe(path, 0);
diff --git a/patches.suse/0009-btrfs-qgroup-Don-t-scan-leaf-if-we-re-modifying-relo.patch b/patches.suse/0009-btrfs-qgroup-Don-t-scan-leaf-if-we-re-modifying-relo.patch
new file mode 100644
index 0000000000..5caaa438ea
--- /dev/null
+++ b/patches.suse/0009-btrfs-qgroup-Don-t-scan-leaf-if-we-re-modifying-relo.patch
@@ -0,0 +1,68 @@
+From c4140cbf35b90422be6589024f47e132eb2298b1 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Thu, 4 Apr 2019 14:45:37 +0800
+Git-commit: c4140cbf35b90422be6589024f47e132eb2298b1
+References: bsc#1063638 bsc#1128052 bsc#1108838
+Patch-mainline: v5.2-rc1
+Subject: [PATCH 9/9] btrfs: qgroup: Don't scan leaf if we're modifying reloc
+ tree
+
+Since reloc tree doesn't contribute to qgroup numbers, just skip them.
+
+This should catch the final cause of unnecessary data ref processing
+when running balance of metadata with qgroups on.
+
+The 4G data 16 snapshots test (*) should explain it pretty well:
+
+ | delayed subtree | refactor delayed ref | this patch
+---------------------------------------------------------------------
+relocated | 22653 | 22673 | 22744
+qgroup dirty | 122792 | 48360 | 70
+time | 24.494 | 11.606 | 3.944
+
+Finally, we're at the stage where qgroup + metadata balance cost no
+obvious overhead.
+
+Test environment:
+
+Test VM:
+- vRAM 8G
+- vCPU 8
+- block dev vitrio-blk, 'unsafe' cache mode
+- host block 850evo
+
+Test workload:
+- Copy 4G data from /usr/ to one subvolume
+- Create 16 snapshots of that subvolume, and modify 3 files in each
+ snapshot
+- Enable quota, rescan
+- Time "btrfs balance start -m"
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/extent-tree.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -8911,11 +8911,14 @@ static noinline int walk_up_proc(struct
+ else
+ ret = btrfs_dec_ref(trans, root, eb, 0);
+ BUG_ON(ret); /* -ENOMEM */
+- ret = btrfs_qgroup_trace_leaf_items(trans, fs_info, eb);
+- if (ret) {
+- btrfs_err_rl(fs_info,
+- "error %d accounting leaf items. Quota is out of sync, rescan required.",
+- ret);
++ if (is_fstree(root->root_key.objectid)) {
++ ret = btrfs_qgroup_trace_leaf_items(trans,
++ fs_info, eb);
++ if (ret) {
++ btrfs_err_rl(fs_info,
++"error %d accounting leaf items. Quota is out of sync, rescan required.",
++ ret);
++ }
+ }
+ }
+ /* make block locked assertion in clean_tree_block happy */
diff --git a/patches.suse/revert-btrfs-qgroup-move-half-of-the-qgroup-accounting-time-out-of-commit-trans.patch b/patches.suse/revert-btrfs-qgroup-move-half-of-the-qgroup-accounting-time-out-of-commit-trans.patch
index 1ff8b31a3b..48b920d0b5 100644
--- a/patches.suse/revert-btrfs-qgroup-move-half-of-the-qgroup-accounting-time-out-of-commit-trans.patch
+++ b/patches.suse/revert-btrfs-qgroup-move-half-of-the-qgroup-accounting-time-out-of-commit-trans.patch
@@ -80,15 +80,15 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
if (new_ref_mod)
*new_ref_mod = head_ref->total_ref_mod;
-@@ -732,7 +726,6 @@ int btrfs_add_delayed_tree_ref(struct bt
+@@ -731,7 +725,6 @@ int btrfs_add_delayed_tree_ref(struct bt
struct btrfs_delayed_ref_head *head_ref;
struct btrfs_delayed_ref_root *delayed_refs;
struct btrfs_qgroup_extent_record *record = NULL;
- int qrecord_inserted;
- bool is_system = (ref_root == BTRFS_CHUNK_TREE_OBJECTID);
- int ret;
- u8 ref_type;
-@@ -775,8 +768,7 @@ int btrfs_add_delayed_tree_ref(struct bt
+ bool is_system;
+ int action = generic_ref->action;
+ int level = generic_ref->tree_ref.level;
+@@ -785,8 +778,7 @@ int btrfs_add_delayed_tree_ref(struct bt
* the spin lock
*/
head_ref = add_delayed_ref_head(fs_info, trans, head_ref, record,
@@ -98,7 +98,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
ret = insert_delayed_ref(trans, delayed_refs, head_ref, &ref->node);
-@@ -788,8 +780,6 @@ int btrfs_add_delayed_tree_ref(struct bt
+@@ -798,8 +790,6 @@ int btrfs_add_delayed_tree_ref(struct bt
if (ret > 0)
kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
@@ -107,15 +107,15 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
return 0;
free_head_ref:
-@@ -814,7 +804,6 @@ int btrfs_add_delayed_data_ref(struct bt
+@@ -822,7 +812,6 @@ int btrfs_add_delayed_data_ref(struct bt
struct btrfs_delayed_ref_head *head_ref;
struct btrfs_delayed_ref_root *delayed_refs;
struct btrfs_qgroup_extent_record *record = NULL;
- int qrecord_inserted;
+ int action = generic_ref->action;
int ret;
- u8 ref_type;
-
-@@ -863,8 +852,7 @@ int btrfs_add_delayed_data_ref(struct bt
+ u64 bytenr = generic_ref->bytenr;
+@@ -881,8 +870,7 @@ int btrfs_add_delayed_data_ref(struct bt
* the spin lock
*/
head_ref = add_delayed_ref_head(fs_info, trans, head_ref, record,
@@ -125,7 +125,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
ret = insert_delayed_ref(trans, delayed_refs, head_ref, &ref->node);
spin_unlock(&delayed_refs->lock);
-@@ -875,8 +863,6 @@ int btrfs_add_delayed_data_ref(struct bt
+@@ -893,8 +881,6 @@ int btrfs_add_delayed_data_ref(struct bt
if (ret > 0)
kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
@@ -134,7 +134,7 @@ Acked-by: Jeff Mahoney <jeffm@suse.com>
return 0;
}
-@@ -902,7 +888,7 @@ int btrfs_add_delayed_extent_op(struct b
+@@ -920,7 +906,7 @@ int btrfs_add_delayed_extent_op(struct b
add_delayed_ref_head(fs_info, trans, head_ref, NULL,
BTRFS_UPDATE_DELAYED_HEAD,
diff --git a/series.conf b/series.conf
index 019dea831a..4186544fae 100644
--- a/series.conf
+++ b/series.conf
@@ -21788,6 +21788,12 @@
patches.fixes/0001-btrfs-reloc-Fix-NULL-pointer-dereference-due-to-expa.patch
patches.suse/0001-btrfs-delayed-ref-Introduce-better-documented-delaye.patch
patches.suse/0002-btrfs-extent-tree-Open-code-process_func-in-__btrfs_.patch
+ patches.suse/0003-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch
+ patches.suse/0004-btrfs-delayed-ref-Use-btrfs_ref-to-refactor-btrfs_ad.patch
+ patches.suse/0006-btrfs-extent-tree-Use-btrfs_ref-to-refactor-add_pinn.patch
+ patches.suse/0007-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_in.patch
+ patches.suse/0008-btrfs-extent-tree-Use-btrfs_ref-to-refactor-btrfs_fr.patch
+ patches.suse/0009-btrfs-qgroup-Don-t-scan-leaf-if-we-re-modifying-relo.patch
patches.drivers/mmc-core-fix-possible-use-after-free-of-host.patch
patches.drivers/phy-sun4i-usb-Make-sure-to-disable-PHY0-passby-for-p.patch
patches.drivers/stm-class-Fix-channel-free-in-stm-output-free-path.patch
@@ -21944,6 +21950,7 @@
patches.fixes/qla2xxx-always-allocate-qla_tgt_wq.patch
patches.suse/lpfc-validate-command-in-lpfc_sli4_scmd_to_wqidx_dis.patch
patches.suse/0001-drm-ttm-Remove-warning-about-inconsistent-mapping-in.patch
+ patches.suse/0001-btrfs-extent-tree-Fix-a-bug-that-btrfs-is-unable-to-.patch
########################################################
# end of sorted patches