Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Filipe Manana and committed by
David Sterba
d30b236a 9e9ff875

+26 -2
+26 -2
fs/btrfs/tree-mod-log.c
··· 164 164 return 0; 165 165 } 166 166 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 + 167 191 /* 168 192 * Determines if logging can be omitted. Returns true if it can. Otherwise, it 169 193 * returns false with the tree_mod_log_lock acquired. The caller must hold ··· 198 174 { 199 175 if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags)) 200 176 return true; 201 - if (eb && btrfs_header_level(eb) == 0) 177 + if (eb && skip_eb_logging(eb)) 202 178 return true; 203 179 204 180 write_lock(&fs_info->tree_mod_log_lock); ··· 216 192 { 217 193 if (!test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags)) 218 194 return false; 219 - if (eb && btrfs_header_level(eb) == 0) 195 + if (eb && skip_eb_logging(eb)) 220 196 return false; 221 197 222 198 return true;