From dd82525956744c3a5e6b7275cd468b6180cc5b72 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 1 Apr 2015 08:36:05 -0700 Subject: Btrfs: free and unlock our path before btrfs_free_and_pin_reserved_extent() The error handling path for alloc_reserved_tree_block is calling btrfs_free_and_pin_reserved_extent with a spinning tree lock held. This might sleep as we allocate extent_state objects: BUG: sleeping function called from invalid context at mm/slub.c:1268 in_atomic(): 1, irqs_disabled(): 0, pid: 11093, name: kworker/u4:7 5 locks held by kworker/u4:7/11093: #0: ("%s-%s""btrfs", name){++++.+}, at: [] process_one_work+0x151/0x520 #1: ((&work->normal_work)){+.+.+.}, at: [] process_one_work+0x151/0x520 #2: (sb_internal){++++.+}, at: [] start_transaction+0x43e/0x590 [btrfs] #3: (&head_ref->mutex){+.+...}, at: [] btrfs_delayed_ref_lock+0x4c/0x240 [btrfs] #4: (btrfs-extent-00){++++..}, at: [] btrfs_clear_lock_blocking_rw+0x9b/0x150 [btrfs] CPU: 0 PID: 11093 Comm: kworker/u4:7 Tainted: G W 4.0.0-rc6-default+ #246 Hardware name: Intel Corporation Santa Rosa platform/Matanzas, BIOS TSRSCRB1.86C.0047.B00.0610170821 10/17/06 Workqueue: btrfs-extent-refs btrfs_extent_refs_helper [btrfs] 00000000000004f4 ffff88006dd17848 ffffffff81ab0e3b ffff88006dd17848 ffff88007a944760 ffff88006dd17868 ffffffff8109d516 ffff88006dd17898 0000000000000000 ffff88006dd17898 ffffffff8109d5b2 ffffffff81aba2bb Call Trace: [] dump_stack+0x4f/0x6c [] ___might_sleep+0xf6/0x140 [] __might_sleep+0x52/0x90 [] ? ftrace_call+0x5/0x34 [] kmem_cache_alloc+0x163/0x1b0 [] ? alloc_extent_state+0x31/0x150 [btrfs] [] ? alloc_extent_state+0x20/0x150 [btrfs] [] alloc_extent_state+0x31/0x150 [btrfs] [] __set_extent_bit+0x37b/0x5d0 [btrfs] [] ? ftrace_call+0x5/0x34 [] ? set_extent_bit+0xd/0x30 [btrfs] [] set_extent_bit+0x23/0x30 [btrfs] [] set_extent_dirty+0x20/0x30 [btrfs] [] pin_down_extent+0xaa/0x170 [btrfs] [] __btrfs_free_reserved_extent+0xcf/0x160 [btrfs] [] btrfs_free_and_pin_reserved_extent+0x16/0x20 [btrfs] [] __btrfs_run_delayed_refs+0xfca/0x1290 [btrfs] [] btrfs_run_delayed_refs+0x6e/0x2e0 [btrfs] [] delayed_ref_async_start+0x48/0xb0 [btrfs] [] normal_work_helper+0x83/0x350 [btrfs] [] ? btrfs_extent_refs_helper+0x9/0x20 [btrfs] [] btrfs_extent_refs_helper+0x12/0x20 [btrfs] [] process_one_work+0x1cb/0x520 [] ? process_one_work+0x151/0x520 [] ? seq_read+0x3f/0x400 [] worker_thread+0x5b/0x4e0 [] ? __kthread_parkme+0x12/0xa0 [] ? rescuer_thread+0x450/0x450 [] kthread+0xf6/0x120 [] ? flush_kthread_worker+0x1b0/0x1b0 [] ret_from_fork+0x58/0x90 [] ? flush_kthread_worker+0x1b0/0x1b0 ------------[ cut here ]------------ This changes things to free the path first, which will also unlock the extent buffer. Signed-off-by: Chris Mason Reported-by: Dave Sterba Tested-by: Dave Sterba --- fs/btrfs/extent-tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/btrfs/extent-tree.c') diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 62fa6049e5b6..41e5812c131f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -7093,9 +7093,9 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, ins, size); if (ret) { + btrfs_free_path(path); btrfs_free_and_pin_reserved_extent(root, ins->objectid, root->nodesize); - btrfs_free_path(path); return ret; } -- cgit v1.2.3