1
linux/fs
Anton Altaparmakov ba6d2377c8 NTFS: Fix a nasty deadlock that appeared in recent kernels.
The situation: VFS inode X on a mounted ntfs volume is dirty.  For
      same inode X, the ntfs_inode is dirty and thus corresponding on-disk
      inode, i.e. mft record, which is in a dirty PAGE_CACHE_PAGE belonging
      to the table of inodes, i.e. $MFT, inode 0.
      What happens:
      Process 1: sys_sync()/umount()/whatever...  calls
      __sync_single_inode() for $MFT -> do_writepages() -> write_page for
      the dirty page containing the on-disk inode X, the page is now locked
      -> ntfs_write_mst_block() which clears PageUptodate() on the page to
      prevent anyone else getting hold of it whilst it does the write out.
      This is necessary as the on-disk inode needs "fixups" applied before
      the write to disk which are removed again after the write and
      PageUptodate is then set again.  It then analyses the page looking
      for dirty on-disk inodes and when it finds one it calls
      ntfs_may_write_mft_record() to see if it is safe to write this
      on-disk inode.  This then calls ilookup5() to check if the
      corresponding VFS inode is in icache().  This in turn calls ifind()
      which waits on the inode lock via wait_on_inode whilst holding the
      global inode_lock.
      Process 2: pdflush results in a call to __sync_single_inode for the
      same VFS inode X on the ntfs volume.  This locks the inode (I_LOCK)
      then calls write-inode -> ntfs_write_inode -> map_mft_record() ->
      read_cache_page() for the page (in page cache of table of inodes
      $MFT, inode 0) containing the on-disk inode.  This page has
      PageUptodate() clear because of Process 1 (see above) so
      read_cache_page() blocks when it tries to take the page lock for the
      page so it can call ntfs_read_page().
      Thus Process 1 is holding the page lock on the page containing the
      on-disk inode X and it is waiting on the inode X to be unlocked in
      ifind() so it can write the page out and then unlock the page.
      And Process 2 is holding the inode lock on inode X and is waiting for
      the page to be unlocked so it can call ntfs_readpage() or discover
      that Process 1 set PageUptodate() again and use the page.
      Thus we have a deadlock due to ifind() waiting on the inode lock.
      The solution: The fix is to use the newly introduced
      ilookup5_nowait() which does not wait on the inode's lock and hence
      avoids the deadlock.  This is safe as we do not care about the VFS
      inode and only use the fact that it is in the VFS inode cache and the
      fact that the vfs and ntfs inodes are one struct in memory to find
      the ntfs inode in memory if present.  Also, the ntfs inode has its
      own locking so it does not matter if the vfs inode is locked.

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
2005-06-26 22:12:02 +01:00
..
adfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
affs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
afs [PATCH] Exterminate PAGE_BUG 2005-05-01 08:59:01 -07:00
autofs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
autofs4 [PATCH] autofs4: bad lookup fix 2005-06-21 19:07:35 -07:00
befs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
cifs [CIFS] Fix cifs update of page cache. Write at correct offset when out of memory 2005-06-09 14:44:07 -07:00
coda [PATCH] class: convert the remaining class_simple users in the kernel to usee the new class api 2005-06-20 15:15:11 -07:00
cramfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
debugfs [PATCH] remove duplicate get_dentry functions in various places 2005-06-23 09:45:20 -07:00
devfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
devpts Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
efs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
exportfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ext2 [PATCH] xip: reduce code duplication 2005-06-24 00:06:41 -07:00
ext3 [PATCH] quota: ext3: Improve quota credit estimates 2005-06-24 00:05:20 -07:00
fat Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
freevxfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hfs [PATCH] hfs, hfsplus: don't leak s_fs_info and fix an oops 2005-05-01 08:59:16 -07:00
hfsplus [PATCH] hfs, hfsplus: don't leak s_fs_info and fix an oops 2005-05-01 08:59:16 -07:00
hostfs [PATCH] uml: remove 2_5compat.h 2005-05-28 16:46:11 -07:00
hpfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hppfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
hugetlbfs [PATCH] Avoiding mmap fragmentation 2005-06-21 18:46:16 -07:00
isofs [PATCH] isofs: show hidden files, add granularity for assoc/hidden files flags 2005-06-21 19:07:38 -07:00
jbd [PATCH] ext3: fix list scanning in __cleanup_transaction 2005-06-02 15:12:29 -07:00
jffs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
jffs2 [PATCH] make some things static 2005-05-05 16:36:47 -07:00
jfs [PATCH] remove <linux/xattr_acl.h> 2005-06-23 09:45:33 -07:00
lockd [PATCH] knfsd: lockd: flush signals on shutdown 2005-06-24 00:06:30 -07:00
minix Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
msdos Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
ncpfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
nfs [PATCH] Remove f_error field from struct file 2005-06-23 09:45:33 -07:00
nfs_common [PATCH] NFSD: Add server support for NFSv3 ACLs. 2005-06-22 16:07:23 -04:00
nfsd [PATCH] knfsd: nfsd4 reboot dirname fix 2005-06-24 00:06:36 -07:00
nls [PATCH] make some things static 2005-05-05 16:36:47 -07:00
ntfs NTFS: Fix a nasty deadlock that appeared in recent kernels. 2005-06-26 22:12:02 +01:00
openpromfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
partitions [PATCH] revert msdos partitioning fix 2005-05-06 22:09:27 -07:00
proc [PATCH] setuid core dump 2005-06-23 09:45:26 -07:00
qnx4 [PATCH] fs/qnx4/*: fix sparse warnings 2005-06-24 14:14:24 -07:00
ramfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
reiserfs [PATCH] make various thing static 2005-06-24 00:06:43 -07:00
romfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
smbfs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
sysfs [PATCH] DocBook: update comments 2005-06-24 00:06:40 -07:00
sysv Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
udf [PATCH] UDF filesystem: array '__mon_yday' declared as not static 2005-05-31 14:54:18 -07:00
ufs Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
umsdos Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
vfat Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
xfs [PATCH] pass iocb to dio_iodone_t 2005-06-24 00:05:19 -07:00
aio.c [PATCH] aio: optimize io_submit_one() 2005-05-01 08:59:16 -07:00
attr.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bad_inode.c [PATCH] make some things static 2005-05-05 16:36:47 -07:00
binfmt_aout.c [PATCH] Avoiding mmap fragmentation 2005-06-21 18:46:16 -07:00
binfmt_elf_fdpic.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
binfmt_elf.c [PATCH] Avoiding mmap fragmentation 2005-06-21 18:46:16 -07:00
binfmt_em86.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
binfmt_flat.c [PATCH] binfmt_flat mmap flag fix 2005-06-06 14:57:51 -07:00
binfmt_misc.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
binfmt_script.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
binfmt_som.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
bio.c [PATCH] DocBook: fix some descriptions 2005-05-01 08:59:26 -07:00
block_dev.c [PATCH] block: add unlocked_ioctl support for block devices 2005-06-23 09:45:32 -07:00
buffer.c [PATCH] Bug in error recovery in fs/buffer.c::__block_prepare_write() 2005-06-23 09:45:34 -07:00
char_dev.c [PATCH] add check to /proc/devices read routines 2005-06-23 09:45:19 -07:00
compat_ioctl.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
compat.c [PATCH] NFS4: Don't use __user with compat_uptr_t 2005-04-27 15:39:03 -07:00
dcache.c [PATCH] make some things static 2005-05-05 16:36:47 -07:00
dcookies.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
direct-io.c [PATCH] pass iocb to dio_iodone_t 2005-06-24 00:05:19 -07:00
dnotify.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
dquot.c [PATCH] quota: sanitize dentry handling in vfs_quota_on_mount 2005-06-23 09:45:20 -07:00
eventpoll.c [PATCH] Remove eventpoll macro obfuscation 2005-06-23 09:45:30 -07:00
exec.c [PATCH] setuid core dump 2005-06-23 09:45:26 -07:00
fcntl.c [PATCH] convert that currently tests _NSIG directly to use valid_signal() 2005-05-01 08:59:14 -07:00
fifo.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
file_table.c [PATCH] Fix of bogus file max limit messages 2005-06-23 09:45:26 -07:00
file.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
filesystems.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
fs-writeback.c [PATCH] O(1) sb list traversing on syncs 2005-06-23 09:45:27 -07:00
inode.c [PATCH] fix for prune_icache()/forced final iput() races 2005-06-23 09:45:17 -07:00
ioctl.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
Kconfig [PATCH] xip: ext2: execute in place 2005-06-24 00:06:41 -07:00
Kconfig.binfmt Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
libfs.c [PATCH] libfs: add simple attribute files 2005-06-20 15:15:30 -07:00
locks.c [PATCH] VFS: Ensure that all the on-stack struct file_lock call fl_release_private 2005-06-22 16:07:40 -04:00
Makefile [PATCH] NFSD: Add server support for NFSv3 ACLs. 2005-06-22 16:07:23 -04:00
mbcache.c [PATCH] make some things static 2005-05-05 16:36:47 -07:00
mpage.c [PATCH] mpage_end_io_write() I/O error handling fix 2005-06-04 17:12:59 -07:00
namei.c [PATCH] add some comments to lookup_create() 2005-06-23 09:45:26 -07:00
namespace.c [PATCH] make various thing static 2005-06-24 00:06:43 -07:00
nfsctl.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
open.c [PATCH] xip: fs/mm: execute in place 2005-06-24 00:06:41 -07:00
pipe.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
posix_acl.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
quota_v1.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
quota_v2.c [PATCH] quota: possible bug in quota format v2 support 2005-04-16 15:25:47 -07:00
quota.c [PATCH] O(1) sb list traversing on syncs 2005-06-23 09:45:27 -07:00
read_write.c [PATCH] aio: fix do_sync_(read|write) to properly handle aio retries 2005-06-23 09:45:34 -07:00
readdir.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
select.c [PATCH] make some things static 2005-05-05 16:36:47 -07:00
seq_file.c [PATCH] DocBook: fix some descriptions 2005-05-01 08:59:26 -07:00
stat.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
super.c [PATCH] O(1) sb list traversing on syncs 2005-06-23 09:45:27 -07:00
xattr_acl.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00
xattr.c Linux-2.6.12-rc2 2005-04-16 15:20:36 -07:00