linux-stable/fs/btrfs
Anand Jain 48b3b9d401 btrfs: fix lock dep warning move scratch super outside of chunk_mutex
Move scratch super outside of the chunk lock to avoid below
lockdep warning. The better place to scratch super is in
the function btrfs_rm_dev_replace_free_srcdev() just before
free_device, which is outside of the chunk lock as well.

To reproduce:
  (fresh boot)
  mkfs.btrfs -f -draid5 -mraid5 /dev/sdc /dev/sdd /dev/sde
  mount /dev/sdc /btrfs
  dd if=/dev/zero of=/btrfs/tf1 bs=4096 count=100
  (get devmgt from https://github.com/asj/devmgt.git)
  devmgt detach /dev/sde
  dd if=/dev/zero of=/btrfs/tf1 bs=4096 count=100
  sync
  btrfs replace start -Brf 3 /dev/sdf /btrfs <--
  devmgt attach host7

======================================================
[ INFO: possible circular locking dependency detected ]
4.6.0-rc2asj+ #1 Not tainted
---------------------------------------------------

btrfs/2174 is trying to acquire lock:
(sb_writers){.+.+.+}, at:
[<ffffffff812449b4>] __sb_start_write+0xb4/0xf0

but task is already holding lock:
(&fs_info->chunk_mutex){+.+.+.}, at:
[<ffffffffa05c5f55>] btrfs_dev_replace_finishing+0x145/0x980 [btrfs]

which lock already depends on the new lock.

Chain exists of:
sb_writers --> &fs_devs->device_list_mutex --> &fs_info->chunk_mutex
Possible unsafe locking scenario:
CPU0				CPU1
----				----
lock(&fs_info->chunk_mutex);
				lock(&fs_devs->device_list_mutex);
				lock(&fs_info->chunk_mutex);
lock(sb_writers);

*** DEADLOCK ***

-> #0 (sb_writers){.+.+.+}:
[<ffffffff810e6415>] __lock_acquire+0x1bc5/0x1ee0
[<ffffffff810e707e>] lock_acquire+0xbe/0x210
[<ffffffff810df49a>] percpu_down_read+0x4a/0xa0
[<ffffffff812449b4>] __sb_start_write+0xb4/0xf0
[<ffffffff81265534>] mnt_want_write+0x24/0x50
[<ffffffff812508a2>] path_openat+0x952/0x1190
[<ffffffff81252451>] do_filp_open+0x91/0x100
[<ffffffff8123f5cc>] file_open_name+0xfc/0x140
[<ffffffff8123f643>] filp_open+0x33/0x60
[<ffffffffa0572bb6>] update_dev_time+0x16/0x40 [btrfs]
[<ffffffffa057f60d>] btrfs_scratch_superblocks+0x5d/0xb0 [btrfs]
[<ffffffffa057f70e>] btrfs_rm_dev_replace_remove_srcdev+0xae/0xd0 [btrfs]
[<ffffffffa05c62c5>] btrfs_dev_replace_finishing+0x4b5/0x980 [btrfs]
[<ffffffffa05c6ae8>] btrfs_dev_replace_start+0x358/0x530 [btrfs]

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2016-05-06 15:22:49 +02:00
..
tests mm, fs: remove remaining PAGE_CACHE_* and page_cache_{get,release} usage 2016-04-04 10:41:08 -07:00
acl.c
async-thread.c
async-thread.h
backref.c
backref.h
btrfs_inode.h
check-integrity.c mm, fs: remove remaining PAGE_CACHE_* and page_cache_{get,release} usage 2016-04-04 10:41:08 -07:00
check-integrity.h
compression.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
compression.h
ctree.c
ctree.h btrfs: bugfix: handle FS_IOC32_{GETFLAGS,SETFLAGS,GETVERSION} in btrfs_ioctl 2016-04-28 10:40:27 +02:00
delayed-inode.c
delayed-inode.h
delayed-ref.c
delayed-ref.h
dev-replace.c
dev-replace.h
dir-item.c
disk-io.c Merge branch 'PAGE_CACHE_SIZE-removal' 2016-04-04 10:50:24 -07:00
disk-io.h
export.c
export.h
extent-tree.c Merge branch 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2016-04-09 10:41:34 -07:00
extent_io.c Btrfs: cleanup error handling in extent_write_cached_pages 2016-04-28 10:41:47 +02:00
extent_io.h mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
extent_map.c
extent_map.h
file-item.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
file.c Btrfs: __btrfs_buffered_write: Pass valid file offset when releasing delalloc space 2016-04-28 10:41:47 +02:00
free-space-cache.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
free-space-cache.h
free-space-tree.c
free-space-tree.h
hash.c
hash.h
inode-item.c
inode-map.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
inode-map.h
inode.c btrfs: bugfix: handle FS_IOC32_{GETFLAGS,SETFLAGS,GETVERSION} in btrfs_ioctl 2016-04-28 10:40:27 +02:00
ioctl.c btrfs: use dynamic allocation for root item in create_subvol 2016-05-06 15:22:49 +02:00
Kconfig
locking.c
locking.h
lzo.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
Makefile
math.h
ordered-data.c
ordered-data.h
orphan.c
print-tree.c
print-tree.h
props.c
props.h
qgroup.c
qgroup.h
raid56.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
raid56.h
rcu-string.h
reada.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00
relocation.c Merge branch 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2016-04-09 10:41:34 -07:00
root-tree.c
scrub.c btrfs: Fix BUG_ON condition in scrub_setup_recheck_block() 2016-05-06 15:22:49 +02:00
send.c btrfs: send: use vmalloc only as fallback for clone_sources_tmp 2016-05-06 15:22:49 +02:00
send.h
struct-funcs.c mm, fs: remove remaining PAGE_CACHE_* and page_cache_{get,release} usage 2016-04-04 10:41:08 -07:00
super.c btrfs: avoid overflowing f_bfree 2016-05-06 15:22:49 +02:00
sysfs.c btrfs: sysfs: protect reading label by lock 2016-05-06 15:22:49 +02:00
sysfs.h
transaction.c
transaction.h
tree-defrag.c
tree-log.c Btrfs: fix file/data loss caused by fsync after rename and new inode 2016-04-06 17:01:44 -07:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c
volumes.c btrfs: fix lock dep warning move scratch super outside of chunk_mutex 2016-05-06 15:22:49 +02:00
volumes.h Btrfs: fix divide error upon chunk's stripe_len 2016-05-06 15:22:49 +02:00
xattr.c
xattr.h
zlib.c mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros 2016-04-04 10:41:08 -07:00