linux/fs
Jeff Layton d2224e7afb nfs: close NFSv4 COMMIT vs. CLOSE race
I've been adding in more artificial delays in the NFSv4 commit and close
codepaths to uncover races. The kernel I'm testing has the patch to
close the race in __rpc_wait_for_completion_task that's in Trond's
cthon2011 branch. The reproducer I've been using does this in a loop:

	mkdir("DIR");
	fd = open("DIR/FILE", O_WRONLY|O_CREAT|O_EXCL, 0644);
	write(fd, "abcdefg", 7);
	close(fd);
	unlink("DIR/FILE");
	rmdir("DIR");

The above reproducer shouldn't result in any silly-renaming. However,
when I add a "msleep(100)" just after the nfs_commit_clear_lock call in
nfs_commit_release, I can almost always force one to occur. If I can
force it to occur with that, then it can happen without that delay
given the right timing.

nfs_commit_inode waits for the NFS_INO_COMMIT bit to clear when called
with FLUSH_SYNC set. nfs_commit_rpcsetup on the other hand does not wait
for the task to complete before putting its reference to it, so the last
reference get put in rpc_release task and gets queued to a workqueue.

In this situation, the last open context reference may be put by the
COMMIT release instead of the close() syscall. The close() syscall
returns too quickly and the unlink runs while the d_count is still
high since the COMMIT release hasn't put its dentry reference yet.

