btrfs: track refs in a rb_tree instead of a list
authorJosef Bacik <josef@toxicpanda.com>
Thu, 19 Oct 2017 18:16:00 +0000 (14:16 -0400)
committerDavid Sterba <dsterba@suse.com>
Wed, 1 Nov 2017 19:45:35 +0000 (20:45 +0100)
commit0e0adbcfdc908684317c99a9bf5e13383f03b7ec
treed5c0abdc94d45770ea98fe55f22d6e61540e75af
parent1d148e5939f55c76d06108548c7c0226e55dde8e
btrfs: track refs in a rb_tree instead of a list

If we get a significant amount of delayed refs for a single block (think
modifying multiple snapshots) we can end up spending an ungodly amount
of time looping through all of the entries trying to see if they can be
merged.  This is because we only add them to a list, so we have O(2n)
for every ref head.  This doesn't make any sense as we likely have refs
for different roots, and so they cannot be merged.  Tracking in a tree
will allow us to break as soon as we hit an entry that doesn't match,
making our worst case O(n).

With this we can also merge entries more easily.  Before we had to hope
that matching refs were on the ends of our list, but with the tree we
can search down to exact matches and merge them at insert time.

Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/backref.c
fs/btrfs/delayed-ref.c
fs/btrfs/delayed-ref.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c