aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/qgroup.c21
-rw-r--r--fs/btrfs/qgroup.h1
-rw-r--r--fs/btrfs/relocation.c10
3 files changed, 21 insertions, 11 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 6b35b3481085..ac9690f36a94 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1761,7 +1761,8 @@ static int adjust_slots_upwards(struct btrfs_path *path, int root_level)
1761static int qgroup_trace_extent_swap(struct btrfs_trans_handle* trans, 1761static int qgroup_trace_extent_swap(struct btrfs_trans_handle* trans,
1762 struct extent_buffer *src_eb, 1762 struct extent_buffer *src_eb,
1763 struct btrfs_path *dst_path, 1763 struct btrfs_path *dst_path,
1764 int dst_level, int root_level) 1764 int dst_level, int root_level,
1765 bool trace_leaf)
1765{ 1766{
1766 struct btrfs_key key; 1767 struct btrfs_key key;
1767 struct btrfs_path *src_path; 1768 struct btrfs_path *src_path;
@@ -1863,7 +1864,7 @@ static int qgroup_trace_extent_swap(struct btrfs_trans_handle* trans,
1863 goto out; 1864 goto out;
1864 1865
1865 /* Record leaf file extents */ 1866 /* Record leaf file extents */
1866 if (dst_level == 0) { 1867 if (dst_level == 0 && trace_leaf) {
1867 ret = btrfs_qgroup_trace_leaf_items(trans, src_path->nodes[0]); 1868 ret = btrfs_qgroup_trace_leaf_items(trans, src_path->nodes[0]);
1868 if (ret < 0) 1869 if (ret < 0)
1869 goto out; 1870 goto out;
@@ -1900,7 +1901,7 @@ static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans,
1900 struct extent_buffer *src_eb, 1901 struct extent_buffer *src_eb,
1901 struct btrfs_path *dst_path, 1902 struct btrfs_path *dst_path,
1902 int cur_level, int root_level, 1903 int cur_level, int root_level,
1903 u64 last_snapshot) 1904 u64 last_snapshot, bool trace_leaf)
1904{ 1905{
1905 struct btrfs_fs_info *fs_info = trans->fs_info; 1906 struct btrfs_fs_info *fs_info = trans->fs_info;
1906 struct extent_buffer *eb; 1907 struct extent_buffer *eb;
@@ -1972,7 +1973,7 @@ static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans,
1972 1973
1973 /* Now record this tree block and its counter part for qgroups */ 1974 /* Now record this tree block and its counter part for qgroups */
1974 ret = qgroup_trace_extent_swap(trans, src_eb, dst_path, cur_level, 1975 ret = qgroup_trace_extent_swap(trans, src_eb, dst_path, cur_level,
1975 root_level); 1976 root_level, trace_leaf);
1976 if (ret < 0) 1977 if (ret < 0)
1977 goto cleanup; 1978 goto cleanup;
1978 1979
@@ -1989,7 +1990,7 @@ static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans,
1989 /* Recursive call (at most 7 times) */ 1990 /* Recursive call (at most 7 times) */
1990 ret = qgroup_trace_new_subtree_blocks(trans, src_eb, 1991 ret = qgroup_trace_new_subtree_blocks(trans, src_eb,
1991 dst_path, cur_level - 1, root_level, 1992 dst_path, cur_level - 1, root_level,
1992 last_snapshot); 1993 last_snapshot, trace_leaf);
1993 if (ret < 0) 1994 if (ret < 0)
1994 goto cleanup; 1995 goto cleanup;
1995 } 1996 }
@@ -2028,6 +2029,7 @@ out:
2028 * @dst_parent, @dst_slot: pointer to dst (reloc tree) eb. 2029 * @dst_parent, @dst_slot: pointer to dst (reloc tree) eb.
2029 */ 2030 */
2030int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans, 2031int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
2032 struct btrfs_block_group_cache *bg_cache,
2031 struct extent_buffer *src_parent, int src_slot, 2033 struct extent_buffer *src_parent, int src_slot,
2032 struct extent_buffer *dst_parent, int dst_slot, 2034 struct extent_buffer *dst_parent, int dst_slot,
2033 u64 last_snapshot) 2035 u64 last_snapshot)
@@ -2037,6 +2039,7 @@ int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
2037 struct btrfs_key first_key; 2039 struct btrfs_key first_key;
2038 struct extent_buffer *src_eb = NULL; 2040 struct extent_buffer *src_eb = NULL;
2039 struct extent_buffer *dst_eb = NULL; 2041 struct extent_buffer *dst_eb = NULL;
2042 bool trace_leaf = false;
2040 u64 child_gen; 2043 u64 child_gen;
2041 u64 child_bytenr; 2044 u64 child_bytenr;
2042 int level; 2045 int level;
@@ -2055,6 +2058,12 @@ int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
2055 return -EUCLEAN; 2058 return -EUCLEAN;
2056 } 2059 }
2057 2060
2061 /*
2062 * Only trace leaf if we're relocating data block groups, this could
2063 * reduce tons of data extents tracing for meta/sys bg relocation.
2064 */
2065 if (bg_cache->flags & BTRFS_BLOCK_GROUP_DATA)
2066 trace_leaf = true;
2058 /* Read out real @src_eb, pointed by @src_parent and @src_slot */ 2067 /* Read out real @src_eb, pointed by @src_parent and @src_slot */
2059 child_bytenr = btrfs_node_blockptr(src_parent, src_slot); 2068 child_bytenr = btrfs_node_blockptr(src_parent, src_slot);
2060 child_gen = btrfs_node_ptr_generation(src_parent, src_slot); 2069 child_gen = btrfs_node_ptr_generation(src_parent, src_slot);
@@ -2099,7 +2108,7 @@ int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
2099 2108
2100 /* Do the generation-aware breadth-first search */ 2109 /* Do the generation-aware breadth-first search */
2101 ret = qgroup_trace_new_subtree_blocks(trans, src_eb, dst_path, level, 2110 ret = qgroup_trace_new_subtree_blocks(trans, src_eb, dst_path, level,
2102 level, last_snapshot); 2111 level, last_snapshot, trace_leaf);
2103 if (ret < 0) 2112 if (ret < 0)
2104 goto out; 2113 goto out;
2105 ret = 0; 2114 ret = 0;
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 1aaf4c276900..80ebeb3ab5ba 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -238,6 +238,7 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans,
238 u64 root_gen, int root_level); 238 u64 root_gen, int root_level);
239 239
240int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans, 240int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
241 struct btrfs_block_group_cache *bg_cache,
241 struct extent_buffer *src_parent, int src_slot, 242 struct extent_buffer *src_parent, int src_slot,
242 struct extent_buffer *dst_parent, int dst_slot, 243 struct extent_buffer *dst_parent, int dst_slot,
243 u64 last_snapshot); 244 u64 last_snapshot);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index d10357122aa1..3e6e3d93caad 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1744,7 +1744,7 @@ int memcmp_node_keys(struct extent_buffer *eb, int slot,
1744 * errors, a negative error number is returned. 1744 * errors, a negative error number is returned.
1745 */ 1745 */
1746static noinline_for_stack 1746static noinline_for_stack
1747int replace_path(struct btrfs_trans_handle *trans, 1747int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc,
1748 struct btrfs_root *dest, struct btrfs_root *src, 1748 struct btrfs_root *dest, struct btrfs_root *src,
1749 struct btrfs_path *path, struct btrfs_key *next_key, 1749 struct btrfs_path *path, struct btrfs_key *next_key,
1750 int lowest_level, int max_level) 1750 int lowest_level, int max_level)
@@ -1888,9 +1888,9 @@ again:
1888 * and tree block numbers, if current trans doesn't free 1888 * and tree block numbers, if current trans doesn't free
1889 * data reloc tree inode. 1889 * data reloc tree inode.
1890 */ 1890 */
1891 ret = btrfs_qgroup_trace_subtree_swap(trans, parent, slot, 1891 ret = btrfs_qgroup_trace_subtree_swap(trans, rc->block_group,
1892 path->nodes[level], path->slots[level], 1892 parent, slot, path->nodes[level],
1893 last_snapshot); 1893 path->slots[level], last_snapshot);
1894 if (ret < 0) 1894 if (ret < 0)
1895 break; 1895 break;
1896 1896
@@ -2209,7 +2209,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
2209 btrfs_comp_cpu_keys(&next_key, &key) >= 0) { 2209 btrfs_comp_cpu_keys(&next_key, &key) >= 0) {
2210 ret = 0; 2210 ret = 0;
2211 } else { 2211 } else {
2212 ret = replace_path(trans, root, reloc_root, path, 2212 ret = replace_path(trans, rc, root, reloc_root, path,
2213 &next_key, level, max_level); 2213 &next_key, level, max_level);
2214 } 2214 }
2215 if (ret < 0) { 2215 if (ret < 0) {