Star64_linux/fs
J. Bruce Fields d891eedbc3 fs/dcache: allow d_obtain_alias() to return unhashed dentries
Without this patch, inodes are not promptly freed on last close of an
unlinked file by an nfs client:

	client$ mount -tnfs4 server:/export/ /mnt/
	client$ tail -f /mnt/FOO
	...
	server$ df -i /export
	server$ rm /export/FOO
	(^C the tail -f)
	server$ df -i /export
	server$ echo 2 >/proc/sys/vm/drop_caches
	server$ df -i /export

the df's will show that the inode is not freed on the filesystem until
the last step, when it could have been freed after killing the client's
tail -f. On-disk data won't be deallocated either, leading to possible
spurious ENOSPC.

This occurs because when the client does the close, it arrives in a
compound with a putfh and a close, processed like:

	- putfh: look up the filehandle.  The only alias found for the
	  inode will be DCACHE_UNHASHED alias referenced by the filp
	  this, so it creates a new DCACHE_DISCONECTED dentry and
	  returns that instead.
	- close: closes the existing filp, which is destroyed
	  immediately by dput() since it's DCACHE_UNHASHED.
	- end of the compound: release the reference
	  to the current filehandle, and dput() the new
	  DCACHE_DISCONECTED dentry, which gets put on the
	  unused list instead of being destroyed immediately.

Nick Piggin suggested fixing this by allowing d_obtain_alias to return
the unhashed dentry that is referenced by the filp, instead of making it
create a new dentry.

Leave __d_find_alias() alone to avoid changing behavior of other
callers.

Also nfsd doesn't need all the checks of __d_find_alias(); any dentry,
hashed or unhashed, disconnected or not, should work.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2011-03-10 05:18:54 -05:00
..
9p
adfs
affs
afs afs: Fix oops in afs_unlink_writeback 2011-02-25 11:12:37 -08:00
autofs4
befs
bfs
btrfs Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable 2011-02-25 14:03:39 -08:00
cachefiles
ceph ceph: fix d_revalidate oopsen on NFS exports 2011-03-10 03:44:05 -05:00
cifs [CIFS] update cifs version 2011-02-21 22:31:47 +00:00
coda
configfs
cramfs
debugfs
devpts
dlm
ecryptfs eCryptfs: Copy up lower inode attrs in getattr 2011-02-21 14:46:36 -06:00
efs
exofs exofs: i_nlink races in rename() 2011-03-03 01:28:17 -05:00
exportfs
ext2 ext2: Fix link count corruption under heavy link+rename load 2011-03-02 11:03:52 +01:00
ext3
ext4
fat fat: fix d_revalidate oopsen on NFS exports 2011-03-10 03:45:49 -05:00
freevxfs
fscache
fuse fuse: fix d_revalidate oopsen on NFS exports 2011-03-10 03:44:31 -05:00
gfs2 gfs2: fix d_revalidate oopsen on NFS exports 2011-03-10 03:44:48 -05:00
hfs hfs: fix rename() over non-empty directory 2011-03-03 01:28:40 -05:00
hfsplus
hostfs
hpfs
hppfs
hugetlbfs
isofs
jbd
jbd2
jffs2
jfs jfs: fix d_revalidate oopsen on NFS exports 2011-03-10 03:45:28 -05:00
lockd
logfs
minix minix: i_nlink races in rename() 2011-03-03 01:28:16 -05:00
ncpfs
nfs nfs4: Ensure that ACL pages sent over NFS were not allocated from the slab (v3) 2011-03-04 17:28:52 -08:00
nfs_common
nfsd nfsd: wrong index used in inner loop 2011-03-08 19:46:10 -05:00
nilfs2 Merge branch 'i_nlink' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2011-03-03 15:37:59 -08:00
nls
notify
ntfs
ocfs2 ocfs2: fix d_revalidate oopsen on NFS exports 2011-03-10 03:45:07 -05:00
omfs
openpromfs
partitions ldm: corrupted partition table can cause kernel oops 2011-02-25 15:07:36 -08:00
proc /proc/self is never going to be invalidated... 2011-03-10 03:41:53 -05:00
qnx4
quota
ramfs
reiserfs reiserfs xattr ->d_revalidate() shouldn't care about RCU 2011-03-10 03:42:01 -05:00
romfs
squashfs
sysfs
sysv sysv: i_nlink races in rename() 2011-03-03 01:28:16 -05:00
ubifs
udf udf: fix i_nlink limit 2011-03-03 01:28:40 -05:00
ufs ufs: i_nlink races in rename() 2011-03-03 01:28:16 -05:00
xfs xfs: zero proper structure size for geometry calls 2011-03-01 21:21:13 -06:00
aio.c aio: fix race between io_destroy() and io_submit() 2011-02-25 15:07:37 -08:00
anon_inodes.c
attr.c
bad_inode.c
binfmt_aout.c
binfmt_elf.c
binfmt_elf_fdpic.c
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
binfmt_som.c
bio-integrity.c
bio.c
block_dev.c fs/block_dev.c: fix new kernel-doc warning 2011-02-28 18:08:31 -08:00
buffer.c
char_dev.c
compat.c
compat_binfmt_elf.c
compat_ioctl.c
dcache.c fs/dcache: allow d_obtain_alias() to return unhashed dentries 2011-03-10 05:18:54 -05:00
dcookies.c
direct-io.c
drop_caches.c
eventfd.c Docbook: add fs/eventfd.c and fix typos in it 2011-02-21 15:07:04 -08:00
eventpoll.c epoll: prevent creating circular epoll structures 2011-02-25 15:07:36 -08:00
exec.c
fcntl.c
fifo.c
file.c
file_table.c
filesystems.c
fs-writeback.c
fs_struct.c
generic_acl.c
inode.c Merge branch 'for-linus' of git://neil.brown.name/md 2011-02-25 11:13:26 -08:00
internal.h Fix over-zealous flush_disk when changing device size. 2011-02-24 17:25:47 +11:00
ioctl.c
ioprio.c
Kconfig
Kconfig.binfmt
libfs.c
locks.c
Makefile
mbcache.c
mpage.c
namei.c nd->inode is not set on the second attempt in path_walk() 2011-03-08 21:16:28 -05:00
namespace.c Unlock vfsmount_lock in do_umount 2011-02-24 02:10:57 -05:00
nfsctl.c
no-block.c
open.c Check for immutable/append flag in fallocate path 2011-03-10 04:22:15 -05:00
pipe.c
pnode.c
pnode.h
posix_acl.c
read_write.c
read_write.h
readdir.c
select.c
seq_file.c
signalfd.c
splice.c
stack.c
stat.c
statfs.c
super.c
sync.c
timerfd.c
utimes.c
xattr.c
xattr_acl.c