kernel-fxtec-pro1x/fs
J. Bruce Fields 7632e465fe dcache: use IS_ROOT to decide where dentry is hashed
Every hashed dentry is either hashed in the dentry_hashtable, or a
superblock's s_anon list.

__d_drop() assumes it can determine which is the case by checking
DCACHE_DISCONNECTED; this is not true.

It is true that when DCACHE_DISCONNECTED is cleared, the dentry is not
only hashed on dentry_hashtable, but is fully connected to its parents
back to the root.

But the converse is *not* true: fs/exportfs/expfs.c:reconnect_path()
attempts to connect a directory (found by filehandle lookup) back to
root by ascending to parents and performing lookups one at a time.  It
does not clear DCACHE_DISCONNECTED until it's done, and that is not at
all an atomic process.

In particular, it is possible for DCACHE_DISCONNECTED to be set on a
dentry which is hashed on the dentry_hashtable.

Instead, use IS_ROOT() to check which hash chain a dentry is on.  This
*does* work:

Dentries are hashed only by:

	- d_obtain_alias, which adds an IS_ROOT() dentry to sb_anon.

	- __d_rehash, called by _d_rehash: hashes to the dentry's
	  parent, and all callers of _d_rehash appear to have d_parent
	  set to a "real" parent.
	- __d_rehash, called by __d_move: rehashes the moved dentry to
	  hash chain determined by target, and assigns target's d_parent
	  to its d_parent, before dropping the dentry's d_lock.

Therefore I believe it's safe for a holder of a dentry's d_lock to
assume that it is hashed on sb_anon if and only if IS_ROOT(dentry) is
true.

I believe the incorrect assumption about DCACHE_DISCONNECTED was
originally introduced by ceb5bdc2d2 "fs: dcache per-bucket dcache hash
locking".

Also add a comment while we're here.

