diff options
-rw-r--r-- | fs/btrfs/qgroup.c | 21 | ||||
-rw-r--r-- | fs/btrfs/qgroup.h | 1 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 10 |
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) static int qgroup_trace_extent_swap(struct btrfs_trans_handle* trans, struct extent_buffer *src_eb, struct btrfs_path *dst_path, - int dst_level, int root_level) + int dst_level, int root_level, + bool trace_leaf) { struct btrfs_key key; struct btrfs_path *src_path; @@ -1863,7 +1864,7 @@ static int qgroup_trace_extent_swap(struct btrfs_trans_handle* trans, goto out; /* Record leaf file extents */ - if (dst_level == 0) { + if (dst_level == 0 && trace_leaf) { ret = btrfs_qgroup_trace_leaf_items(trans, src_path->nodes[0]); if (ret < 0) goto out; @@ -1900,7 +1901,7 @@ static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans, struct extent_buffer *src_eb, struct btrfs_path *dst_path, int cur_level, int root_level, - u64 last_snapshot) + u64 last_snapshot, bool trace_leaf) { struct btrfs_fs_info *fs_info = trans->fs_info; struct extent_buffer *eb; @@ -1972,7 +1973,7 @@ static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans, /* Now record this tree block and its counter part for qgroups */ ret = qgroup_trace_extent_swap(trans, src_eb, dst_path, cur_level, - root_level); + root_level, trace_leaf); if (ret < 0) goto cleanup; @@ -1989,7 +1990,7 @@ static int qgroup_trace_new_subtree_blocks(struct btrfs_trans_handle* trans, /* Recursive call (at most 7 times) */ ret = qgroup_trace_new_subtree_blocks(trans, src_eb, dst_path, cur_level - 1, root_level, - last_snapshot); + last_snapshot, trace_leaf); if (ret < 0) goto cleanup; } @@ -2028,6 +2029,7 @@ out: * @dst_parent, @dst_slot: pointer to dst (reloc tree) eb. */ int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans, + struct btrfs_block_group_cache *bg_cache, struct extent_buffer *src_parent, int src_slot, struct extent_buffer *dst_parent, int dst_slot, u64 last_snapshot) @@ -2037,6 +2039,7 @@ int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans, struct btrfs_key first_key; struct extent_buffer *src_eb = NULL; struct extent_buffer *dst_eb = NULL; + bool trace_leaf = false; u64 child_gen; u64 child_bytenr; int level; @@ -2055,6 +2058,12 @@ int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans, return -EUCLEAN; } + /* + * Only trace leaf if we're relocating data block groups, this could + * reduce tons of data extents tracing for meta/sys bg relocation. + */ + if (bg_cache->flags & BTRFS_BLOCK_GROUP_DATA) + trace_leaf = true; /* Read out real @src_eb, pointed by @src_parent and @src_slot */ child_bytenr = btrfs_node_blockptr(src_parent, src_slot); 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, /* Do the generation-aware breadth-first search */ ret = qgroup_trace_new_subtree_blocks(trans, src_eb, dst_path, level, - level, last_snapshot); + level, last_snapshot, trace_leaf); if (ret < 0) goto out; 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, u64 root_gen, int root_level); int btrfs_qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans, + struct btrfs_block_group_cache *bg_cache, struct extent_buffer *src_parent, int src_slot, struct extent_buffer *dst_parent, int dst_slot, 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, * errors, a negative error number is returned. */ static noinline_for_stack -int replace_path(struct btrfs_trans_handle *trans, +int replace_path(struct btrfs_trans_handle *trans, struct reloc_control *rc, struct btrfs_root *dest, struct btrfs_root *src, struct btrfs_path *path, struct btrfs_key *next_key, int lowest_level, int max_level) @@ -1888,9 +1888,9 @@ again: * and tree block numbers, if current trans doesn't free * data reloc tree inode. */ - ret = btrfs_qgroup_trace_subtree_swap(trans, parent, slot, - path->nodes[level], path->slots[level], - last_snapshot); + ret = btrfs_qgroup_trace_subtree_swap(trans, rc->block_group, + parent, slot, path->nodes[level], + path->slots[level], last_snapshot); if (ret < 0) break; @@ -2209,7 +2209,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, btrfs_comp_cpu_keys(&next_key, &key) >= 0) { ret = 0; } else { - ret = replace_path(trans, root, reloc_root, path, + ret = replace_path(trans, rc, root, reloc_root, path, &next_key, level, max_level); } if (ret < 0) { |