WARNING in btrfs_release_global_block_rsv (3)

Status: upstream: reported on 2026/11/02 13:09
Subsystems: btrfs
Labels: prio:low
[Documentation on labels]
Reported-by: syzbot+7ec60f4482abeecb0fd8@syzkaller.appspotmail.com
First crash: 4d10h, last: 2d01h
✨ AI-generated root cause summary:

In Btrfs, when an extent is freed and reallocated with a smaller size before its delayed refs are processed, update_existing_head_ref() overwrites existing->num_bytes with the new size before adjusting checksum deletion accounting. When existing->total_ref_mod transitions from negative to non-negative, btrfs_delayed_refs_rsv_release() calculates and releases fewer csum leaves than were originally accounted in add_delayed_ref_head(). This permanently leaks delayed_refs_rsv size and reserved space, leading to metadata space exhaustion (premature -ENOSPC) during runtime and triggering a WARNING on unmount in btrfs_release_global_block_rsv().

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit c339f4010dea:

Root Cause Analysis

1. Context and Mechanism

In Btrfs, delayed references (btrfs_delayed_ref_root, btrfs_delayed_ref_head, and btrfs_delayed_ref_node) buffer backref and checksum updates in memory to minimize contention on the extent tree and checksum tree.

When a data extent is queued for deletion in add_delayed_ref_head() (fs/btrfs/delayed-ref.c):

  • If head_ref->is_data and head_ref->ref_mod < 0, Btrfs anticipates deleting checksum items when the data extent reference count drops to 0.
  • It reserves metadata space in trans->delayed_ref_csum_deletions by calculating btrfs_csum_bytes_to_leaves(fs_info, head_ref->num_bytes).
  • It increments delayed_refs->pending_csums += head_ref->num_bytes.
  • btrfs_update_delayed_refs_rsv(trans) subsequently increases fs_info->delayed_refs_rsv.size and fs_info->delayed_refs_rsv.reserved.

If that same block/extent range is freed and reallocated before the delayed ref entries are run, an existing delayed reference head is reused via update_existing_head_ref() (fs/btrfs/delayed-ref.c):

	if (update->must_insert_reserved) {
		existing->must_insert_reserved = update->must_insert_reserved;
		existing->owning_root = update->owning_root;
		existing->num_bytes = update->num_bytes;
	}
...
	old_ref_mod = existing->total_ref_mod;
	existing->ref_mod += update->ref_mod;
	existing->total_ref_mod += update->ref_mod;

	if (existing->is_data) {
		u64 csum_leaves =
			btrfs_csum_bytes_to_leaves(fs_info,
						   existing->num_bytes);

		if (existing->total_ref_mod >= 0 && old_ref_mod < 0) {
			delayed_refs->pending_csums -= existing->num_bytes;
			btrfs_delayed_refs_rsv_release(fs_info, 0, csum_leaves);
		}
		if (existing->total_ref_mod < 0 && old_ref_mod >= 0) {
			delayed_refs->pending_csums += existing->num_bytes;
			trans->delayed_ref_csum_deletions += csum_leaves;
		}
	}

2. The Flaw

Notice that existing->num_bytes = update->num_bytes; is executed before calculating csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, existing->num_bytes) and updating delayed_refs->pending_csums.

If an extent is reallocated with a smaller size than the original extent (update->num_bytes < old existing->num_bytes), and the new reference modification transitions total_ref_mod from negative to non-negative (old_ref_mod < 0 && existing->total_ref_mod >= 0):

  1. csum_leaves is calculated based on the new, smaller update->num_bytes rather than the original num_bytes that was used when reserving space.
  2. delayed_refs->pending_csums is decremented by update->num_bytes rather than the original num_bytes, leaving pending_csums artificially positive.
  3. btrfs_delayed_refs_rsv_release(fs_info, 0, csum_leaves) releases fewer bytes from delayed_refs_rsv than were added in add_delayed_ref_head().

As a result:

  • fs_info->delayed_refs_rsv.size is under-decremented and remains greater than zero.
  • Because delayed_refs_rsv.size never drops to 0, delayed_refs_rsv.reserved is never clamped to 0.
  • When unmounting the filesystem in close_ctree() -> btrfs_free_block_groups() -> btrfs_release_global_block_rsv(), the assertion fires:
    WARN_ON(fs_info->delayed_refs_rsv.reserved > 0);
    

Classification Justification

  • RootCauseFiles: fs/btrfs/delayed-ref.c contains update_existing_head_ref(), where num_bytes is prematurely updated before checksum deletion leaf accounting is reconciled.
  • MemoryCorruption: false. The bug only affects space reservation counters and does not result in invalid memory access, out-of-bounds writes, or use-after-free conditions.
  • InfoLeak: "none". No kernel, heap, or pointer contents are disclosed to user space.
  • RawDenialOfService: true. The unaccounted reservation in delayed_refs_rsv permanently inflates space_info->bytes_may_use in the metadata space info. Over time, leaked metadata reservations prevent the filesystem from reserving metadata space for new transactions, causing premature and false -ENOSPC errors that deny write access to the filesystem.
  • IsNetCandidate: false. The defect is purely in the Btrfs filesystem storage reservation layer.
  • IsKVMCandidate: false. No virtualization or KVM subsystems are involved.
