linux/fs
Fengguang Wu 9ae9d68cbf [PATCH] splice(): fix interaction with readahead
Eric Dumazet, thank you for disclosing this bug.

Readahead logic somehow fails to populate the page range with data.
It can be because

1) the readahead routine is not always called in the following lines of

fs/splice.c:
        if (!loff || nr_pages > 1)
                page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);

2) even called, page_cache_readahead() wont guarantee the pages are there.
It wont submit readahead I/O for pages already in the radix tree, or when
(ra_pages == 0), or after 256 cache hits.

In your case, it should be because of the retried reads, which lead to
excessive cache hits, and disables readahead at some time.

And that _one_ failure of readahead blocks the whole read process.
The application receives EAGAIN and retries the read, but
__generic_file_splice_read() refuse to make progress:

- in the previous invocation, it has allocated a blank page and inserted it
  into the radix tree, but never has the chance to start I/O for it: the test
  of SPLICE_F_NONBLOCK goes before that.

- in the retried invocation, the readahead code will neither get out of the
  cache hit mode, nor will it submit I/O for an already existing page.

Cc: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
2007-05-08 08:44:36 +02:00
..
9p v9fs: don't use primary fid when removing file 2007-04-24 08:23:08 -07:00
adfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
affs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
afs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
autofs [PATCH] Mark struct super_operations const 2007-02-12 09:48:47 -08:00
autofs4 [PATCH] autofs4: fix race in unhashed dentry code 2007-04-12 15:31:42 -07:00
befs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
bfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
cifs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
coda slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
configfs remove "struct subsystem" as it is no longer needed 2007-05-02 18:57:59 -07:00
cramfs mm: make read_cache_page synchronous 2007-05-07 12:12:51 -07:00
debugfs remove "struct subsystem" as it is no longer needed 2007-05-02 18:57:59 -07:00
devpts [PATCH] Mark struct super_operations const 2007-02-12 09:48:47 -08:00
dlm Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw 2007-05-07 12:26:27 -07:00
ecryptfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
efs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
exportfs [PATCH] VFS: Make filldir_t and struct kstat deal in 64-bit inode numbers 2006-10-03 08:03:40 -07:00
ext2 slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
ext3 slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
ext4 slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
fat slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
freevxfs mm: make read_cache_page synchronous 2007-05-07 12:12:51 -07:00
fuse Merge branch 'server-cluster-locking-api' of git://linux-nfs.org/~bfields/linux 2007-05-07 12:34:24 -07:00
gfs2 Merge branch 'server-cluster-locking-api' of git://linux-nfs.org/~bfields/linux 2007-05-07 12:34:24 -07:00
hfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
hfsplus slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
hostfs [PATCH] uml: hostfs variable renaming 2007-03-29 08:22:25 -07:00
hpfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
hppfs [PATCH] Mark struct super_operations const 2007-02-12 09:48:47 -08:00
hugetlbfs hugetlbfs: add NULL check in hugetlb_zero_setup() 2007-05-07 12:12:57 -07:00
isofs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
jbd [PATCH] jbd: wait for already submitted t_sync_datalist buffer to complete 2006-12-22 08:55:51 -08:00
jbd2 [PATCH] jbd2: wait for already submitted t_sync_datalist buffer to complete 2006-12-07 08:39:42 -08:00
jffs2 slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
jfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
lockd Merge branch 'server-cluster-locking-api' of git://linux-nfs.org/~bfields/linux 2007-05-07 12:34:24 -07:00
minix slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
msdos [PATCH] mark struct inode_operations const 2 2007-02-12 09:48:46 -08:00
ncpfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
nfs Merge branch 'server-cluster-locking-api' of git://linux-nfs.org/~bfields/linux 2007-05-07 12:34:24 -07:00
nfs_common [PATCH] nfs_common endianness annotations 2006-10-20 10:26:41 -07:00
nfsd Merge branch 'server-cluster-locking-api' of git://linux-nfs.org/~bfields/linux 2007-05-07 12:34:24 -07:00
nls [PATCH] fs: make nls_cp936.c handle some U00XY characters and U20AC correctly 2006-12-07 08:39:46 -08:00
ntfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
ocfs2 slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
openpromfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
partitions mm: optimize acorn partition truncate 2007-05-07 12:12:55 -07:00
proc slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
qnx4 slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
ramfs [PATCH] Mark struct super_operations const 2007-02-12 09:48:47 -08:00
reiserfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
romfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
smbfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
sysfs remove "struct subsystem" as it is no longer needed 2007-05-02 18:57:59 -07:00
sysv slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
udf slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
ufs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
vfat [PATCH] mark struct inode_operations const 3 2007-02-12 09:48:46 -08:00
xfs slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
aio.c KMEM_CACHE(): simplify slab cache creation 2007-05-07 12:12:55 -07:00
attr.c
bad_inode.c [PATCH] mark struct inode_operations const 1 2007-02-12 09:48:46 -08:00
binfmt_aout.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
binfmt_elf_fdpic.c [PATCH] fix page leak during core dump 2007-04-02 10:06:08 -07:00
binfmt_elf.c [PATCH] fix page leak during core dump 2007-04-02 10:06:08 -07:00
binfmt_em86.c
binfmt_flat.c [PATCH] uclinux: correctly remap bin_fmtflat exe allocated mem regions 2007-02-09 10:45:33 -08:00
binfmt_misc.c [PATCH] Mark struct super_operations const 2007-02-12 09:48:47 -08:00
binfmt_script.c
binfmt_som.c [PARISC] Fix fs/binfmt_som.c 2006-10-04 06:51:26 -06:00
bio.c KMEM_CACHE(): simplify slab cache creation 2007-05-07 12:12:55 -07:00
block_dev.c slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
buffer.c slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
char_dev.c [PATCH] remove protection of LANANA-reserved majors 2007-04-04 21:12:47 -07:00
compat_ioctl.c [PATCH] x86-64: Shut up warnings for vfat compat ioctls on other file systems 2007-05-02 19:27:21 +02:00
compat.c [PATCH] x86-64: Print type and size correctly for unknown compat ioctls 2007-05-02 19:27:21 +02:00
dcache.c KMEM_CACHE(): simplify slab cache creation 2007-05-07 12:12:55 -07:00
dcookies.c [PATCH] slab: remove kmem_cache_t 2006-12-07 08:39:25 -08:00
direct-io.c [PATCH] dio: lock refcount operations 2006-12-10 09:57:21 -08:00
dnotify.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
dquot.c mm: remove destroy_dirty_buffers from invalidate_bdev() 2007-05-07 12:12:55 -07:00
drop_caches.c [PATCH] remove invalidate_inode_pages() 2007-02-11 10:51:31 -08:00
eventpoll.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
exec.c exec.c: fix coredump to pipe problem and obscure "security hole" 2007-04-17 16:36:26 -07:00
fcntl.c [PATCH] fdtable: Make fdarray and fdsets equal in size 2006-12-10 09:57:22 -08:00
fifo.c
file_table.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
file.c [PATCH] fdtable: Provide free_fdtable() wrapper 2006-12-22 08:55:50 -08:00
filesystems.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
fs-writeback.c Write back inode data pages even when the inode itself is locked 2007-01-26 12:53:20 -08:00
generic_acl.c [PATCH] Generic infrastructure for acls 2006-09-29 09:18:24 -07:00
inode.c slab allocators: Remove SLAB_DEBUG_INITIAL flag 2007-05-07 12:12:57 -07:00
inotify_user.c [PATCH] inotify: read return val fix 2007-02-12 09:48:28 -08:00
inotify.c [PATCH] severing fs.h, radix-tree.h -> sched.h 2006-12-04 02:00:24 -05:00
internal.h [PATCH] CONFIG_BLOCK internal.h cleanups 2006-09-30 20:52:32 +02:00
ioctl.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
ioprio.c [PATCH] pid: replace do/while_each_task_pid with do/while_each_pid_task 2007-02-12 09:48:32 -08:00
Kconfig Merge git://git.linux-nfs.org/pub/linux/nfs-2.6 2007-05-04 19:55:11 -07:00
Kconfig.binfmt blackfin architecture 2007-05-07 12:12:58 -07:00
libfs.c [PATCH] shmem and simple const super_operations 2007-03-05 07:57:51 -08:00
locks.c Merge branch 'server-cluster-locking-api' of git://linux-nfs.org/~bfields/linux 2007-05-07 12:34:24 -07:00
Makefile Remove JFFS (version 1), as scheduled. 2007-02-17 16:10:59 -05:00
mbcache.c [PATCH] slab: remove kmem_cache_t 2006-12-07 08:39:25 -08:00
mpage.c [PATCH] BLOCK: Dissociate generic_writepages() from mpage stuff [try #6] 2006-09-30 20:52:26 +02:00
namei.c mm: make read_cache_page synchronous 2007-05-07 12:12:51 -07:00
namespace.c [PATCH] Transform kmem_cache_alloc()+memset(0) -> kmem_cache_zalloc(). 2007-02-11 10:51:27 -08:00
nfsctl.c
no-block.c [PATCH] BLOCK: Make it possible to disable the block layer [try #6] 2006-09-30 20:52:31 +02:00
open.c [PATCH] fdtable: Make fdarray and fdsets equal in size 2006-12-10 09:57:22 -08:00
pipe.c [PATCH] AUDIT_FD_PAIR 2007-02-17 21:30:15 -05:00
pnode.c [PATCH] rename struct namespace to struct mnt_namespace 2006-12-08 08:28:51 -08:00
pnode.h [PATCH] rename struct namespace to struct mnt_namespace 2006-12-08 08:28:51 -08:00
posix_acl.c [PATCH] kmemdup: some users 2006-10-01 00:39:19 -07:00
quota_v1.c
quota_v2.c
quota.c [PATCH] BLOCK: Make it possible to disable the block layer [try #6] 2006-09-30 20:52:31 +02:00
read_write.c [PATCH] FS: speed up rw_verify_area() 2007-02-12 09:48:29 -08:00
read_write.h [PATCH] Remove readv/writev methods and use aio_read/aio_write instead 2006-10-01 00:39:28 -07:00
readdir.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
select.c [PATCH] fdtable: Make fdarray and fdsets equal in size 2006-12-10 09:57:22 -08:00
seq_file.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
splice.c [PATCH] splice(): fix interaction with readahead 2007-05-08 08:44:36 +02:00
stack.c [PATCH] fs/stack.c: Copy i_nlink after all other attributes are copied 2007-02-19 14:21:50 -08:00
stat.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00
super.c the overdue removal of the mount/umount uevents 2007-04-27 10:57:31 -07:00
sync.c [PATCH] Turn do_sync_file_range() into do_sync_mapping_range() 2007-04-26 15:02:26 -07:00
utimes.c [PATCH] severing fs.h, radix-tree.h -> sched.h 2006-12-04 02:00:24 -05:00
xattr_acl.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
xattr.c [PATCH] VFS: change struct file to use struct path 2006-12-08 08:28:41 -08:00