linux/fs
Steven Whitehouse 9fe55eea7e Fix race when checking i_size on direct i/o read
So far I've had one ACK for this, and no other comments. So I think it
is probably time to send this via some suitable tree. I'm guessing that
the vfs tree would be the most appropriate route, but not sure that
there is one at the moment (don't see anything recent at kernel.org)
so in that case I think -mm is the "back up plan". Al, please let me
know if you will take this?

Steve.

---------------------

Following on from the "Re: [PATCH v3] vfs: fix a bug when we do some dio
reads with append dio writes" thread on linux-fsdevel, this patch is my
current version of the fix proposed as option (b) in that thread.

Removing the i_size test from the direct i/o read path at vfs level
means that filesystems now have to deal with requests which are beyond
i_size themselves. These I've divided into three sets:

 a) Those with "no op" ->direct_IO (9p, cifs, ceph)
These are obviously not going to be an issue

 b) Those with "home brew" ->direct_IO (nfs, fuse)
I've been told that NFS should not have any problem with the larger
i_size, however I've added an extra test to FUSE to duplicate the
original behaviour just to be on the safe side.

 c) Those using __blockdev_direct_IO()
These call through to ->get_block() which should deal with the EOF
condition correctly. I've verified that with GFS2 and I believe that
Zheng has verified it for ext4. I've also run the test on XFS and it
passes both before and after this change.

The part of the patch in filemap.c looks a lot larger than it really is
- there are only two lines of real change. The rest is just indentation
of the contained code.

