FAILED: patch "[PATCH] btrfs: handle delayed ref head accounting cleanup in abort" failed to apply to 4.20-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.20-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 31890da0bfdd24b135a258404b93c58a65510c7a Mon Sep 17 00:00:00 2001
From: Josef Bacik <[email protected]>
Date: Wed, 21 Nov 2018 14:05:41 -0500
Subject: [PATCH] btrfs: handle delayed ref head accounting cleanup in abort
We weren't doing any of the accounting cleanup when we aborted transactions. Fix this by making cleanup_ref_head_accounting global and calling it from the abort code, this fixes the issue where our accounting was all wrong after the fs aborts.
The test generic/475 on a 2G VM can trigger the problems eg.:
[ 8502.136957] WARNING: CPU: 0 PID: 11064 at fs/btrfs/extent-tree.c:5986 btrfs_free_block_grou +ps+0x3dc/0x410 [btrfs] [ 8502.148372] CPU: 0 PID: 11064 Comm: umount Not tainted 5.0.0-rc1-default+ #394 [ 8502.150807] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.2-0-gf9626 +cc-prebuilt.qemu-project.org 04/01/2014 [ 8502.154317] RIP: 0010:btrfs_free_block_groups+0x3dc/0x410 [btrfs] [ 8502.160623] RSP: 0018:ffffb1ab84b93de8 EFLAGS: 00010206 [ 8502.161906] RAX: 0000000001000000 RBX: ffff9f34b1756400 RCX: 0000000000000000 [ 8502.163448] RDX: 0000000000000002 RSI: 0000000000000001 RDI: ffff9f34b1755400 [ 8502.164906] RBP: ffff9f34b7e8c000 R08: 0000000000000001 R09: 0000000000000000 [ 8502.166716] R10: 0000000000000000 R11: 0000000000000001 R12: ffff9f34b7e8c108 [ 8502.168498] R13: ffff9f34b7e8c158 R14: 0000000000000000 R15: dead000000000100 [ 8502.170296] FS: 00007fb1cf15ffc0(0000) GS:ffff9f34bd400000(0000) knlGS:0000000000000000 [ 8502.172439] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8502.173669] CR2: 00007fb1ced507b0 CR3: 000000002f7a6000 CR4: 00000000000006f0 [ 8502.175094] Call Trace: [ 8502.175759] close_ctree+0x17f/0x350 [btrfs] [ 8502.176721] generic_shutdown_super+0x64/0x100 [ 8502.177702] kill_anon_super+0x14/0x30 [ 8502.178607] btrfs_kill_super+0x12/0xa0 [btrfs] [ 8502.179602] deactivate_locked_super+0x29/0x60 [ 8502.180595] cleanup_mnt+0x3b/0x70 [ 8502.181406] task_work_run+0x98/0xc0 [ 8502.182255] exit_to_usermode_loop+0x83/0x90 [ 8502.183113] do_syscall_64+0x15b/0x180 [ 8502.183919] entry_SYSCALL_64_after_hwframe+0x49/0xbe
Corresponding to
release_global_block_rsv() {
...
WARN_ON(fs_info->delayed_refs_rsv.reserved > 0);fs/btrfs/ctree.h +4 -0
@@ -35,6 +35,7 @@struct btrfs_trans_handle ;struct btrfs_transaction ;struct btrfs_pending_snapshot ; +struct btrfs_delayed_ref_root ;extern struct kmem_cache *btrfs_trans_handle_cachep;extern struct kmem_cache *btrfs_bit_radix_cachep;extern struct kmem_cache *btrfs_path_cachep;
@@ -2664,6 +2665,9 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, unsigned long count);int btrfs_async_run_delayed_refs (struct btrfs_fs_info *fs_info,unsigned long count,u64 transid,int wait); +void btrfs_cleanup_ref_head_accounting (struct btrfs_fs_info *fs_info, +struct btrfs_delayed_ref_root *delayed_refs, +struct btrfs_delayed_ref_head *head);int btrfs_lookup_data_extent (struct btrfs_fs_info *fs_info,u64 start,u64 len); int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 bytenr,
fs/btrfs/disk-io.c +1 -0
@@ -4265,6 +4265,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,if (pin_bytes)btrfs_pin_extent (fs_info, head->bytenr, head->num_bytes,1 ); +btrfs_cleanup_ref_head_accounting (fs_info, delayed_refs, head);btrfs_put_delayed_ref_head (head);cond_resched ();spin_lock (&delayed_refs->lock);
fs/btrfs/extent-tree.c +5 -7
@@ -2456,12 +2456,10 @@ static int run_and_cleanup_extent_op(struct btrfs_trans_handle *trans,return ret ? ret :1 ; } -static void cleanup_ref_head_accounting (struct btrfs_trans_handle *trans, -struct btrfs_delayed_ref_head *head) +void btrfs_cleanup_ref_head_accounting (struct btrfs_fs_info *fs_info, +struct btrfs_delayed_ref_root *delayed_refs, +struct btrfs_delayed_ref_head *head) { -struct btrfs_fs_info *fs_info = trans->fs_info; -struct btrfs_delayed_ref_root *delayed_refs = - &trans->transaction->delayed_refs;int nr_items =1 ;/* Dropping this ref head update. */ if (head->total_ref_mod <0 ) {
@@ -2544,7 +2542,7 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans, } } -cleanup_ref_head_accounting (trans, head); +btrfs_cleanup_ref_head_accounting (fs_info, delayed_refs, head);trace_run_delayed_ref_head (fs_info, head,0 );btrfs_delayed_ref_unlock (head);
@@ -7188,7 +7186,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,if (head->must_insert_reserved) ret =1 ; -cleanup_ref_head_accounting (trans, head); +btrfs_cleanup_ref_head_accounting (trans->fs_info, delayed_refs, head);mutex_unlock (&head->mutex);btrfs_put_delayed_ref_head (head);return ret;