linux/fs/ext4
Jan Kara 487caeef9f ext4: Fix possible deadlock between ext4_truncate() and ext4_get_blocks()
During truncate we are sometimes forced to start a new transaction as
the amount of blocks to be journaled is both quite large and hard to
predict. So far we restarted a transaction while holding i_data_sem
and that violates lock ordering because i_data_sem ranks below a
transaction start (and it can lead to a real deadlock with
ext4_get_blocks() mapping blocks in some page while having a
transaction open).

We fix the problem by dropping the i_data_sem before restarting the
transaction and acquire it afterwards. It's slightly subtle that this
works:

1) By the time ext4_truncate() is called, all the page cache for the
truncated part of the file is dropped so get_block() should not be
called on it (we only have to invalidate extent cache after we
reacquire i_data_sem because some extent from not-truncated part could
extend also into the part we are going to truncate).

2) Writes, migrate or defrag hold i_mutex so they are stopped for all
the time of the truncate.

This bug has been found and analyzed by Theodore Tso <tytso@mit.edu>.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2009-08-17 22:17:20 -04:00
..
acl.c ext[234]: move over to 'check_acl' permission model 2009-09-08 11:09:04 -07:00
acl.h ext[234]: move over to 'check_acl' permission model 2009-09-08 11:09:04 -07:00
balloc.c ext4: Convert ext4_lock_group to use sb_bgl_lock 2009-05-02 20:35:09 -04:00
bitmap.c ext4: Change unsigned long to unsigned int 2008-11-05 00:14:04 -05:00
block_validity.c ext4: Add a comprehensive block validity check to ext4_get_blocks() 2009-05-17 15:38:01 -04:00
dir.c ext4: Define a new set of flags for ext4_get_blocks() 2009-05-14 00:58:52 -04:00
ext4_extents.h ext4: Show unwritten extent flag in ext4_ext_show_leaf() 2009-09-18 13:34:55 -04:00
ext4_jbd2.c ext4: Fix buffer head reference leak in no-journal mode 2009-07-13 09:07:20 -04:00
ext4_jbd2.h ext4: Fix buffer head reference leak in no-journal mode 2009-07-13 09:07:20 -04:00
ext4.h ext4: Fix possible deadlock between ext4_truncate() and ext4_get_blocks() 2009-08-17 22:17:20 -04:00
extents.c ext4: Fix possible deadlock between ext4_truncate() and ext4_get_blocks() 2009-08-17 22:17:20 -04:00
file.c ext4: Remove syncing logic from ext4_file_write 2009-09-14 17:08:16 +02:00
fsync.c ext4: convert instrumentation from markers to tracepoints 2009-06-17 11:48:11 -04:00
hash.c ext4: Add support for non-native signed/unsigned htree hash algorithms 2008-10-28 13:21:44 -04:00
ialloc.c ext4: fix build warning when EXT4FS_DEBUG is on 2009-07-27 21:44:40 -04:00
inode.c ext4: Fix possible deadlock between ext4_truncate() and ext4_get_blocks() 2009-08-17 22:17:20 -04:00
ioctl.c Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4 2009-07-13 16:39:25 -07:00
Kconfig ext4: Add configurable run-time mballoc debugging 2009-09-18 13:38:55 -04:00
Makefile ext4: online defrag -- Add EXT4_IOC_MOVE_EXT ioctl 2009-06-17 19:24:03 -04:00
mballoc.c ext4: Avoid group preallocation for closed files 2009-09-18 13:34:02 -04:00
mballoc.h ext4: Add configurable run-time mballoc debugging 2009-09-18 13:38:55 -04:00
migrate.c ext4: teach the inode allocator to use a goal inode number 2009-06-13 11:45:35 -04:00
move_extent.c ext4: fix journal ref count in move_extent_par_page 2009-08-10 23:05:28 -04:00
namei.c ext4: More buffer head reference leaks 2009-07-17 10:54:08 -04:00
resize.c block: rename CONFIG_LBD to CONFIG_LBDAF 2009-06-19 08:08:50 +02:00
super.c ext4: Avoid null pointer dereference when decoding EROFS w/o a journal 2009-07-27 23:09:47 -04:00
symlink.c ext4: Rename ext4dev to ext4 2008-10-10 20:02:48 -04:00
xattr_security.c ext4: move headers out of include/linux 2008-04-29 18:13:32 -04:00
xattr_trusted.c ext4: remove double definitions of xattr macros 2008-07-11 19:27:31 -04:00
xattr_user.c ext4: remove double definitions of xattr macros 2008-07-11 19:27:31 -04:00
xattr.c ext4: Use lowercase names of quota functions 2009-03-26 02:18:36 +01:00
xattr.h ext4: Rename ext4dev to ext4 2008-10-10 20:02:48 -04:00