Skip to content

Commit a6e9553

Browse files
fdmananakdave
authored andcommitted
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>
1 parent b72647f commit a6e9553

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

fs/btrfs/tree-mod-log.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,30 @@ static noinline int tree_mod_log_insert(struct btrfs_fs_info *fs_info,
164164
return 0;
165165
}
166166

167+
static inline bool skip_eb_logging(const struct extent_buffer *eb)
168+
{
169+
const u64 owner = btrfs_header_owner(eb);
170+
171+
if (btrfs_header_level(eb) == 0)
172+
return true;
173+
174+
/*
175+
* Tree mod logging exists so that there's a consistent view of the
176+
* extents and backrefs of inodes even if while a task is iterating over
177+
* them other tasks are modifying subvolume trees and the extent tree
178+
* (including running delayed refs). So we only need to log extent
179+
* buffers from the extent tree and subvolume trees.
180+
*/
181+
182+
if (owner == BTRFS_EXTENT_TREE_OBJECTID)
183+
return false;
184+
185+
if (btrfs_is_fstree(owner))
186+
return false;
187+
188+
return true;
189+
}
190+
167191
/*
168192
* Determines if logging can be omitted. Returns true if it can. Otherwise, it
169193
* 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
174198
{
175199
if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
176200
return true;
177-
if (eb && btrfs_header_level(eb) == 0)
201+
if (eb && skip_eb_logging(eb))
178202
return true;
179203

180204
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,
192216
{
193217
if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
194218
return false;
195-
if (eb && btrfs_header_level(eb) == 0)
219+
if (eb && skip_eb_logging(eb))
196220
return false;
197221

198222
return true;

0 commit comments

Comments
 (0)