linux/fs
Theodore Ts'o 0e47bf3502 ext4: fix a potential deadlock in __ext4_es_shrink()
commit 3f1f9b8513 upstream.

This fixes the following lockdep complaint:

[ INFO: possible circular locking dependency detected ]
3.16.0-rc2-mm1+ #7 Tainted: G           O
-------------------------------------------------------
kworker/u24:0/4356 is trying to acquire lock:
 (&(&sbi->s_es_lru_lock)->rlock){+.+.-.}, at: [<ffffffff81285fff>] __ext4_es_shrink+0x4f/0x2e0

but task is already holding lock:
 (&ei->i_es_lock){++++-.}, at: [<ffffffff81286961>] ext4_es_insert_extent+0x71/0x180

which lock already depends on the new lock.

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(&ei->i_es_lock);
                               lock(&(&sbi->s_es_lru_lock)->rlock);
                               lock(&ei->i_es_lock);
  lock(&(&sbi->s_es_lru_lock)->rlock);

 *** DEADLOCK ***

6 locks held by kworker/u24:0/4356:
 #0:  ("writeback"){.+.+.+}, at: [<ffffffff81071d00>] process_one_work+0x180/0x560
 #1:  ((&(&wb->dwork)->work)){+.+.+.}, at: [<ffffffff81071d00>] process_one_work+0x180/0x560
 #2:  (&type->s_umount_key#22){++++++}, at: [<ffffffff811a9c74>] grab_super_passive+0x44/0x90
 #3:  (jbd2_handle){+.+...}, at: [<ffffffff812979f9>] start_this_handle+0x189/0x5f0
 #4:  (&ei->i_data_sem){++++..}, at: [<ffffffff81247062>] ext4_map_blocks+0x132/0x550
 #5:  (&ei->i_es_lock){++++-.}, at: [<ffffffff81286961>] ext4_es_insert_extent+0x71/0x180

stack backtrace:
CPU: 0 PID: 4356 Comm: kworker/u24:0 Tainted: G           O   3.16.0-rc2-mm1+ #7
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
Workqueue: writeback bdi_writeback_workfn (flush-253:0)
 ffffffff8213dce0 ffff880014b07538 ffffffff815df0bb 0000000000000007
 ffffffff8213e040 ffff880014b07588 ffffffff815db3dd ffff880014b07568
 ffff880014b07610 ffff88003b868930 ffff88003b868908 ffff88003b868930
Call Trace:
 [<ffffffff815df0bb>] dump_stack+0x4e/0x68
 [<ffffffff815db3dd>] print_circular_bug+0x1fb/0x20c
 [<ffffffff810a7a3e>] __lock_acquire+0x163e/0x1d00
 [<ffffffff815e89dc>] ? retint_restore_args+0xe/0xe
 [<ffffffff815ddc7b>] ? __slab_alloc+0x4a8/0x4ce
 [<ffffffff81285fff>] ? __ext4_es_shrink+0x4f/0x2e0
 [<ffffffff810a8707>] lock_acquire+0x87/0x120
 [<ffffffff81285fff>] ? __ext4_es_shrink+0x4f/0x2e0
 [<ffffffff8128592d>] ? ext4_es_free_extent+0x5d/0x70
 [<ffffffff815e6f09>] _raw_spin_lock+0x39/0x50
 [<ffffffff81285fff>] ? __ext4_es_shrink+0x4f/0x2e0
 [<ffffffff8119760b>] ? kmem_cache_alloc+0x18b/0x1a0
 [<ffffffff81285fff>] __ext4_es_shrink+0x4f/0x2e0
 [<ffffffff812869b8>] ext4_es_insert_extent+0xc8/0x180
 [<ffffffff812470f4>] ext4_map_blocks+0x1c4/0x550
 [<ffffffff8124c4c4>] ext4_writepages+0x6d4/0xd00
	...

