OSDN Git Service

btrfs: qgroup: Don't trace subtree if we're dropping reloc tree
authorQu Wenruo <wqu@suse.com>
Thu, 27 Sep 2018 06:42:33 +0000 (14:42 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 15 Oct 2018 15:23:36 +0000 (17:23 +0200)
Reloc tree doesn't contribute to qgroup numbers, as we have accounted
them at balance time (see replace_path()).

Skipping the unneeded subtree tracing should reduce the overhead.

[[Benchmark]]
Hardware:
VM 4G vRAM, 8 vCPUs,
disk is using 'unsafe' cache mode,
backing device is SAMSUNG 850 evo SSD.
Host has 16G ram.

Mkfs parameter:
--nodesize 4K (To bump up tree size)

Initial subvolume contents:
4G data copied from /usr and /lib.
(With enough regular small files)

Snapshots:
16 snapshots of the original subvolume.
each snapshot has 3 random files modified.

balance parameter:
-m

So the content should be pretty similar to a real world root fs layout.

                     | v4.19-rc1    | w/ patchset    | diff (*)
---------------------------------------------------------------
relocated extents    | 22929        | 22900          | -0.1%
qgroup dirty extents | 227757       | 167139         | -26.6%
time (sys)           | 65.253s      | 50.123s        | -23.2%
time (real)          | 74.032s      | 52.551s        | -29.0%

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-tree.c

index 8798fa0..d68ee91 100644 (file)
@@ -8683,7 +8683,13 @@ skip:
                        parent = 0;
                }
 
-               if (need_account) {
+               /*
+                * Reloc tree doesn't contribute to qgroup numbers, and we have
+                * already accounted them at merge time (replace_path),
+                * thus we could skip expensive subtree trace here.
+                */
+               if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
+                   need_account) {
                        ret = btrfs_qgroup_trace_subtree(trans, next,
                                                         generation, level - 1);
                        if (ret) {