]> git.hungrycats.org Git - linux/commitdiff
wip: cand28 = cand25 + extent-buffer leak forensics (audit search present)
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Tue, 8 Sep 2026 01:37:12 +0000 (21:37 -0400)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Tue, 8 Sep 2026 01:37:12 +0000 (21:37 -0400)
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h

index 6c251d78a750691cccb56ce7e4454cf971b39ca2..003d9beaaf4ba80259611de578213df7c26a0bdc 100644 (file)
@@ -580,9 +580,19 @@ struct extent_buffer *btrfs_find_create_tree_block(
                                                u64 bytenr, u64 owner_root,
                                                int level)
 {
+       struct extent_buffer *eb;
+
        if (btrfs_is_testing(fs_info))
                return alloc_test_extent_buffer(fs_info, bytenr);
-       return alloc_extent_buffer(fs_info, bytenr, owner_root, level);
+       eb = alloc_extent_buffer(fs_info, bytenr, owner_root, level);
+#ifdef CONFIG_BTRFS_DEBUG
+       if (!IS_ERR(eb)) {
+               if (!eb->dbg_create_ip)
+                       eb->dbg_create_ip = _RET_IP_;
+               btrfs_eb_dbg_grab(eb, _RET_IP_);
+       }
+#endif
+       return eb;
 }
 
 /*
index 2c2218ff00adb31a428ea6fbd28a100db39e74c0..b76515b1acaf49d8cbf21204a5e5aeaf901dbd1c 100644 (file)
@@ -76,9 +76,18 @@ void btrfs_extent_buffer_leak_debug_check(struct btrfs_fs_info *fs_info)
                eb = list_first_entry(&fs_info->allocated_ebs,
                                      struct extent_buffer, leak_list);
                btrfs_err(fs_info,
-                      "buffer leak start %llu len %u refs %d bflags %lu owner %llu",
+"buffer leak start %llu len %u refs %d bflags %lu owner %llu gen %llu level %d nritems %u log_index %d lock_owner %d f0up %d",
                       eb->start, eb->len, refcount_read(&eb->refs), eb->bflags,
-                      btrfs_header_owner(eb));
+                      btrfs_header_owner(eb), btrfs_header_generation(eb),
+                      btrfs_header_level(eb), btrfs_header_nritems(eb),
+                      eb->log_index, eb->lock_owner,
+                      eb->folios[0] ? folio_test_uptodate(eb->folios[0]) : -1);
+               btrfs_err(fs_info, "  leak: created %pS staled %pS grabs %u",
+                         (void *)eb->dbg_create_ip, (void *)eb->dbg_stale_ip,
+                         eb->dbg_grab_n);
+               for (int i = 0; i < 6; i++)
+                       btrfs_err(fs_info, "  leak: grab[%d] %pS", i,
+                                 (void *)eb->dbg_grab_ip[i]);
                list_del(&eb->leak_list);
                WARN_ON_ONCE(1);
                kmem_cache_free(extent_buffer_cache, eb);
@@ -3202,6 +3211,7 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info,
                spin_lock(&eb->refs_lock);
                spin_unlock(&eb->refs_lock);
        }
+       btrfs_eb_dbg_grab(eb, _RET_IP_);
        mark_extent_buffer_accessed(eb);
        return eb;
 }
@@ -3703,6 +3713,9 @@ void free_extent_buffer_stale(struct extent_buffer *eb)
 
        spin_lock(&eb->refs_lock);
        set_bit(EXTENT_BUFFER_STALE, &eb->bflags);
+#ifdef CONFIG_BTRFS_DEBUG
+       eb->dbg_stale_ip = _RET_IP_;
+#endif
 
        if (refcount_read(&eb->refs) == 2 && !extent_buffer_under_io(eb) &&
            test_and_clear_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags))
index 73571d5d3d5ad96fb1698a0b718deffec69e72a8..c8ba72f8ee5b1c7117b5326c87e2bc2dff5a9373 100644 (file)
@@ -115,9 +115,23 @@ struct extent_buffer {
 #ifdef CONFIG_BTRFS_DEBUG
        struct list_head leak_list;
        pid_t lock_owner;
+       /* DEBUG (cand27): where the last refs were taken / the block staled */
+       unsigned long dbg_grab_ip[6];
+       unsigned int dbg_grab_n;
+       unsigned long dbg_create_ip;
+       unsigned long dbg_stale_ip;
 #endif
 };
 
+#ifdef CONFIG_BTRFS_DEBUG
+static inline void btrfs_eb_dbg_grab(struct extent_buffer *eb, unsigned long ip)
+{
+       eb->dbg_grab_ip[eb->dbg_grab_n++ % 6] = ip;
+}
+#else
+#define btrfs_eb_dbg_grab(eb, ip)      do {} while (0)
+#endif
+
 struct btrfs_eb_write_context {
        struct writeback_control *wbc;
        struct extent_buffer *eb;