• J
    btrfs: fix lockdep splat in btrfs_recover_relocation · d26e08a4
    Josef Bacik 提交于
    stable inclusion
    from stable-5.10.11
    commit 14e17e90bfaaf0392d8a48744f91d81ea121fd10
    bugzilla: 47621
    
    --------------------------------
    
    commit fb286100 upstream.
    
    While testing the error paths of relocation I hit the following lockdep
    splat:
    
      ======================================================
      WARNING: possible circular locking dependency detected
      5.10.0-rc6+ #217 Not tainted
      ------------------------------------------------------
      mount/779 is trying to acquire lock:
      ffffa0e676945418 (&fs_info->balance_mutex){+.+.}-{3:3}, at: btrfs_recover_balance+0x2f0/0x340
    
      but task is already holding lock:
      ffffa0e60ee31da8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x27/0x100
    
      which lock already depends on the new lock.
    
      the existing dependency chain (in reverse order) is:
    
      -> #2 (btrfs-root-00){++++}-{3:3}:
    	 down_read_nested+0x43/0x130
    	 __btrfs_tree_read_lock+0x27/0x100
    	 btrfs_read_lock_root_node+0x31/0x40
    	 btrfs_search_slot+0x462/0x8f0
    	 btrfs_update_root+0x55/0x2b0
    	 btrfs_drop_snapshot+0x398/0x750
    	 clean_dirty_subvols+0xdf/0x120
    	 btrfs_recover_relocation+0x534/0x5a0
    	 btrfs_start_pre_rw_mount+0xcb/0x170
    	 open_ctree+0x151f/0x1726
    	 btrfs_mount_root.cold+0x12/0xea
    	 legacy_get_tree+0x30/0x50
    	 vfs_get_tree+0x28/0xc0
    	 vfs_kern_mount.part.0+0x71/0xb0
    	 btrfs_mount+0x10d/0x380
    	 legacy_get_tree+0x30/0x50
    	 vfs_get_tree+0x28/0xc0
    	 path_mount+0x433/0xc10
    	 __x64_sys_mount+0xe3/0x120
    	 do_syscall_64+0x33/0x40
    	 entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
      -> #1 (sb_internal#2){.+.+}-{0:0}:
    	 start_transaction+0x444/0x700
    	 insert_balance_item.isra.0+0x37/0x320
    	 btrfs_balance+0x354/0xf40
    	 btrfs_ioctl_balance+0x2cf/0x380
    	 __x64_sys_ioctl+0x83/0xb0
    	 do_syscall_64+0x33/0x40
    	 entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
      -> #0 (&fs_info->balance_mutex){+.+.}-{3:3}:
    	 __lock_acquire+0x1120/0x1e10
    	 lock_acquire+0x116/0x370
    	 __mutex_lock+0x7e/0x7b0
    	 btrfs_recover_balance+0x2f0/0x340
    	 open_ctree+0x1095/0x1726
    	 btrfs_mount_root.cold+0x12/0xea
    	 legacy_get_tree+0x30/0x50
    	 vfs_get_tree+0x28/0xc0
    	 vfs_kern_mount.part.0+0x71/0xb0
    	 btrfs_mount+0x10d/0x380
    	 legacy_get_tree+0x30/0x50
    	 vfs_get_tree+0x28/0xc0
    	 path_mount+0x433/0xc10
    	 __x64_sys_mount+0xe3/0x120
    	 do_syscall_64+0x33/0x40
    	 entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
      other info that might help us debug this:
    
      Chain exists of:
        &fs_info->balance_mutex --> sb_internal#2 --> btrfs-root-00
    
       Possible unsafe locking scenario:
    
    	 CPU0                    CPU1
    	 ----                    ----
        lock(btrfs-root-00);
    				 lock(sb_internal#2);
    				 lock(btrfs-root-00);
        lock(&fs_info->balance_mutex);
    
       *** DEADLOCK ***
    
      2 locks held by mount/779:
       #0: ffffa0e60dc040e0 (&type->s_umount_key#47/1){+.+.}-{3:3}, at: alloc_super+0xb5/0x380
       #1: ffffa0e60ee31da8 (btrfs-root-00){++++}-{3:3}, at: __btrfs_tree_read_lock+0x27/0x100
    
      stack backtrace:
      CPU: 0 PID: 779 Comm: mount Not tainted 5.10.0-rc6+ #217
      Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014
      Call Trace:
       dump_stack+0x8b/0xb0
       check_noncircular+0xcf/0xf0
       ? trace_call_bpf+0x139/0x260
       __lock_acquire+0x1120/0x1e10
       lock_acquire+0x116/0x370
       ? btrfs_recover_balance+0x2f0/0x340
       __mutex_lock+0x7e/0x7b0
       ? btrfs_recover_balance+0x2f0/0x340
       ? btrfs_recover_balance+0x2f0/0x340
       ? rcu_read_lock_sched_held+0x3f/0x80
       ? kmem_cache_alloc_trace+0x2c4/0x2f0
       ? btrfs_get_64+0x5e/0x100
       btrfs_recover_balance+0x2f0/0x340
       open_ctree+0x1095/0x1726
       btrfs_mount_root.cold+0x12/0xea
       ? rcu_read_lock_sched_held+0x3f/0x80
       legacy_get_tree+0x30/0x50
       vfs_get_tree+0x28/0xc0
       vfs_kern_mount.part.0+0x71/0xb0
       btrfs_mount+0x10d/0x380
       ? __kmalloc_track_caller+0x2f2/0x320
       legacy_get_tree+0x30/0x50
       vfs_get_tree+0x28/0xc0
       ? capable+0x3a/0x60
       path_mount+0x433/0xc10
       __x64_sys_mount+0xe3/0x120
       do_syscall_64+0x33/0x40
       entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    This is straightforward to fix, simply release the path before we setup
    the balance_ctl.
    
    CC: stable@vger.kernel.org # 4.4+
    Reviewed-by: NQu Wenruo <wqu@suse.com>
    Reviewed-by: NJohannes Thumshirn <johannes.thumshirn@wdc.com>
    Signed-off-by: NJosef Bacik <josef@toxicpanda.com>
    Reviewed-by: NDavid Sterba <dsterba@suse.com>
    Signed-off-by: NDavid Sterba <dsterba@suse.com>
    Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
    Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
    d26e08a4
volumes.c 205.2 KB