summaryrefslogtreecommitdiff
path: root/fs/btrfs/tree-mod-log.c
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2025-07-01 22:20:19 +0100
committerDavid Sterba <dsterba@suse.com>2025-07-22 00:09:20 +0200
commitd30b236a3e706b1225accaff686d56d3bd4e8007 (patch)
tree502943d6fa33dcd59bffd1cef1902cd2b3869881 /fs/btrfs/tree-mod-log.c
parent9e9ff875e4174be939371667d2cc81244e31232f (diff)
btrfs: avoid logging tree mod log elements for irrelevant extent buffers
We are logging tree mod log operations for extent buffers from any tree but we only need to log for the extent tree and subvolume tree, since the tree mod log is used to get a consistent view, within a transaction, of extents and their backrefs. So it's pointless to log operations for trees such as the csum tree, free space tree, root tree, chunk tree, log trees, data relocation tree, etc, as these trees are not used for backref walking and all tree mod log users are about backref walking. So skip extent buffers that don't belong neither to the extent nor to subvolume trees. This avoids unnecessary memory allocations and having a larger tree mod log rbtree with nodes that are never needed. Reviewed-by: Boris Burkov <boris@bur.io> Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/tree-mod-log.c')
-rw-r--r--fs/btrfs/tree-mod-log.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/fs/btrfs/tree-mod-log.c b/fs/btrfs/tree-mod-log.c
index 1ac2678fc4ca..dcb8aef6e900 100644
--- a/fs/btrfs/tree-mod-log.c
+++ b/fs/btrfs/tree-mod-log.c
@@ -164,6 +164,30 @@ static noinline int tree_mod_log_insert(struct btrfs_fs_info *fs_info,
return 0;
}
+static inline bool skip_eb_logging(const struct extent_buffer *eb)
+{
+ const u64 owner = btrfs_header_owner(eb);
+
+ if (btrfs_header_level(eb) == 0)
+ return true;
+
+ /*
+ * Tree mod logging exists so that there's a consistent view of the
+ * extents and backrefs of inodes even if while a task is iterating over
+ * them other tasks are modifying subvolume trees and the extent tree
+ * (including running delayed refs). So we only need to log extent
+ * buffers from the extent tree and subvolume trees.
+ */
+
+ if (owner == BTRFS_EXTENT_TREE_OBJECTID)
+ return false;
+
+ if (btrfs_is_fstree(owner))
+ return false;
+
+ return true;
+}
+
/*
* Determines if logging can be omitted. Returns true if it can. Otherwise, it
* returns false with the tree_mod_log_lock acquired. The caller must hold
@@ -174,7 +198,7 @@ static bool tree_mod_dont_log(struct btrfs_fs_info *fs_info, const struct extent
{
if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
return true;
- if (eb && btrfs_header_level(eb) == 0)
+ if (eb && skip_eb_logging(eb))
return true;
write_lock(&fs_info->tree_mod_log_lock);
@@ -192,7 +216,7 @@ static bool tree_mod_need_log(const struct btrfs_fs_info *fs_info,
{
if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
return false;
- if (eb && btrfs_header_level(eb) == 0)
+ if (eb && skip_eb_logging(eb))
return false;
return true;