summaryrefslogtreecommitdiffstats
path: root/0001-btrfs-drop-logs-when-we-ve-aborted-a-transaction.patch
diff options
context:
space:
mode:
Diffstat (limited to '0001-btrfs-drop-logs-when-we-ve-aborted-a-transaction.patch')
-rw-r--r--0001-btrfs-drop-logs-when-we-ve-aborted-a-transaction.patch150
1 files changed, 150 insertions, 0 deletions
diff --git a/0001-btrfs-drop-logs-when-we-ve-aborted-a-transaction.patch b/0001-btrfs-drop-logs-when-we-ve-aborted-a-transaction.patch
new file mode 100644
index 000000000..797cd956e
--- /dev/null
+++ b/0001-btrfs-drop-logs-when-we-ve-aborted-a-transaction.patch
@@ -0,0 +1,150 @@
+From ef67963dac255b293e19815ea3d440567be4626f Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Tue, 24 Mar 2020 10:47:52 -0400
+Subject: [PATCH] btrfs: drop logs when we've aborted a transaction
+
+Dave reported a problem where we were panicing with generic/475 with
+misc-5.7. This is because we were doing IO after we had stopped all of
+the worker threads, because we do the log tree cleanup on roots at drop
+time. Cleaning up the log tree will always need to do reads if we
+happened to have evicted the blocks from memory.
+
+Because of this simply add a helper to btrfs_cleanup_transaction() that
+will go through and drop all of the log roots. This gets run before we
+do the close_ctree() work, and thus we are allowed to do any reads that
+we would need. I ran this through many iterations of generic/475 with
+constrained memory and I did not see the issue.
+
+ general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6b6b: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI
+ CPU: 2 PID: 12359 Comm: umount Tainted: G W 5.6.0-rc7-btrfs-next-58 #1
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:btrfs_queue_work+0x33/0x1c0 [btrfs]
+ RSP: 0018:ffff9cfb015937d8 EFLAGS: 00010246
+ RAX: 0000000000000000 RBX: ffff8eb5e339ed80 RCX: 0000000000000000
+ RDX: 0000000000000001 RSI: ffff8eb5eb33b770 RDI: ffff8eb5e37a0460
+ RBP: ffff8eb5eb33b770 R08: 000000000000020c R09: ffffffff9fc09ac0
+ R10: 0000000000000007 R11: 0000000000000000 R12: 6b6b6b6b6b6b6b6b
+ R13: ffff9cfb00229040 R14: 0000000000000008 R15: ffff8eb5d3868000
+ FS: 00007f167ea022c0(0000) GS:ffff8eb5fae00000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f167e5e0cb1 CR3: 0000000138c18004 CR4: 00000000003606e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+ btrfs_end_bio+0x81/0x130 [btrfs]
+ __split_and_process_bio+0xaf/0x4e0 [dm_mod]
+ ? percpu_counter_add_batch+0xa3/0x120
+ dm_process_bio+0x98/0x290 [dm_mod]
+ ? generic_make_request+0xfb/0x410
+ dm_make_request+0x4d/0x120 [dm_mod]
+ ? generic_make_request+0xfb/0x410
+ generic_make_request+0x12a/0x410
+ ? submit_bio+0x38/0x160
+ submit_bio+0x38/0x160
+ ? percpu_counter_add_batch+0xa3/0x120
+ btrfs_map_bio+0x289/0x570 [btrfs]
+ ? kmem_cache_alloc+0x24d/0x300
+ btree_submit_bio_hook+0x79/0xc0 [btrfs]
+ submit_one_bio+0x31/0x50 [btrfs]
+ read_extent_buffer_pages+0x2fe/0x450 [btrfs]
+ btree_read_extent_buffer_pages+0x7e/0x170 [btrfs]
+ walk_down_log_tree+0x343/0x690 [btrfs]
+ ? walk_log_tree+0x3d/0x380 [btrfs]
+ walk_log_tree+0xf7/0x380 [btrfs]
+ ? plist_requeue+0xf0/0xf0
+ ? delete_node+0x4b/0x230
+ free_log_tree+0x4c/0x130 [btrfs]
+ ? wait_log_commit+0x140/0x140 [btrfs]
+ btrfs_free_log+0x17/0x30 [btrfs]
+ btrfs_drop_and_free_fs_root+0xb0/0xd0 [btrfs]
+ btrfs_free_fs_roots+0x10c/0x190 [btrfs]
+ ? do_raw_spin_unlock+0x49/0xc0
+ ? _raw_spin_unlock+0x29/0x40
+ ? release_extent_buffer+0x121/0x170 [btrfs]
+ close_ctree+0x289/0x2e6 [btrfs]
+ generic_shutdown_super+0x6c/0x110
+ kill_anon_super+0xe/0x30
+ btrfs_kill_super+0x12/0x20 [btrfs]
+ deactivate_locked_super+0x3a/0x70
+
+Reported-by: David Sterba <dsterba@suse.com>
+Fixes: 8c38938c7bb096 ("btrfs: move the root freeing stuff into btrfs_put_root")
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/disk-io.c | 36 ++++++++++++++++++++++++++++++++----
+ 1 file changed, 32 insertions(+), 4 deletions(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index a6cb5cbbdb9f..d10c7be10f3b 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2036,9 +2036,6 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info)
+ for (i = 0; i < ret; i++)
+ btrfs_drop_and_free_fs_root(fs_info, gang[i]);
+ }
+-
+- if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
+- btrfs_free_log_root_tree(NULL, fs_info);
+ }
+
+ static void btrfs_init_scrub(struct btrfs_fs_info *fs_info)
+@@ -3888,7 +3885,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
+ spin_unlock(&fs_info->fs_roots_radix_lock);
+
+ if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
+- btrfs_free_log(NULL, root);
++ ASSERT(root->log_root == NULL);
+ if (root->reloc_root) {
+ btrfs_put_root(root->reloc_root);
+ root->reloc_root = NULL;
+@@ -4211,6 +4208,36 @@ static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info)
+ up_write(&fs_info->cleanup_work_sem);
+ }
+
++static void btrfs_drop_all_logs(struct btrfs_fs_info *fs_info)
++{
++ struct btrfs_root *gang[8];
++ u64 root_objectid = 0;
++ int ret;
++
++ spin_lock(&fs_info->fs_roots_radix_lock);
++ while ((ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
++ (void **)gang, root_objectid,
++ ARRAY_SIZE(gang))) != 0) {
++ int i;
++
++ for (i = 0; i < ret; i++)
++ gang[i] = btrfs_grab_root(gang[i]);
++ spin_unlock(&fs_info->fs_roots_radix_lock);
++
++ for (i = 0; i < ret; i++) {
++ if (!gang[i])
++ continue;
++ root_objectid = gang[i]->root_key.objectid;
++ btrfs_free_log(NULL, gang[i]);
++ btrfs_put_root(gang[i]);
++ }
++ root_objectid++;
++ spin_lock(&fs_info->fs_roots_radix_lock);
++ }
++ spin_unlock(&fs_info->fs_roots_radix_lock);
++ btrfs_free_log_root_tree(NULL, fs_info);
++}
++
+ static void btrfs_destroy_ordered_extents(struct btrfs_root *root)
+ {
+ struct btrfs_ordered_extent *ordered;
+@@ -4603,6 +4630,7 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info)
+ btrfs_destroy_delayed_inodes(fs_info);
+ btrfs_assert_delayed_root_empty(fs_info);
+ btrfs_destroy_all_delalloc_inodes(fs_info);
++ btrfs_drop_all_logs(fs_info);
+ mutex_unlock(&fs_info->transaction_kthread_mutex);
+
+ return 0;
+--
+2.26.2
+