mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
btrfs: fix delayed_node ref_tracker use after free
Move the print before releasing the delayed node.
In my initial testing there was a bug that was causing delayed_nodes
to not get freed which is why I put the print after the release. This
obviously neglects the case where the delayed node is properly freed.
Add condition to make sure we only print if we have more than one
reference to the delayed_node to prevent printing when we only have
the reference taken in btrfs_kill_all_delayed_nodes().
Fixes: b767a28d61 ("btrfs: print leaked references in kill_all_delayed_nodes()")
Tested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Leo Martins <loemra.dev@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
committed by
David Sterba
parent
1fabe43b4e
commit
0fd7e7a1ad
@@ -2110,9 +2110,9 @@ void btrfs_kill_all_delayed_nodes(struct btrfs_root *root)
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
__btrfs_kill_delayed_node(delayed_nodes[i]);
|
||||
btrfs_delayed_node_ref_tracker_dir_print(delayed_nodes[i]);
|
||||
btrfs_release_delayed_node(delayed_nodes[i],
|
||||
&delayed_node_trackers[i]);
|
||||
btrfs_delayed_node_ref_tracker_dir_print(delayed_nodes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +219,13 @@ static inline void btrfs_delayed_node_ref_tracker_dir_print(struct btrfs_delayed
|
||||
if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Only print if there are leaked references. The caller is
|
||||
* holding one reference, so if refs == 1 there is no leak.
|
||||
*/
|
||||
if (refcount_read(&node->refs) == 1)
|
||||
return;
|
||||
|
||||
ref_tracker_dir_print(&node->ref_dir.dir,
|
||||
BTRFS_DELAYED_NODE_REF_TRACKER_DISPLAY_LIMIT);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user