Cc: Nick Piggin <npiggin@kernel.dk>
Acked-by: Christoph Hellwig <hch@infradead.org>
Reviewed-by: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2013-11-09 00:16:33 -05:00
..
9p 9p: make v9fs_cache_inode_{get,put,set}_cookie empty inlines for !9P_CACHEFS 2013-10-24 23:34:47 -04:00
adfs adfs: delayed freeing of sbi 2013-10-24 23:43:27 -04:00
affs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
afs afs: dget_parent() can't return a negative dentry 2013-09-29 22:02:24 -04:00
autofs4 autofs4: make freeing sbi rcu-delayed 2013-10-24 23:43:27 -04:00
befs befs: split symlink iops in two - for short and long symlinks resp. 2013-10-24 23:34:50 -04:00
bfs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
btrfs btrfs: Fix crash due to not allocating integrity data for a bioset 2013-10-05 10:52:10 -04:00
cachefiles CacheFiles: Don't try to dump the index key if the cookie has been cleared 2013-09-20 15:15:43 -07:00
ceph ceph: use d_invalidate() to invalidate aliases 2013-09-06 12:55:29 -07:00
cifs cifs: rcu-delay unload_nls() and freeing sbi 2013-10-24 23:43:27 -04:00
coda coda_revalidate_inode(): switch to passing inode... 2013-11-09 00:16:21 -05:00
configfs
cramfs
debugfs
devpts
dlm
ecryptfs file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
efivarfs
efs efs: iget_locked() doesn't return an ERR_PTR() 2013-08-24 12:10:22 -04:00
exofs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
exportfs exportfs: fix 32-bit nfsd handling of 64-bit inode numbers 2013-11-09 00:16:32 -05:00
ext2 truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
ext3 Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs 2013-09-06 09:06:02 -07:00
ext4 Merge branch 'akpm' (patches from Andrew Morton) 2013-09-12 15:44:27 -07:00
f2fs f2fs: optimize gc for better performance 2013-09-05 13:50:32 +09:00
fat fat: rcu-delay unloading nls and freeing sbi 2013-10-24 23:43:28 -04:00
freevxfs
fscache Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client 2013-09-19 12:50:37 -05:00
fuse fuse: rcu-delay freeing fuse_conn 2013-10-24 23:45:13 -04:00
gfs2 new helper: kfree_put_link() 2013-10-24 23:34:49 -04:00
hfs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
hfsplus truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
hostfs um: hostfs: Fix writeback 2013-09-07 10:38:29 +02:00
hpfs hpfs: make freeing sbi and codetables rcu-delayed 2013-10-24 23:43:26 -04:00
hppfs
hugetlbfs cope with potentially long ->d_dname() output for shmem/hugetlb 2013-08-24 12:10:17 -04:00
isofs isofs: don't pass dentry to isofs_hash{i,}_common() 2013-10-24 23:34:59 -04:00
jbd
jbd2 jbd2: Fix endian mixing problems in the checksumming code 2013-08-28 14:59:58 -04:00
jffs2
jfs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
lockd
logfs
minix truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
ncpfs ncpfs: rcu-delay unload_nls() and freeing ncp_server 2013-10-24 23:43:28 -04:00
nfs nfs: use %p[dD] instead of open-coded (and often racy) equivalents 2013-10-24 23:34:50 -04:00
nfs_common
nfsd nfsd: switch to %p[dD] 2013-10-24 23:34:51 -04:00
nilfs2 nilfs2: fix issue with race condition of competition between segments for dirty blocks 2013-09-30 14:31:02 -07:00
nls
notify
ntfs iget/iget5: don't bother with ->i_lock until we find a match 2013-11-09 00:16:31 -05:00
ocfs2 ocfs2: get rid of impossible checks 2013-11-09 00:16:32 -05:00
omfs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
openpromfs
proc new helper: kfree_put_link() 2013-10-24 23:34:49 -04:00
pstore pstore: Remove the messages related to compression failure 2013-09-16 09:28:29 -07:00
qnx4 qnx4: i_sb is never NULL 2013-11-09 00:16:32 -05:00
qnx6
quota fs: convert fs shrinkers to new scan/count API 2013-09-10 18:56:31 -04:00
ramfs initmpfs: move rootfs code from fs/ramfs/ to init/ 2013-09-11 15:59:37 -07:00
reiserfs reiserfs: fix race with flush_used_journal_lists and flush_journal_list 2013-09-24 11:24:21 +02:00
romfs
squashfs Squashfs: add corruption check for type in squashfs_readdir() 2013-09-06 04:57:54 +01:00
sysfs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-09-07 14:36:57 -07:00
sysv sysv: Add forgotten superblock lock init for v7 fs 2013-09-29 22:02:02 -04:00
ubifs ubifs: switch to %pd 2013-10-24 23:34:51 -04:00
udf udf: Fortify LVID loading 2013-09-24 11:23:33 +02:00
ufs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
xfs xfs: Use kmem_free() instead of free() 2013-10-04 13:56:12 -05:00
aio.c rework aio migrate pages to use aio fs 2013-11-09 00:16:28 -05:00
anon_inodes.c ... and kill anon_inode_getfile_private() 2013-11-09 00:16:28 -05:00
attr.c
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 elf{,_fdpic} coredump: get rid of pointless if (siginfo->si_signo) 2013-11-09 00:16:30 -05: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 Merge branch 'for-3.12/core' of git://git.kernel.dk/linux-block 2013-09-22 15:00:11 -07:00
bio.c block: Fix bio_copy_data() 2013-09-24 14:41:42 -07:00
block_dev.c a trivial writeback fix 2013-09-13 23:06:40 -04:00
buffer.c
char_dev.c consolidate the reassignments of ->f_op in ->open() instances 2013-10-24 23:34:53 -04:00
compat.c
compat_binfmt_elf.c
compat_ioctl.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
coredump.c constify do_coredump() argument 2013-11-09 00:16:29 -05:00
coredump.h
dcache.c dcache: use IS_ROOT to decide where dentry is hashed 2013-11-09 00:16:33 -05:00
dcookies.c
direct-io.c direct-io: Use return from cmpxchg to decide of assignment happened 2013-09-09 10:47:42 -07:00
drop_caches.c shrinker: add node awareness 2013-09-10 18:56:31 -04:00
eventfd.c
eventpoll.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
exec.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
fcntl.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
fhandle.c
file.c
file_table.c get rid of s_files and files_lock 2013-11-09 00:16:20 -05:00
filesystems.c
fs-writeback.c new helpers: lock_mount_hash/unlock_mount_hash 2013-10-24 23:34:59 -04:00
fs_struct.c
generic_acl.c
inode.c iget/iget5: don't bother with ->i_lock until we find a match 2013-11-09 00:16:31 -05: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
Kconfig
Kconfig.binfmt
libfs.c take anon inode allocation to libfs.c 2013-11-09 00:16:27 -05:00
locks.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
Makefile
mbcache.c fs: convert fs shrinkers to new scan/count API 2013-09-10 18:56:31 -04:00
mount.h RCU'd vfsmounts 2013-11-09 00:16:19 -05:00
mpage.c
namei.c VFS: Put a small type field into struct dentry::d_flags 2013-11-09 00:16:30 -05:00
namespace.c RCU'd vfsmounts 2013-11-09 00:16:19 -05:00
no-block.c
open.c get rid of s_files and files_lock 2013-11-09 00:16:20 -05:00
pipe.c
pnode.c split __lookup_mnt() in two functions 2013-10-24 23:35:00 -04:00
pnode.h vfs: Don't copy mount bind mounts of /proc/<pid>/ns/mnt between namespaces 2013-08-26 18:42:15 -07:00
posix_acl.c
proc_namespace.c don't bother with vfsmount_lock in mounts_poll() 2013-10-24 23:34:59 -04:00
read_write.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
readdir.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
select.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
seq_file.c
signalfd.c
splice.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
stack.c
stat.c vfs: split out vfs_getattr_nosec 2013-11-09 00:16:31 -05:00
statfs.c
super.c get rid of s_files and files_lock 2013-11-09 00:16:20 -05:00
sync.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
timerfd.c
utimes.c
xattr.c
xattr_acl.c