There remains a test of i_size though, which was added for btrfs. It
doesn't cause the other filesystems a problem as the test is performed
after ->direct_IO has been called. It is possible that there is a race
that does matter to btrfs, however this patch doesn't change that, so
its still an overall improvement.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Reported-by: Zheng Liu <gnehzuil.liu@gmail.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Dave Chinner <david@fromorbit.com>
Acked-by: Miklos Szeredi <miklos@szeredi.hu>
Cc: Chris Mason <clm@fb.com>
Cc: Josef Bacik <jbacik@fb.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2014-01-26 08:26:42 -05:00
..
9p fs: make posix_acl_create more useful 2014-01-25 23:58:18 -05:00
adfs adfs: delayed freeing of sbi 2013-10-24 23:43:27 -04:00
affs affs: use ->kill_sb() to simplify ->put_super() and failure exits of ->mount() 2014-01-25 03:13:01 -05:00
afs afs: get rid of junk in fs/afs/proc.c 2014-01-25 03:14:06 -05:00
autofs4 autofs4: make freeing sbi rcu-delayed 2013-10-24 23:43:27 -04:00
befs befs: iget_locked() doesn't return an ERR_PTR 2014-01-25 03:14:38 -05:00
bfs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
btrfs btrfs: use generic posix ACL infrastructure 2014-01-25 23:58:18 -05:00
cachefiles Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-11-13 15:34:18 +09:00
ceph ceph: Avoid data inconsistency due to d-cache aliasing in readpage() 2013-12-13 09:11:38 -08:00
cifs cifs: set FILE_CREATED 2013-12-27 15:14:45 -06:00
coda coda_revalidate_inode(): switch to passing inode... 2013-11-09 00:16:21 -05:00
configfs configfs: fix race between dentry put and lookup 2013-11-21 16:42:27 -08:00
cramfs cramfs: take headers to fs/cramfs 2014-01-25 03:13:02 -05:00
debugfs debugfs: use list_next_entry() in debugfs_remove_recursive() 2013-11-13 12:09:24 +09:00
devpts devpts: plug the memory leak in kill_sb 2013-11-13 12:09:36 +09:00
dlm genetlink: only pass array to genl_register_family_with_ops() 2013-11-19 16:39:05 -05:00
ecryptfs ecryptfs: fix failure handling in ->readlink() 2014-01-25 03:13:00 -05:00
efivarfs consolidate simple ->d_delete() instances 2013-11-15 22:04:17 -05:00
efs efs: get rid of ->put_super() 2014-01-25 03:13:02 -05:00
exofs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
exportfs exportfs: fix quadratic behavior in filehandle lookup 2013-11-09 00:16:38 -05:00
ext2 ext2/3/4: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
ext3 ext2/3/4: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
ext4 ext2/3/4: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
f2fs f2fs: use generic posix ACL infrastructure 2014-01-25 23:58:19 -05:00
fat fat: rcu-delay unloading nls and freeing sbi 2013-10-24 23:43:28 -04:00
freevxfs
fscache Merge branch 'for-3.13/core' of git://git.kernel.dk/linux-block 2013-11-14 12:08:14 +09:00
fuse Fix race when checking i_size on direct i/o read 2014-01-26 08:26:42 -05:00
gfs2 gfs2: use generic posix ACL infrastructure 2014-01-25 23:58:22 -05:00
hfs fs/hfs/btree.h: remove duplicate defines 2013-11-13 12:09:32 +09:00
hfsplus hfsplus: remove can_set_xattr 2014-01-26 08:26:41 -05:00
hostfs consolidate simple ->d_delete() instances 2013-11-15 22:04:17 -05:00
hpfs locks: break delegations on any attribute modification 2013-11-09 00:16:44 -05:00
hppfs clean up scary strncpy(dst, src, strlen(src)) uses 2013-07-03 16:07:41 -07:00
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 jbd: Revert "jbd: remove dependency on __GFP_NOFAIL" 2013-10-31 20:37:15 +01:00
jbd2 jbd2: rename obsoleted msg JBD->JBD2 2013-12-08 21:14:59 -05:00
jffs2 jffs2: use generic posix ACL infrastructure 2014-01-25 23:58:20 -05:00
jfs jfs: use generic posix ACL infrastructure 2014-01-25 23:58:22 -05:00
lockd LOCKD: Don't call utsname()->nodename from nlmclnt_setlockargs 2013-08-05 15:03:46 -04:00
logfs block: submit_bio_wait() conversions 2013-11-24 16:33:41 -07:00
minix fs/minix: Drop dependency on H8300 2013-09-16 18:20:25 -07:00
ncpfs ncpfs: rcu-delay unload_nls() and freeing ncp_server 2013-10-24 23:43:28 -04:00
nfs nfs: use generic posix ACL infrastructure for v3 Posix ACLs 2014-01-26 08:26:20 -05:00
nfs_common
nfsd nfsd: use get_acl and ->set_acl 2014-01-26 08:26:41 -05:00
nilfs2 nilfs2: fix segctor bug that causes file system corruption 2014-01-15 14:19:42 +07:00
nls nls: have register_nls() set ->owner 2014-01-25 03:14:05 -05:00
notify fsnotify: update comments concerning locking scheme 2013-07-09 10:33:20 -07:00
ntfs iget/iget5: don't bother with ->i_lock until we find a match 2013-11-09 00:16:31 -05:00
ocfs2 ocfs2: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00
omfs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
openpromfs
proc procfs: also fix proc_reg_get_unmapped_area() for !MMU case 2013-12-12 18:19:26 -08:00
pstore pstore: Don't allow high traffic options on fragile devices 2013-12-20 13:12:01 -08:00
qnx4 qnx4: clean qnx4_fill_super() up 2014-01-25 03:13:03 -05:00
qnx6
quota genetlink: make multicast groups const, prevent abuse 2013-11-19 16:39:06 -05:00
ramfs initmpfs: move rootfs code from fs/ramfs/ to init/ 2013-09-11 15:59:37 -07:00
reiserfs reiserfs: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00
romfs
squashfs Squashfs: fix failure to unlock pages on decompress error 2013-11-24 01:02:50 +00:00
sysfs sysfs: give different locking key to regular and bin files 2013-12-07 21:22:00 -08:00
sysv sysv: Add forgotten superblock lock init for v7 fs 2013-09-29 22:02:02 -04:00
ubifs Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-11-13 15:34:18 +09:00
udf udf: fix for pathetic mount times in case of invalid file system 2013-10-18 22:39:07 +02:00
ufs truncate: drop 'oldsize' truncate_pagecache() parameter 2013-09-12 15:38:02 -07:00
xfs xfs: use generic posix ACL infrastructure 2014-01-25 23:58:21 -05:00
aio.c Merge git://git.kvack.org/~bcrl/aio-next 2013-12-22 11:03:49 -08:00
anon_inodes.c ... and kill anon_inode_getfile_private() 2013-11-09 00:16:28 -05:00
attr.c locks: break delegations on any attribute modification 2013-11-09 00:16:44 -05:00
bad_inode.c [readdir] ->readdir() is gone 2013-06-29 12:57:04 +04:00
binfmt_aout.c dump_skip(): dump_seek() replacement taking coredump_params 2013-11-09 00:16:26 -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_elf.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 bio: fix argument of __bio_add_page() for max_sectors > 0xffff 2013-11-18 12:31:27 -07:00
block_dev.c a trivial writeback fix 2013-09-13 23:06:40 -04:00
buffer.c fs: buffer: move allocation failure loop into the allocator 2013-10-16 21:35:53 -07:00
char_dev.c Merge branch 'for-3.13/core' of git://git.kernel.dk/linux-block 2013-11-14 12:08:14 +09:00
compat_binfmt_elf.c
compat_ioctl.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
compat.c [readdir] constify ->actor 2013-06-29 12:57:05 +04:00
coredump.c dump_emit(): use __kernel_write(), not vfs_write() 2013-11-15 22:04:09 -05:00
coredump.h
dcache.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2014-01-17 17:29:36 -08: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 eventfd_ctx_fdget(): use fdget() instead of fget() 2014-01-25 03:13:04 -05:00
eventpoll.c epoll: do not take the nested ep->mtx on EPOLL_CTL_DEL 2014-01-02 14:40:30 -08:00
exec.c Merge git://git.infradead.org/users/eparis/audit 2013-11-21 19:18:14 -08:00
fcntl.c file->f_op is never NULL... 2013-10-24 23:34:54 -04:00
fhandle.c
file_table.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-11-13 15:34:18 +09:00
file.c fs: __fget_light() can use __fget() in slow path 2014-01-25 03:14:38 -05:00
filesystems.c
fs_struct.c seqcount: Add lockdep functionality to seqcount/seqlock structures 2013-11-06 12:40:26 +01:00
fs-writeback.c writeback: Fix data corruption on NFS 2013-12-14 04:21:26 +08:00
inode.c locks: break delegations on any attribute modification 2013-11-09 00:16:44 -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 fs: remove generic_acl 2014-01-26 08:26:40 -05:00
Kconfig.binfmt
libfs.c consolidate simple ->d_delete() instances 2013-11-15 22:04:17 -05:00
locks.c locks: missing unlock on error in generic_add_lease() 2013-11-13 07:30:53 -05:00
Makefile fs: remove generic_acl 2014-01-26 08:26:40 -05:00
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 fs: add get_acl helper 2014-01-25 23:58:16 -05:00
namespace.c vfs: Fix a regression in mounting proc 2013-11-26 20:54:52 -08:00
no-block.c
open.c locks: break delegations on any attribute modification 2013-11-09 00:16:44 -05:00
pipe.c vfs: fix subtle use-after-free of pipe_inode_info 2013-12-02 09:44:51 -08:00
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 fs: remove generic_acl 2014-01-26 08:26:40 -05:00
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 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-11-13 15:34:18 +09:00
seq_file.c seq_file: always clear m->count when we free m->buf 2013-11-18 19:07:53 -08:00
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 vfs: allow O_PATH file descriptors for fstatfs() 2013-10-12 13:12:31 -07:00
super.c get rid of s_files and files_lock 2013-11-09 00:16:20 -05:00
sync.c Merge branch 'akpm' (patches from Andrew Morton) 2013-11-13 15:45:43 +09:00
timerfd.c
utimes.c locks: break delegations on any attribute modification 2013-11-09 00:16:44 -05:00
xattr.c