From: Zygo Blaxell Date: Tue, 8 Sep 2026 01:37:12 +0000 (-0400) Subject: wip: cand28 = cand25 + extent-buffer leak forensics (audit search present) X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb3b4e80ea8e20a96e955913b71bb465958e701e;p=linux wip: cand28 = cand25 + extent-buffer leak forensics (audit search present) --- diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 6c251d78a7506..003d9beaaf4ba 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -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; } /* diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 2c2218ff00adb..b76515b1acaf4 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -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)) diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 73571d5d3d5ad..c8ba72f8ee5b1 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -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;