Skip to content

Commit ef67963

Browse files
josefbacikkdave
authored andcommitted
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 <[email protected]> Fixes: 8c38938 ("btrfs: move the root freeing stuff into btrfs_put_root") Reviewed-by: Nikolay Borisov <[email protected]> Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 5150bf1 commit ef67963

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

fs/btrfs/disk-io.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,9 +2036,6 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info)
20362036
for (i = 0; i < ret; i++)
20372037
btrfs_drop_and_free_fs_root(fs_info, gang[i]);
20382038
}
2039-
2040-
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
2041-
btrfs_free_log_root_tree(NULL, fs_info);
20422039
}
20432040

20442041
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,
38883885
spin_unlock(&fs_info->fs_roots_radix_lock);
38893886

38903887
if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
3891-
btrfs_free_log(NULL, root);
3888+
ASSERT(root->log_root == NULL);
38923889
if (root->reloc_root) {
38933890
btrfs_put_root(root->reloc_root);
38943891
root->reloc_root = NULL;
@@ -4211,6 +4208,36 @@ static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info)
42114208
up_write(&fs_info->cleanup_work_sem);
42124209
}
42134210

4211+
static void btrfs_drop_all_logs(struct btrfs_fs_info *fs_info)
4212+
{
4213+
struct btrfs_root *gang[8];
4214+
u64 root_objectid = 0;
4215+
int ret;
4216+
4217+
spin_lock(&fs_info->fs_roots_radix_lock);
4218+
while ((ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
4219+
(void **)gang, root_objectid,
4220+
ARRAY_SIZE(gang))) != 0) {
4221+
int i;
4222+
4223+
for (i = 0; i < ret; i++)
4224+
gang[i] = btrfs_grab_root(gang[i]);
4225+
spin_unlock(&fs_info->fs_roots_radix_lock);
4226+
4227+
for (i = 0; i < ret; i++) {
4228+
if (!gang[i])
4229+
continue;
4230+
root_objectid = gang[i]->root_key.objectid;
4231+
btrfs_free_log(NULL, gang[i]);
4232+
btrfs_put_root(gang[i]);
4233+
}
4234+
root_objectid++;
4235+
spin_lock(&fs_info->fs_roots_radix_lock);
4236+
}
4237+
spin_unlock(&fs_info->fs_roots_radix_lock);
4238+
btrfs_free_log_root_tree(NULL, fs_info);
4239+
}
4240+
42144241
static void btrfs_destroy_ordered_extents(struct btrfs_root *root)
42154242
{
42164243
struct btrfs_ordered_extent *ordered;
@@ -4603,6 +4630,7 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info)
46034630
btrfs_destroy_delayed_inodes(fs_info);
46044631
btrfs_assert_delayed_root_empty(fs_info);
46054632
btrfs_destroy_all_delalloc_inodes(fs_info);
4633+
btrfs_drop_all_logs(fs_info);
46064634
mutex_unlock(&fs_info->transaction_kthread_mutex);
46074635

46084636
return 0;

0 commit comments

Comments
 (0)