btrfs: qgroup: Don't scan leaf if we're modifying reloc tree
authorQu Wenruo <wqu@suse.com>
Thu, 4 Apr 2019 06:45:37 +0000 (14:45 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 29 Apr 2019 17:02:49 +0000 (19:02 +0200)
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

index 2e69e67a6ae9a6433c0411754d04ff0d5793cda5..34078f302538d4ed1bbac59a7903758d5eacd00b 100644 (file)
@@ -9141,11 +9141,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
                        else
                                ret = btrfs_dec_ref(trans, root, eb, 0);
                        BUG_ON(ret); /* -ENOMEM */
-                       ret = btrfs_qgroup_trace_leaf_items(trans, eb);
-                       if (ret) {
-                               btrfs_err_rl(fs_info,
-                                            "error %d accounting leaf items. Quota is out of sync, rescan required.",
+                       if (is_fstree(root->root_key.objectid)) {
+                               ret = btrfs_qgroup_trace_leaf_items(trans, 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 btrfs_clean_tree_block happy */