Fix this by having rpc_commit_rpcsetup wait for the RPC call to complete
before putting the task reference when FLUSH_SYNC is set. With this, the
last reference is put by the process that's initiating the FLUSH_SYNC
commit and the race is closed.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
2011-03-10 15:04:53 -05:00
..
9p switch 9p 2011-01-12 20:03:43 -05:00
adfs switch adfs 2011-01-12 20:02:45 -05:00
affs switch affs 2011-01-12 20:03:42 -05:00
afs afs: Fix oops in afs_unlink_writeback 2011-02-25 11:12:37 -08:00
autofs4 autofs4: clean ->d_release() and autofs4_free_ino() up 2011-01-18 01:21:29 -05:00
befs befs: don't pass huge structs by value 2011-01-13 08:03:15 -08:00
bfs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
btrfs Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable 2011-02-25 14:03:39 -08:00
cachefiles llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
ceph ceph: no .snap inside of snapped namespace 2011-03-04 12:25:09 -08:00
cifs [CIFS] update cifs version 2011-02-21 22:31:47 +00:00
coda Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2011-01-13 10:27:28 -08:00
configfs configfs: change depends -> select SYSFS 2011-01-16 21:22:29 +00:00
cramfs cramfs: generate unique inode number for better inode cache usage 2011-01-13 08:03:23 -08:00
debugfs convert get_sb_single() users 2010-10-29 04:16:28 -04:00
devpts convert get_sb_single() users 2010-10-29 04:16:28 -04:00
dlm dlm: use single thread workqueues 2011-02-11 16:50:47 -06:00
ecryptfs eCryptfs: Copy up lower inode attrs in getattr 2011-02-21 14:46:36 -06:00
efs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
exofs exofs: i_nlink races in rename() 2011-03-03 01:28:17 -05:00
exportfs fs: dcache per-inode inode alias locking 2011-01-07 17:50:31 +11:00
ext2 ext2: Fix link count corruption under heavy link+rename load 2011-03-02 11:03:52 +01:00
ext3 Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6 2011-01-21 07:33:37 -08:00
ext4 ext4: serialize unaligned asynchronous DIO 2011-02-12 08:17:34 -05:00
fat switch fat to ->s_d_op, close exportfs races there 2011-01-12 20:02:43 -05:00
freevxfs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
fscache FS-Cache: Fix operation handling 2011-01-14 09:23:36 -08:00
fuse fuse: fix truncate after open 2011-02-25 14:44:58 +01:00
gfs2 mm: prevent concurrent unmap_mapping_range() on the same inode 2011-02-23 19:52:52 -08:00
hfs hfs: fix rename() over non-empty directory 2011-03-03 01:28:40 -05:00
hfsplus hfsplus: fix up a comparism in hfsplus_file_extend 2011-02-03 16:34:18 -07:00
hostfs switch hostfs 2011-01-12 20:03:42 -05:00
hpfs hpfs_setattr error case avoids unlock_kernel 2011-01-17 05:11:37 -05:00
hppfs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
hugetlbfs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
isofs fix isofs d_op handling 2011-01-12 20:02:43 -05:00
jbd fix comment typos concerning "consistent" 2010-12-10 16:04:28 +01:00
jbd2 jbd2: call __jbd2_log_start_commit with j_state_lock write locked 2011-02-12 08:18:24 -05:00
jffs2 Merge git://git.infradead.org/mtd-2.6 2011-01-17 11:15:30 -08:00
jfs Merge branch 'for-2.6.38/core' of git://git.kernel.dk/linux-2.6-block 2011-01-13 10:45:01 -08:00
lockd NLM: Fix "kernel BUG at fs/lockd/host.c:417!" or ".../host.c:283!" 2011-01-25 15:24:47 -05:00
logfs Merge branch 'for-2.6.38/core' of git://git.kernel.dk/linux-2.6-block 2011-01-13 10:45:01 -08:00
minix minix: i_nlink races in rename() 2011-03-03 01:28:16 -05:00
ncpfs move internal-only parts of ncpfs headers to fs/ncpfs 2011-01-12 20:03:43 -05:00
nfs nfs: close NFSv4 COMMIT vs. CLOSE race 2011-03-10 15:04:53 -05:00
nfs_common NFS: Prevent memory allocation failure in nfsacl_encode() 2011-01-25 15:24:47 -05:00
nfsd nfsd: correctly handle return value from nfsd_map_name_to_* 2011-02-16 18:31:05 -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 Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2011-01-13 10:05:56 -08:00
ntfs NTFS: Fix invalid pointer dereference in ntfs_mft_record_alloc(). 2011-01-31 12:58:11 +10:00
ocfs2 ocfs2: Check heartbeat mode for kernel stacks only 2011-02-20 02:36:28 -08:00
omfs new helper: mount_bdev() 2010-10-29 04:16:13 -04:00
openpromfs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
partitions ldm: corrupted partition table can cause kernel oops 2011-02-25 15:07:36 -08:00
proc of/flattree: Drop an uninteresting message to pr_debug level 2011-03-02 13:45:18 -07:00
qnx4 fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
quota quota: Fix deadlock during path resolution 2011-01-12 19:14:55 +01:00
ramfs convert get_sb_nodev() users 2010-10-29 04:16:31 -04:00
reiserfs fix reiserfs mkdir() breakage 2011-03-03 01:28:40 -05:00
romfs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
squashfs squashfs: fix use of uninitialised variable in zlib & xz decompressors 2011-01-26 10:50:05 +10:00
sysfs kconfig: rename CONFIG_EMBEDDED to CONFIG_EXPERT 2011-01-20 17:02:05 -08:00
sysv sysv: i_nlink races in rename() 2011-03-03 01:28:16 -05:00
ubifs fs: icache RCU free inodes 2011-01-07 17:50:26 +11:00
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 sanitize vfsmount refcounting changes 2011-01-16 13:47:07 -05:00
attr.c
bad_inode.c fs: provide rcu-walk aware permission i_ops 2011-01-07 17:50:29 +11:00
binfmt_aout.c Don't dump task struct in a.out core-dumps 2010-10-14 10:57:40 -07:00
binfmt_elf_fdpic.c
binfmt_elf.c binfmt_elf: cleanups 2011-01-13 08:03:12 -08:00
binfmt_em86.c
binfmt_flat.c
binfmt_misc.c convert get_sb_single() users 2010-10-29 04:16:28 -04:00
binfmt_script.c Make do_execve() take a const filename pointer 2010-08-17 18:07:43 -07:00
binfmt_som.c
bio-integrity.c bio-integrity: mark kintegrityd_wq highpri and CPU intensive 2011-01-03 15:01:48 +01:00
bio.c bio: take care not overflow page count when mapping/copying user data 2010-11-10 14:40:43 +01:00
block_dev.c fs/block_dev.c: fix new kernel-doc warning 2011-02-28 18:08:31 -08:00
buffer.c fs: Use this_cpu_inc_return in buffer.c 2010-12-17 15:18:05 +01:00
char_dev.c Merge branch 'for-2.6.38/core' of git://git.kernel.dk/linux-2.6-block 2011-01-13 10:45:01 -08:00
compat_binfmt_elf.c
compat_ioctl.c Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6 2011-01-07 14:39:20 -08:00
compat.c compat: copy missing fields in compat_statfs64 to user 2011-01-17 04:54:38 -05:00
dcache.c fs: fix new dcache.c kernel-doc warnings 2011-01-22 20:32:38 -08:00
dcookies.c
direct-io.c fs/direct-io.c: don't try to allocate more than BIO_MAX_PAGES in a bio 2011-01-20 17:02:05 -08:00
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 vfs: sparse: add __FMODE_EXEC 2011-02-02 16:03:19 -08:00
fcntl.c vfs: sparse: add __FMODE_EXEC 2011-02-02 16:03:19 -08:00
fifo.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
file_table.c CRED: Fix kernel panic upon security_file_alloc() failure. 2011-02-04 10:40:29 -08:00
file.c vfs: use kmalloc() to allocate fdmem if possible 2010-08-11 08:59:02 -07:00
filesystems.c fs: rcu-walk for path lookup 2011-01-07 17:50:27 +11:00
fs_struct.c sanitize vfsmount refcounting changes 2011-01-16 13:47:07 -05:00
fs-writeback.c fs/fs-writeback.c: fix sync_inodes_sb() return value kernel-doc 2011-01-13 17:32:48 -08:00
generic_acl.c fs: provide simple rcu-walk generic_check_acl implementation 2011-01-07 17:50:29 +11:00
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 fs: make block fiemap mapping length at least blocksize long 2011-02-02 16:03:20 -08:00
ioprio.c ioprio: grab rcu_read_lock in sys_ioprio_{set,get}() 2010-11-15 10:23:31 +01:00
Kconfig kconfig: rename CONFIG_EMBEDDED to CONFIG_EXPERT 2011-01-20 17:02:05 -08:00
Kconfig.binfmt coredump: default CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y 2010-10-27 18:03:12 -07:00
libfs.c pass default dentry_operations to mount_pseudo() 2011-01-12 20:03:43 -05:00
locks.c Merge branch 'for-2.6.38' of git://linux-nfs.org/~bfields/linux 2011-01-14 13:17:26 -08:00
Makefile Merge 'staging-next' to Linus's tree 2010-10-28 09:44:56 -07:00
mbcache.c ext2: Resolve 'dereferencing pointer to incomplete type' when enabling EXT2_XATTR_DEBUG 2011-01-10 19:04:08 +01:00
mpage.c fs/mpage.c: consolidate code 2011-01-13 17:32:32 -08:00
namei.c vfs: fix BUG_ON() in fs/namei.c:1461 2011-02-16 08:56:55 -08:00
namespace.c Unlock vfsmount_lock in do_umount 2011-02-24 02:10:57 -05:00
nfsctl.c
no-block.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
open.c Fix possible filp_cachep memory corruption 2011-02-11 15:53:38 -08:00
pipe.c Fix broken "pipe: use event aware wakeups" optimization 2011-01-20 16:21:59 -08:00
pnode.c fs: scale mntget/mntput 2011-01-07 17:50:33 +11:00
pnode.h
posix_acl.c NFS: Prevent memory allocation failure in nfsacl_encode() 2011-01-25 15:24:47 -05:00
read_write.c fix signedness mess in rw_verify_area() on 64bit architectures 2011-01-12 20:06:58 -05:00
read_write.h
readdir.c vfs: fix warning: 'dirent' is used uninitialized in this function 2010-08-09 20:45:05 -07:00
select.c fs/select.c: fix information leak to userspace 2011-01-13 08:03:12 -08:00
seq_file.c fs: take dcache_lock inside __d_path 2010-10-25 21:26:12 -04:00
signalfd.c Merge branch 'hwpoison' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6 2010-10-26 10:13:10 -07:00
splice.c Merge branch 'for-2.6.38/core' of git://git.kernel.dk/linux-2.6-block 2011-01-13 10:45:01 -08:00
stack.c
stat.c Add an AT_NO_AUTOMOUNT flag to suppress terminal automount 2011-01-15 20:07:33 -05:00
statfs.c add f_flags to struct statfs(64) 2010-08-09 16:48:44 -04:00
super.c vfs: call rcu_barrier after ->kill_sb() 2011-02-11 16:12:19 -08:00
sync.c
timerfd.c llseek: automatically add .llseek fop 2010-10-15 15:53:27 +02:00
utimes.c Mark arguments to certain syscalls as being const 2010-08-13 16:53:13 -07:00
xattr_acl.c
xattr.c