Reported-by: Minchan Kim <minchan@kernel.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reported-by: Minchan Kim <minchan@kernel.org>
Cc: Zheng Liu <gnehzuil.liu@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-07-17 16:21:05 -07:00
..
9p Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2014-01-28 08:38:04 -08:00
adfs adfs: delayed freeing of sbi 2013-10-24 23:43:27 -04:00
affs fs/affs/super.c: bugfix / double free 2014-06-07 10:28:16 -07:00
afs afs: proc cells and rootcell are writeable 2014-02-01 10:59:39 -08:00
autofs4 autofs: fix lockref lookup 2014-06-07 10:28:20 -07:00
befs befs: iget_locked() doesn't return an ERR_PTR 2014-01-25 03:14:38 -05:00
bfs
btrfs btrfs: allocate raid type kobjects dynamically 2014-06-30 20:12:02 -07:00
cachefiles Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-11-13 15:34:18 +09:00
ceph ceph: clear directory's completeness when creating file 2014-06-07 10:28:20 -07:00
cifs CIFS: fix mount failure with broken pathnames when smb3 mount with mapchars option 2014-07-09 11:18:27 -07:00
coda coda_revalidate_inode(): switch to passing inode... 2013-11-09 00:16:21 -05:00
configfs configfs: fix race between dentry put and lookup 2013-11-21 16:42:27 -08:00
cramfs cramfs: take headers to fs/cramfs 2014-01-25 03:13:02 -05:00
debugfs debugfs: use list_next_entry() in debugfs_remove_recursive() 2013-11-13 12:09:24 +09:00
devpts devpts: plug the memory leak in kill_sb 2013-11-13 12:09:36 +09:00
dlm Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-01-25 11:17:34 -08:00
ecryptfs ecryptfs: fix failure handling in ->readlink() 2014-01-25 03:13:00 -05:00
efivarfs consolidate simple ->d_delete() instances 2013-11-15 22:04:17 -05:00
efs efs: get rid of ->put_super() 2014-01-25 03:13:02 -05:00
exofs exofs: Print less in r4w 2014-01-23 18:54:14 +02:00
exportfs exportfs: fix quadratic behavior in filehandle lookup 2013-11-09 00:16:38 -05:00
ext2 ext2/3/4: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
ext3 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2014-01-28 08:38:04 -08:00
ext4 ext4: fix a potential deadlock in __ext4_es_shrink() 2014-07-17 16:21:05 -07:00
f2fs Merge branch 'for-3.14/core' of git://git.kernel.dk/linux-block 2014-01-30 11:19:05 -08:00
fat fat: rcu-delay unloading nls and freeing sbi 2013-10-24 23:43:28 -04:00
freevxfs
fscache FS-Cache: Handle removal of unadded object to the fscache_object_list rb tree 2014-02-17 13:47:35 -08:00
fuse Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2014-01-28 08:38:04 -08:00
gfs2 Merge branch 'for-3.14/core' of git://git.kernel.dk/linux-block 2014-01-30 11:19:05 -08:00
hfs fs/hfs/btree.h: remove duplicate defines 2013-11-13 12:09:32 +09:00
hfsplus hfsplus: add HFSX subfolder count support 2014-03-10 17:26:21 -07:00
hostfs um: hostfs: make functions static 2014-01-26 11:51:09 +01:00
hpfs hpfs: optimize quad buffer loading 2014-02-02 16:24:07 -08:00
hppfs
hugetlbfs
isofs isofs: don't pass dentry to isofs_hash{i,}_common() 2013-10-24 23:34:59 -04:00
jbd jbd: Revise KERN_EMERG error messages 2013-12-04 12:27:46 +01:00
jbd2 ext4: disable synchronous transaction batching if max_batch_time==0 2014-07-17 16:21:05 -07:00
jffs2 jffs2: remove from wait queue after schedule() 2014-04-26 17:19:06 -07:00
jfs jfs: set i_ctime when setting ACL 2014-02-13 15:56:05 -06:00
kernfs kernfs: add back missing error check in kernfs_fop_mmap() 2014-06-07 10:28:08 -07:00
lockd lockd: ensure we tear down any live sockets when socket creation fails during lockd_up 2014-05-13 13:32:56 +02:00
logfs Merge branch 'for-3.14/core' of git://git.kernel.dk/linux-block 2014-01-30 11:19:05 -08:00
minix
ncpfs ncpfs: rcu-delay unload_nls() and freeing ncp_server 2013-10-24 23:43:28 -04:00
nfs nfs: Fix cache_validity check in nfs_write_pageuptodate() 2014-07-06 18:57:28 -07:00
nfs_common
nfsd nfsd: fix rare symlink decoding bug 2014-07-09 11:18:27 -07:00
nilfs2 Merge branch 'for-3.14/core' of git://git.kernel.dk/linux-block 2014-01-30 11:19:05 -08:00
nls nls: have register_nls() set ->owner 2014-01-25 03:14:05 -05:00
notify fsnotify: Allocate overflow events with proper type 2014-02-25 11:18:06 +01:00
ntfs fix O_SYNC|O_APPEND syncing the wrong range on write() 2014-02-09 15:18:09 -05:00
ocfs2 ocfs2: fix panic on kfree(xattr->name) 2014-05-06 07:59:36 -07:00
omfs
openpromfs
proc mm: add !pte_present() check on existing hugetlb_entry callbacks 2014-06-11 11:54:13 -07:00
pstore pstore: Don't allow high traffic options on fragile devices 2013-12-20 13:12:01 -08:00
qnx4 qnx4: clean qnx4_fill_super() up 2014-01-25 03:13:03 -05:00
qnx6
quota quota: Fix race between dqput() and dquot_scan_active() 2014-02-20 21:57:04 +01:00
ramfs fs/ramfs: move ramfs_aops to inode.c 2014-01-23 16:36:58 -08:00
reiserfs reiserfs: call truncate_setsize under tailpack mutex 2014-07-06 18:57:29 -07:00
romfs romfs: fix returm err while getting inode in fill_super 2014-01-23 16:37:04 -08:00
squashfs Squashfs: fix failure to unlock pages on decompress error 2013-11-24 01:02:50 +00:00
sysfs sysfs: make sure read buffer is zeroed 2014-06-07 10:28:24 -07:00
sysv
ubifs UBIFS: Remove incorrect assertion in shrink_tnc() 2014-07-06 18:57:26 -07:00
udf udf: Fix data corruption on file type conversion 2014-02-20 21:56:00 +01:00
ufs
xfs xfs: xfs_readsb needs to check for magic numbers 2014-07-06 18:57:28 -07:00
Kconfig fs: remove generic_acl 2014-01-26 08:26:40 -05:00
Kconfig.binfmt
Makefile Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2014-01-28 08:38:04 -08:00
aio.c aio: block io_destroy() until all context requests are completed 2014-07-09 11:18:28 -07:00
anon_inodes.c vfs: Allocate anon_inode_inode in anon_inode_init() 2014-03-27 09:52:54 -07:00
attr.c fs,userns: Change inode_capable to capable_wrt_inode_uidgid 2014-06-16 13:40:32 -07:00
bad_inode.c
binfmt_aout.c dump_skip(): dump_seek() replacement taking coredump_params 2013-11-09 00:16:26 -05:00
binfmt_elf.c fs: binfmt_elf: remove unused defines INTERPRETER_NONE and INTERPRETER_ELF 2014-01-23 16:36:58 -08:00
binfmt_elf_fdpic.c elf{,_fdpic} coredump: get rid of pointless if (siginfo->si_signo) 2013-11-09 00:16:30 -05:00
binfmt_em86.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
binfmt_som.c
bio-integrity.c bio-integrity: Drop bio_integrity_verify BUG_ON in post bip->bip_iter world 2014-02-21 15:56:36 -08:00
bio.c block: Fix cloning of discard/write same bios 2014-02-11 08:40:45 -07:00
block_dev.c
buffer.c mm: __set_page_dirty uses spin_lock_irqsave instead of spin_lock_irq 2014-02-06 13:48:51 -08:00
char_dev.c Merge branch 'for-3.13/core' of git://git.kernel.dk/linux-block 2013-11-14 12:08:14 +09:00
compat.c
compat_binfmt_elf.c
compat_ioctl.c fs/compat_ioctl.c: fix an underflow issue (harmless) 2014-01-21 16:19:42 -08:00
coredump.c coredump: fix va_list corruption 2014-06-07 10:28:08 -07:00
dcache.c fix races between __d_instantiate() and checks of dentry flags 2014-06-07 10:28:20 -07:00
dcookies.c fs/compat: fix lookup_dcookie() parameter handling 2014-01-29 16:22:40 -08:00
direct-io.c block: Abstract out bvec iterator 2013-11-23 22:33:47 -08:00
drop_caches.c
eventfd.c eventfd_ctx_fdget(): use fdget() instead of fget() 2014-01-25 03:13:04 -05:00
eventpoll.c epoll: fix use-after-free in eventpoll_release_file 2014-06-30 20:12:02 -07:00
exec.c metag: Reduce maximum stack size to 256MB 2014-06-07 10:28:23 -07:00
fcntl.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
fhandle.c
file.c vfs: Don't let __fdget_pos() get FMODE_PATH files 2014-03-23 00:03:12 -04:00
file_table.c don't bother with {get,put}_write_access() on non-regular files 2014-05-31 13:20:29 -07:00
filesystems.c
fs-writeback.c bdi: avoid oops on device removal 2014-04-26 17:19:05 -07:00
fs_struct.c seqcount: Add lockdep functionality to seqcount/seqlock structures 2013-11-06 12:40:26 +01:00
inode.c fs,userns: Change inode_capable to capable_wrt_inode_uidgid 2014-06-16 13:40:32 -07:00
internal.h get rid of s_files and files_lock 2013-11-09 00:16:20 -05:00
ioctl.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
ioprio.c
libfs.c consolidate simple ->d_delete() instances 2013-11-15 22:04:17 -05:00
locks.c locks: allow __break_lease to sleep even when break_time is 0 2014-05-13 13:32:53 +02:00
mbcache.c
mount.h switch mnt_hash to hlist 2014-03-30 19:18:51 -04:00
mpage.c block: Abstract out bvec iterator 2013-11-23 22:33:47 -08:00
namei.c fs,userns: Change inode_capable to capable_wrt_inode_uidgid 2014-06-16 13:40:32 -07:00
namespace.c smarter propagate_mnt() 2014-05-06 07:59:36 -07:00
no-block.c
open.c don't bother with {get,put}_write_access() on non-regular files 2014-05-31 13:20:29 -07:00
pipe.c fs/pipe.c: skip file_update_time on frozen fs 2014-01-23 16:37:00 -08:00
pnode.c smarter propagate_mnt() 2014-05-06 07:59:36 -07:00
pnode.h smarter propagate_mnt() 2014-05-06 07:59:36 -07:00
posix_acl.c posix_acl: handle NULL ACL in posix_acl_equiv_mode 2014-06-07 10:28:16 -07:00
proc_namespace.c fs/proc_namespace.c: simplify testing nsp and nsp->mnt_ns 2014-01-23 16:37:02 -08:00
read_write.c vfs: atomic f_pos access in llseek() 2014-03-23 00:03:12 -04:00
readdir.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
select.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-11-13 15:34:18 +09:00
seq_file.c seq_file: always clear m->count when we free m->buf 2013-11-18 19:07:53 -08:00
signalfd.c
splice.c fuse: fix pipe_buf_operations 2014-01-22 19:36:57 +01:00
stack.c
stat.c vfs: split out vfs_getattr_nosec 2013-11-09 00:16:31 -05:00
statfs.c
super.c fs: Don't return 0 from get_anon_bdev 2014-05-31 13:20:31 -07:00
sync.c Revert "writeback: do not sync data dirtied after sync start" 2014-02-22 02:02:28 +01:00
timerfd.c
utimes.c locks: break delegations on any attribute modification 2013-11-09 00:16:44 -05:00
xattr.c