• David Sterba's avatar
    btrfs: clean up pending block groups when transaction commit aborts · c7cc64a9
    David Sterba authored
    The fstests generic/475 stresses transaction aborts and can reveal
    space accounting or use-after-free bugs regarding block goups.
    
    In this case the pending block groups that remain linked to the
    structures after transaction commit aborts in the middle.
    
    The corrupted slabs lead to failures in following tests, eg. generic/476
    
      [ 8172.752887] BUG: unable to handle kernel NULL pointer dereference at 0000000000000058
      [ 8172.755799] #PF error: [normal kernel read fault]
      [ 8172.757571] PGD 661ae067 P4D 661ae067 PUD 3db8e067 PMD 0
      [ 8172.759000] Oops: 0000 [#1] PREEMPT SMP
      [ 8172.760209] CPU: 0 PID: 39 Comm: kswapd0 Tainted: G        W         5.0.0-rc2-default #408
      [ 8172.762495] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.2-0-gf9626cc-prebuilt.qemu-project.org 04/01/2014
      [ 8172.765772] RIP: 0010:shrink_page_list+0x2f9/0xe90
      [ 8172.770453] RSP: 0018:ffff967f00663b18 EFLAGS: 00010287
      [ 8172.771184] RAX: 0000000000000000 RBX: ffff967f00663c20 RCX: 0000000000000000
      [ 8172.772850] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8c0620ab20e0
      [ 8172.774629] RBP: ffff967f00663dd8 R08: 0000000000000000 R09: 0000000000000000
      [ 8172.776094] R10: ffff8c0620ab22f8 R11: ffff8c063f772688 R12: ffff967f00663b78
      [ 8172.777533] R13: ffff8c063f625600 R14: ffff8c063f625608 R15: dead000000000200
      [ 8172.778886] FS:  0000000000000000(0000) GS:ffff8c063d400000(0000) knlGS:0000000000000000
      [ 8172.780545] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [ 8172.781787] CR2: 0000000000000058 CR3: 000000004e962000 CR4: 00000000000006f0
      [ 8172.783547] Call Trace:
      [ 8172.784112]  shrink_inactive_list+0x194/0x410
      [ 8172.784747]  shrink_node_memcg.constprop.85+0x3a5/0x6a0
      [ 8172.785472]  shrink_node+0x62/0x1e0
      [ 8172.786011]  balance_pgdat+0x216/0x460
      [ 8172.786577]  kswapd+0xe3/0x4a0
      [ 8172.787085]  ? finish_wait+0x80/0x80
      [ 8172.787795]  ? balance_pgdat+0x460/0x460
      [ 8172.788799]  kthread+0x116/0x130
      [ 8172.789640]  ? kthread_create_on_node+0x60/0x60
      [ 8172.790323]  ret_from_fork+0x24/0x30
      [ 8172.794253] CR2: 0000000000000058
    
    or accounting errors at umount time:
    
      [ 8159.537251] WARNING: CPU: 2 PID: 19031 at fs/btrfs/extent-tree.c:5987 btrfs_free_block_groups+0x3d5/0x410 [btrfs]
      [ 8159.543325] CPU: 2 PID: 19031 Comm: umount Tainted: G        W         5.0.0-rc2-default #408
      [ 8159.545472] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.11.2-0-gf9626cc-prebuilt.qemu-project.org 04/01/2014
      [ 8159.548155] RIP: 0010:btrfs_free_block_groups+0x3d5/0x410 [btrfs]
      [ 8159.554030] RSP: 0018:ffff967f079cbde8 EFLAGS: 00010206
      [ 8159.555144] RAX: 0000000001000000 RBX: ffff8c06366cf800 RCX: 0000000000000000
      [ 8159.556730] RDX: 0000000000000002 RSI: 0000000000000001 RDI: ffff8c06255ad800
      [ 8159.558279] RBP: ffff8c0637ac0000 R08: 0000000000000001 R09: 0000000000000000
      [ 8159.559797] R10: 0000000000000000 R11: 0000000000000001 R12: ffff8c0637ac0108
      [ 8159.561296] R13: ffff8c0637ac0158 R14: 0000000000000000 R15: dead000000000100
      [ 8159.562852] FS:  00007f7f693b9fc0(0000) GS:ffff8c063d800000(0000) knlGS:0000000000000000
      [ 8159.564839] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [ 8159.566160] CR2: 00007f7f68fab7b0 CR3: 000000000aec7000 CR4: 00000000000006e0
      [ 8159.567898] Call Trace:
      [ 8159.568597]  close_ctree+0x17f/0x350 [btrfs]
      [ 8159.569628]  generic_shutdown_super+0x64/0x100
      [ 8159.570808]  kill_anon_super+0x14/0x30
      [ 8159.571857]  btrfs_kill_super+0x12/0xa0 [btrfs]
      [ 8159.573063]  deactivate_locked_super+0x29/0x60
      [ 8159.574234]  cleanup_mnt+0x3b/0x70
      [ 8159.575176]  task_work_run+0x98/0xc0
      [ 8159.576177]  exit_to_usermode_loop+0x83/0x90
      [ 8159.577315]  do_syscall_64+0x15b/0x180
      [ 8159.578339]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
    
    This fix is based on 2 Josef's patches that used sideefects of
    btrfs_create_pending_block_groups, this fix introduces the helper that
    does what we need.
    
    CC: stable@vger.kernel.org # 4.4+
    CC: Josef Bacik <josef@toxicpanda.com>
    Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    c7cc64a9
transaction.c 64.9 KB