▶ ▼ ✨ AI Jobs (2)
ID Workflow Result Correct Bug Created Started Finished Revision
73d90753 repro-c 💥 WARNING in btrfs_release_global_block_rsv (3) 2026/11/01 07:48 2026/11/01 07:48 2026/11/01 16:50 25a0ae84
fd368209 assessment-security DenialOfService: ✅ Exploitable: ❌ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ❌ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ WARNING in btrfs_release_global_block_rsv (3) 2026/10/29 13:07 2026/10/29 13:08 2026/10/29 14:02 b1d00f76
▶ ▼ Discussions (1)
Title Replies (including bot) Last reply
[syzbot] [btrfs?] WARNING in btrfs_release_global_block_rsv (3) 0 (1) 2026/11/02 13:09
▶ ▼ Similar bugs (5)
Kernel Title Rank 🛈 Repro Cause bisect Fix bisect Count Last Reported Patched Status
linux-5.15 WARNING in btrfs_release_global_block_rsv -1 1 1303d 1303d 0/3 auto-obsoleted due to no activity on 2023/08/07 13:28
linux-6.1 WARNING in btrfs_release_global_block_rsv origin:upstream -1 syz, C error 5 180d 607d 0/3 upstream: reported C repro on 2025/03/05 00:58
linux-6.6 WARNING in btrfs_release_global_block_rsv -1 1 235d 235d 0/2 auto-obsoleted due to no activity on 2026/06/20 00:44
upstream WARNING in btrfs_release_global_block_rsv btrfs -1 syz, C done done 7 1021d 1130d 0/29 auto-obsoleted due to no activity on 2024/04/25 16:32
upstream WARNING in btrfs_release_global_block_rsv (2) prio:low btrfs -1 syz, C error done 276 148d 712d 0/29 auto-obsoleted due to no activity on 2026/08/16 00:08

Sample crash report:
BTRFS info (device loop6): last unmount of filesystem db05bf05-c4f4-4d41-ba1f-eb57295b561b
------------[ cut here ]------------
fs_info->delayed_refs_rsv.reserved > 0
WARNING: fs/btrfs/block-rsv.c:481 at btrfs_release_global_block_rsv+0x2e4/0x300 fs/btrfs/block-rsv.c:481, CPU#1: syz-executor/6147
Modules linked in:
CPU: 1 UID: 0 PID: 6147 Comm: syz-executor Not tainted syzkaller #0 PREEMPT_{RT,(full)} 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/07/2026
RIP: 0010:btrfs_release_global_block_rsv+0x2e4/0x300 fs/btrfs/block-rsv.c:481
Code: 0f 0b 90 e9 c1 fe ff ff e8 69 cd 84 fd 90 0f 0b 90 e9 eb fe ff ff e8 5b cd 84 fd 90 0f 0b 90 e9 15 ff ff ff e8 4d cd 84 fd 90 <0f> 0b 90 e9 46 ff ff ff e8 3f cd 84 fd 90 0f 0b 90 e9 69 ff ff ff
RSP: 0018:ffffc90006717ad0 EFLAGS: 00010293
RAX: ffffffff84430bd3 RBX: ffff8880636e4768 RCX: ffff888031809f40
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffff8880636e42b0 R08: 0000000000000000 R09: 0000000000000000
R10: dffffc0000000000 R11: fffffbfff21ab138 R12: ffff8880636e4000
R13: 0000000000000000 R14: 0000000000008000 R15: dffffc0000000000
FS:  000055557537f500(0000) GS:ffff888124816000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f2f2de04e00 CR3: 000000003d9c0000 CR4: 00000000003526f0
Call Trace:
 <TASK>
 btrfs_free_block_groups+0xdc2/0x1040 fs/btrfs/block-group.c:4444
 close_ctree+0x7d1/0x1200 fs/btrfs/disk-io.c:4575
 generic_shutdown_super+0x140/0x2d0 fs/super.c:723
 kill_anon_super+0x3b/0x70 fs/super.c:1315
 btrfs_kill_super+0x41/0x50 fs/btrfs/super.c:2139
 deactivate_locked_super+0xbe/0x110 fs/super.c:558
 cleanup_mnt+0x204/0x2a0 fs/namespace.c:1396
 task_work_run+0x1d9/0x260 kernel/task_work.c:233
 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline]
 __exit_to_user_mode_loop kernel/entry/common.c:70 [inline]
 exit_to_user_mode_loop+0x204/0x770 kernel/entry/common.c:101
 __exit_to_user_mode_prepare include/linux/irq-entry-common.h:207 [inline]
 syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:230 [inline]
 syscall_exit_to_user_mode include/linux/entry-common.h:343 [inline]
 do_syscall_64+0x328/0x520 arch/x86/entry/syscall_64.c:89
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f43e2c70797
Code: a2 c7 05 5c 9f 25 00 00 00 00 00 eb 96 e8 e1 12 00 00 90 31 f6 e9 09 00 00 00 66 0f 1f 84 00 00 00 00 00 b8 a6 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 c7 c2 e8 ff ff ff f7 d8 64 89 02 b8
RSP: 002b:00007ffe17fa6818 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
RAX: 0000000000000000 RBX: 00007f43e2d05f93 RCX: 00007f43e2c70797
RDX: 0000000000000000 RSI: 0000000000000009 RDI: 00007ffe17fa68d0
RBP: 00007ffe17fa68d0 R08: 00007ffe17fa78d0 R09: 00000000ffffffff
R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffe17fa7960
R13: 00007f43e2d05f93 R14: 000000000003637c R15: 00007ffe17fa79a0
 </TASK>

Crashes (2):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/10/31 21:49 upstream 36aad21d50d1 2041d3f8 .config console log report info [disk image] [vmlinux] [kernel image] ci2-upstream-fs WARNING in btrfs_release_global_block_rsv
2026/10/29 13:07 upstream c339f4010dea b1d00f76 .config console log report info [disk image] [vmlinux] [kernel image] ci2-upstream-fs WARNING in btrfs_release_global_block_rsv
* Struck through repros no longer work on HEAD.