btrfs: use a regular rb_root instead of cached rb_root for extent_map_tree
authorFilipe Manana <fdmanana@suse.com>
Fri, 10 May 2024 16:41:04 +0000 (17:41 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 11 Jul 2024 13:33:18 +0000 (15:33 +0200)
commit4e660ca3a98d93180973426239e69ee44f4d7941
treeadaec0d5dca0b3a6b24f6af573dc5479afc2e403
parent7f5830bc964dbe761af27c9a9f788bd8c7397d3d
btrfs: use a regular rb_root instead of cached rb_root for extent_map_tree

We are currently using a cached rb_root (struct rb_root_cached) for the
rb root of struct extent_map_tree. This doesn't offer much of an advantage
here because:

1) It's only advantage over the regular rb_root is that it caches a
   pointer to the left most node (first node), so a call to
   rb_first_cached() doesn't have to chase pointers until it reaches
   the left most node;

2) We only have two scenarios that access left most node with
   rb_first_cached():

      When dropping all extent maps from an inode, during inode eviction;

      When iterating over extent maps during the extent map shrinker;

3) In both cases we keep removing extent maps, which causes deletion of
   the left most node so rb_erase_cached() has to call rb_next() to find
   out what's the next left most node and assign it to
   struct rb_root_cached::rb_leftmost;

4) We can do that ourselves in those two uses cases and stop using a
   rb_root_cached rb tree and use instead a regular rb_root rb tree.

   This reduces the size of struct extent_map_tree by 8 bytes and, since
   this structure is embedded in struct btrfs_inode, it also reduces the
   size of that structure by 8 bytes.

   So on a 64 bits platform the size of btrfs_inode is reduced from 1032
   bytes down to 1024 bytes.

   This means we will be able to have 4 inodes per 4K page instead of 3.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent_map.c
fs/btrfs/extent_map.h
fs/btrfs/tests/extent-map-tests.c