linux/fs
Filipe Manana 85e0a0f21a Btrfs: remove unnecessary locking of cleaner_mutex to avoid deadlock
After commmit e44163e177 ("btrfs: explictly delete unused block groups
in close_ctree and ro-remount"), added in the 4.3 merge window, we have
calls to btrfs_delete_unused_bgs() while holding the cleaner_mutex.
This can cause a deadlock with a concurrent block group relocation (when
a filesystem balance or shrink operation is in progress for example)
because btrfs_delete_unused_bgs() locks delete_unused_bgs_mutex and the
relocation path locks first delete_unused_bgs_mutex and then it locks
cleaner_mutex, resulting in a classic ABBA deadlock:

         CPU 0                                        CPU 1

lock fs_info->cleaner_mutex

                                           __btrfs_balance() || btrfs_shrink_device()
                                             lock fs_info->delete_unused_bgs_mutex
                                             btrfs_relocate_chunk()
                                               btrfs_relocate_block_group()
                                                 lock fs_info->cleaner_mutex
btrfs_delete_unused_bgs()
  lock fs_info->delete_unused_bgs_mutex

Fix this by not taking the cleaner_mutex before calling
btrfs_delete_unused_bgs() because it's no longer needed after
commit 67c5e7d464 ("Btrfs: fix race between balance and unused block
group deletion"). The mutex fs_info->delete_unused_bgs_mutex, the
spinlock fs_info->unused_bgs_lock and a block group's spinlock are
enough to get correct serialization between tasks running relocation
and unused block group deletion (as well as between multiple tasks
concurrently calling btrfs_delete_unused_bgs()).

This issue was discussed (in the mailing list) during the review of
the patch titled "btrfs: explictly delete unused block groups in
close_ctree and ro-remount" and it was agreed that acquiring the
cleaner mutex had to be dropped after the patch titled
"Btrfs: fix race between balance and unused block group deletion"
got merged (both patches were submitted at about the same time, but
one landed in kernel 4.2 and the other in the 4.3 merge window).

Signed-off-by: Filipe Manana <fdmanana@suse.com>
2015-09-10 11:27:57 +01:00
..
9p 9p: don't leave a half-initialized inode sitting around 2015-07-12 11:22:05 -04:00
adfs fs/adfs: remove unneeded cast 2015-06-30 19:44:57 -07:00
affs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
afs
autofs4 make simple_positive() public 2015-06-23 18:02:01 -04:00
befs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
bfs
btrfs Btrfs: remove unnecessary locking of cleaner_mutex to avoid deadlock 2015-09-10 11:27:57 +01:00
cachefiles Merge branch 'fscache-fixes' into for-next 2015-06-23 18:01:30 -04:00
ceph Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
cifs cifs: Unset CIFS_MOUNT_POSIX_PATHS flag when following dfs mounts 2015-06-29 14:50:22 -05:00
coda fs: cleanup slight list_entry abuse 2015-06-23 18:01:59 -04:00
configfs configfs: fix kernel infoleak through user-controlled format string 2015-07-17 16:39:53 -07:00
cramfs
debugfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
devpts devpts: if initialization failed, don't crash when opening /dev/ptmx 2015-06-30 19:44:58 -07:00
dlm
ecryptfs ioctl_compat: handle FITRIM 2015-07-09 11:42:21 -07:00
efivarfs
efs fs/efs: femove unneeded cast 2015-06-25 17:00:42 -07:00
exofs pagemap.h: move dir_pages() over there 2015-06-23 18:02:00 -04:00
exportfs
ext2 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
ext3 Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs 2015-06-24 20:07:10 -07:00
ext4 ioctl_compat: handle FITRIM 2015-07-09 11:42:21 -07:00
f2fs f2fs: call set_page_dirty to attach i_wb for cgroup 2015-07-25 08:54:26 -07:00
fat writeback: separate out include/linux/backing-dev-defs.h 2015-06-02 08:33:34 -06:00
freevxfs pagemap.h: move dir_pages() over there 2015-06-23 18:02:00 -04:00
fscache
fuse Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
gfs2 GFS2: merge window 2015-06-27 09:47:46 -07:00
hfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
hfsplus Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
hostfs Merge branch 'for-linus-1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-06-22 12:51:21 -07:00
hpfs hpfs: hpfs_error: Remove static buffer, use vsprintf extension %pV instead 2015-07-09 13:35:31 -07:00
hugetlbfs mm/hugetlb: reduce arch dependent code about hugetlb_prefault_arch_hook 2015-06-24 17:49:41 -07:00
isofs
jbd
jbd2 Revert "jbd2: speedup jbd2_journal_dirty_metadata()" 2015-06-27 09:41:50 -07:00
jffs2 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
jfs A couple trivial fixes and an error path fix 2015-07-16 16:28:28 -07:00
kernfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2015-07-03 15:20:57 -07:00
lockd
logfs
minix Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
ncpfs ncpfs: successful rename() should invalidate caches for parents 2015-06-14 11:31:39 -04:00
nfs NFS client bugfixes for Linux 4.2 2015-07-28 09:37:44 -07:00
nfs_common
nfsd nfsd: wrap too long lines in nfsd4_encode_read 2015-06-22 14:15:05 -04:00
nilfs2 ioctl_compat: handle FITRIM 2015-07-09 11:42:21 -07:00
nls
notify Revert "fsnotify: fix oops in fsnotify_clear_marks_by_group_flags()" 2015-07-21 16:06:53 -07:00
ntfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
ocfs2 ioctl_compat: handle FITRIM 2015-07-09 11:42:21 -07:00
omfs omfs: fix potential integer overflow in allocator 2015-05-28 18:25:19 -07:00
openpromfs
overlayfs fix a braino in ovl_d_select_inode() 2015-07-12 11:22:05 -04:00
proc Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2015-07-18 10:49:57 -07:00
pstore Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2015-07-03 15:20:57 -07:00
qnx4
qnx6 pagemap.h: move dir_pages() over there 2015-06-23 18:02:00 -04:00
quota
ramfs
reiserfs Merge branch 'akpm' (patches from Andrew) 2015-06-26 09:52:05 -07:00
romfs
squashfs fs: cleanup slight list_entry abuse 2015-06-23 18:01:59 -04:00
sysfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2015-07-03 15:20:57 -07:00
sysv pagemap.h: move dir_pages() over there 2015-06-23 18:02:00 -04:00
tracefs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
ubifs This pull request includes the following UBI/UBIFS changes: 2015-06-25 14:11:34 -07:00
udf udf: Don't corrupt unalloc spacetable when writing it 2015-07-09 16:38:57 +02:00
ufs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
xfs xfs: remote attributes need to be considered data 2015-07-29 11:48:02 +10:00
aio.c
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf_fdpic.c
binfmt_elf.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
block_dev.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
buffer.c buffer: remove unusued 'ret' variable 2015-06-02 09:22:34 -06:00
char_dev.c
compat_binfmt_elf.c
compat_ioctl.c ioctl_compat: handle FITRIM 2015-07-09 11:42:21 -07:00
compat.c
coredump.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
dax.c xfs: call dax_fault on read page faults for DAX 2015-07-29 11:48:00 +10:00
dcache.c freeing unlinked file indefinitely delayed 2015-07-12 11:27:04 -04:00
dcookies.c
direct-io.c
drop_caches.c
eventfd.c
eventpoll.c
exec.c
fcntl.c
fhandle.c vfs: read file_handle only once in handle_to_path 2015-06-02 10:29:07 -07:00
file_table.c remove the pointless include of lglock.h 2015-06-23 18:02:00 -04:00
file.c fs/file.c: __fget() and dup2() atomicity rules 2015-07-01 02:31:08 -04:00
filesystems.c
fs_pin.c
fs_struct.c
fs-writeback.c block: export bio_associate_*() and wbc_account_io() 2015-07-23 13:36:44 -06:00
inode.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
internal.h overlayfs: Make f_path always point to the overlay and f_inode to the underlay 2015-06-19 03:19:32 -04:00
ioctl.c
Kconfig
Kconfig.binfmt
libfs.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
locks.c locks: inline posix_lock_file_wait and flock_lock_file_wait 2015-07-13 06:29:11 -04:00
Makefile um: Remove hppfs 2015-05-31 13:23:08 +02:00
mbcache.c
mount.h fs: use seq_open_private() for proc_mounts 2015-06-30 19:44:56 -07:00
mpage.c writeback: implement foreign cgroup inode detection 2015-06-02 08:40:20 -06:00
namei.c link_path_walk(): be careful when failing with ENOTDIR 2015-08-01 20:18:38 -04:00
namespace.c mnt: In detach_mounts detach the appropriate unmounted mount 2015-07-23 11:31:15 -05:00
no-block.c
nsfs.c
open.c fs: Call security_ops->inode_killpriv on truncate 2015-06-23 18:01:09 -04:00
pipe.c
pnode.c
pnode.h mnt: Clarify and correct the disconnect logic in umount_tree 2015-07-22 20:33:27 -05:00
posix_acl.c fs/posix_acl.c: make posix_acl_create() safer and cleaner 2015-06-23 18:01:07 -04:00
proc_namespace.c fs: use seq_open_private() for proc_mounts 2015-06-30 19:44:56 -07:00
read_write.c
readdir.c
select.c
seq_file.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2015-07-04 19:36:06 -07:00
signalfd.c
splice.c Merge branch 'akpm' (patches from Andrew) 2015-06-24 20:47:21 -07:00
stack.c
stat.c
statfs.c
super.c fs:super:get_anon_bdev: fix race condition could cause dev exceed its upper limitation 2015-07-01 01:50:06 -04:00
sync.c
timerfd.c
utimes.c
xattr.c