android_kernel_google_msm/fs
Christophe Leroy 0765dbc54e splice: sendfile() at once fails for big files
commit 0ff28d9f4674d781e492bcff6f32f0fe48cf0fed upstream.

Using sendfile with below small program to get MD5 sums of some files,
it appear that big files (over 64kbytes with 4k pages system) get a
wrong MD5 sum while small files get the correct sum.
This program uses sendfile() to send a file to an AF_ALG socket
for hashing.

/* md5sum2.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/if_alg.h>

int main(int argc, char **argv)
{
	int sk = socket(AF_ALG, SOCK_SEQPACKET, 0);
	struct stat st;
	struct sockaddr_alg sa = {
		.salg_family = AF_ALG,
		.salg_type = "hash",
		.salg_name = "md5",
	};
	int n;

	bind(sk, (struct sockaddr*)&sa, sizeof(sa));

	for (n = 1; n < argc; n++) {
		int size;
		int offset = 0;
		char buf[4096];
		int fd;
		int sko;
		int i;

		fd = open(argv[n], O_RDONLY);
		sko = accept(sk, NULL, 0);
		fstat(fd, &st);
		size = st.st_size;
		sendfile(sko, fd, &offset, size);
		size = read(sko, buf, sizeof(buf));
		for (i = 0; i < size; i++)
			printf("%2.2x", buf[i]);
		printf("  %s\n", argv[n]);
		close(fd);
		close(sko);
	}
	exit(0);
}

Test below is done using official linux patch files. First result is
with a software based md5sum. Second result is with the program above.

root@vgoip:~# ls -l patch-3.6.*
-rw-r--r--    1 root     root         64011 Aug 24 12:01 patch-3.6.2.gz
-rw-r--r--    1 root     root         94131 Aug 24 12:01 patch-3.6.3.gz

root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
5fd77b24e68bb24dcc72d6e57c64790e  patch-3.6.3.gz

After investivation, it appears that sendfile() sends the files by blocks
of 64kbytes (16 times PAGE_SIZE). The problem is that at the end of each
block, the SPLICE_F_MORE flag is missing, therefore the hashing operation
is reset as if it was the end of the file.

This patch adds SPLICE_F_MORE to the flags when more data is pending.

With the patch applied, we get the correct sums:

root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Jens Axboe <axboe@fb.com>
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Zefan Li <lizefan@huawei.com>
2016-04-27 18:55:30 +08:00
..
9p 9p: don't leave a half-initialized inode sitting around 2016-03-21 09:17:41 +08:00
adfs
affs move d_rcu from overlapping d_child to overlapping d_alias 2015-04-14 17:33:58 +08:00
afs
autofs4 autofs4: check dev ioctl size before allocating 2015-06-19 11:40:33 +08:00
befs
bfs
btrfs btrfs: skip waiting on ordered range for special files 2016-04-27 18:55:22 +08:00
cachefiles fs: cachefiles: add support for large files in filesystem caching 2014-06-07 16:02:04 -07:00
ceph fs: create and use seq_show_option for escaping 2016-04-27 18:55:18 +08:00
cifs cifs: use server timestamp for ntlmv2 authentication 2016-04-27 18:55:24 +08:00
coda move d_rcu from overlapping d_child to overlapping d_alias 2015-04-14 17:33:58 +08:00
configfs configfs: fix race between dentry put and lookup 2013-11-29 10:50:37 -08:00
cramfs
debugfs debugfs: leave freeing a symlink body until inode eviction 2015-06-19 11:40:18 +08:00
devpts devpts: plug the memory leak in kill_sb 2013-12-04 10:50:14 -08:00
dlm dlm fixes for 3.4 2012-04-23 18:22:42 -07:00
ecryptfs eCryptfs: Invalidate dcache entries when lower i_nlink is zero 2016-04-27 18:55:16 +08:00
efs
exofs ore: Fix wrong math in allocation of per device BIO 2014-02-13 11:51:11 -08:00
exportfs move d_rcu from overlapping d_child to overlapping d_alias 2015-04-14 17:33:58 +08:00
ext2 ext2: Fix fs corruption in ext2_get_xip_mem() 2014-09-25 11:49:19 +08:00
ext3 ext3: Don't check quota format when there are no quota files 2015-02-02 17:05:00 +08:00
ext4 fs: create and use seq_show_option for escaping 2016-04-27 18:55:18 +08:00
fat fat: fix possible overflow for fat_clusters 2013-06-07 12:49:12 -07:00
freevxfs
fscache fs/fscache/stats.c: fix memory leak 2013-05-07 19:51:55 -07:00
fuse fuse: initialize fc->release before calling it 2015-10-22 09:20:07 +08:00
gfs2 fs: create and use seq_show_option for escaping 2016-04-27 18:55:18 +08:00
hfs hfs: fix B-tree corruption after insertion at position 0 2016-04-27 18:55:18 +08:00
hfsplus hfs,hfsplus: cache pages correctly between bnode_create and bnode_free 2016-04-27 18:55:18 +08:00
hostfs fs: create and use seq_show_option for escaping 2016-04-27 18:55:18 +08:00
hpfs hpfs: update ctime and mtime on directory modification 2016-04-27 18:55:17 +08:00
hppfs
hugetlbfs hugetlbfs: fix mmap failure in unaligned size request 2013-05-19 10:54:48 -07:00
isofs isofs: Fix unchecked printing of ER records 2015-04-14 17:33:47 +08:00
jbd jbd: Fix lock ordering bug in journal_unmap_buffer() 2012-12-03 11:47:10 -08:00
jbd2 jbd2: avoid infinite loop when destroying aborted journal 2015-10-22 09:20:08 +08:00
jffs2 jffs2: fix handling of corrupted summary length 2015-06-19 11:40:16 +08:00
jfs jfs: fix readdir regression 2015-04-14 17:34:02 +08:00
lockd lockd: Try to reconnect if statd has moved 2015-02-02 17:04:42 +08:00
logfs
minix
ncpfs move d_rcu from overlapping d_child to overlapping d_alias 2015-04-14 17:33:58 +08:00
nfs NFSv4: don't set SETATTR for O_RDONLY|O_EXCL 2016-04-27 18:55:15 +08:00
nfs_common
nfsd nfsd: fix the check for confirmed openowner in nfs4_preprocess_stateid_op 2015-09-18 09:20:38 +08:00
nilfs2 nilfs2: fix sanity check of btree level in nilfs_btree_root_broken() 2015-09-18 09:20:36 +08:00
nls
notify fsnotify: next_i is freed during fsnotify_unmount_inodes. 2015-04-14 17:34:03 +08:00
ntfs
ocfs2 ocfs2/dlm: fix deadlock when dispatch assert master 2016-04-27 18:55:24 +08:00
omfs fs, omfs: add NULL terminator in the end up the token list 2015-09-18 09:20:43 +08:00
openpromfs
proc pagemap: do not leak physical addresses to non-privileged userspace 2015-04-14 17:34:02 +08:00
pstore pstore: Avoid deadlock in panic and emergency-restart path 2013-03-04 06:06:43 +08:00
qnx4
qnx6
quota quota: Fix race between dqput() and dquot_scan_active() 2014-03-11 16:10:02 -07:00
ramfs fs: ramfs: file-nommu: add SetPageUptodate() 2012-07-16 09:04:45 -07:00
reiserfs fs: create and use seq_show_option for escaping 2016-04-27 18:55:18 +08:00
romfs MTD merge for 3.4 2012-03-30 17:31:56 -07:00
squashfs Add an extra mount time sanity check, plus some code cleanups and bug fixes. 2012-03-28 18:05:54 -07:00
sysfs sysfs: fix use after free in case of concurrent read/write and readdir 2013-05-07 19:51:54 -07:00
sysv
ubifs UBIFS: fix free log space calculation 2015-02-02 17:04:36 +08:00
udf udf: Check length of extended attributes and allocation descriptors 2015-09-18 09:20:45 +08:00
ufs Remove all #inclusions of asm/system.h 2012-03-28 18:30:03 +01:00
xfs fs: create and use seq_show_option for escaping 2016-04-27 18:55:18 +08:00
aio.c aio: fix possible invalid memory access when DEBUG is enabled 2013-05-01 09:41:03 -07:00
anon_inodes.c
attr.c vfs: increment iversion when a file is truncated 2012-06-10 00:36:12 +09:00
bad_inode.c
binfmt_aout.c VM: add "vm_mmap()" helper function 2012-04-20 17:29:13 -07:00
binfmt_elf.c fs/binfmt_elf.c: fix bug in loading of PIE binaries 2015-09-18 09:20:30 +08:00
binfmt_elf_fdpic.c VM: add "vm_mmap()" helper function 2012-04-20 17:29:13 -07:00
binfmt_em86.c exec: use -ELOOP for max recursion depth 2013-03-28 12:12:28 -07:00
binfmt_flat.c VM: add "vm_mmap()" helper function 2012-04-20 17:29:13 -07:00
binfmt_misc.c exec: use -ELOOP for max recursion depth 2013-03-28 12:12:28 -07:00
binfmt_script.c exec: use -ELOOP for max recursion depth 2013-03-28 12:12:28 -07:00
binfmt_som.c VM: add "vm_mmap()" helper function 2012-04-20 17:29:13 -07:00
bio-integrity.c
bio.c SCSI: sg: Fix user memory corruption when SG_IO is interrupted by a signal 2013-09-07 21:58:16 -07:00
block_dev.c writeback: Fix periodic writeback after fs mount 2013-07-28 16:26:08 -07:00
buffer.c fs/buffer.c: support buffer cache allocations with gfp modifiers 2016-03-21 09:17:39 +08:00
char_dev.c
compat.c Fix: compat_rw_copy_check_uvector() misuse in aio, readv, writev, and security keys 2013-03-14 11:29:51 -07:00
compat_binfmt_elf.c
compat_ioctl.c fs/compat_ioctl.c: VIDEO_SET_SPU_PALETTE missing error check 2012-10-31 10:02:55 -07:00
dcache.c dcache: Handle escaped paths in prepend_path 2015-10-22 09:20:08 +08:00
dcookies.c
direct-io.c fs: Fix possible use-after-free with AIO 2013-03-04 06:06:41 +08:00
drop_caches.c
eventfd.c
eventpoll.c epoll: prevent missed events on EPOLL_CTL_MOD 2013-01-17 08:50:54 -08:00
exec.c fs: take i_mutex during prepare_binprm for set[ug]id executables 2015-06-19 11:40:33 +08:00
fcntl.c
fhandle.c vfs: read file_handle only once in handle_to_path 2015-09-18 09:20:44 +08:00
fifo.c fifo: Do not restart open() if it already found a partner 2012-07-19 08:58:56 -07:00
file.c fs/file.c:fdtable: avoid triggering OOMs from alloc_fdmem 2014-02-22 10:32:45 -08:00
file_table.c get rid of s_files and files_lock 2016-03-21 09:17:55 +08:00
filesystems.c
fs-writeback.c writeback: fix a subtle race condition in I_DIRTY clearing 2015-04-14 17:33:41 +08:00
fs_struct.c The following text was taken from the original review request: 2012-03-24 10:24:31 -07:00
generic_acl.c
inode.c vfs: Revert spurious fix to spinning prevention in prune_icache_sb 2013-04-16 21:27:26 -07:00
internal.h get rid of s_files and files_lock 2016-03-21 09:17:55 +08:00
ioctl.c
ioprio.c block: Fix computation of merged request priority 2015-02-02 17:05:17 +08:00
Kconfig
Kconfig.binfmt
libfs.c move d_rcu from overlapping d_child to overlapping d_alias 2015-04-14 17:33:58 +08:00
locks.c locks: allow __break_lease to sleep even when break_time is 0 2014-05-13 14:11:31 +02:00
Makefile
mbcache.c
mount.h
mpage.c
namei.c vfs: Test for and handle paths that are unreachable from their mnt_root 2015-10-22 09:20:08 +08:00
namespace.c mnt: Prevent pivot_root from creating a loop in the mount tree 2015-02-02 17:04:50 +08:00
no-block.c
open.c get rid of s_files and files_lock 2016-03-21 09:17:55 +08:00
pipe.c pipe: Fix buffer offset after partially failed read 2016-04-27 18:55:30 +08:00
pnode.c get rid of propagate_umount() mistakenly treating slaves as busy. 2014-12-01 18:02:21 +08:00
pnode.h
posix_acl.c posix_acl: handle NULL ACL in posix_acl_equiv_mode 2014-06-07 16:02:02 -07:00
proc_namespace.c
read_write.c
read_write.h
readdir.c
select.c posix_types.h: Cleanup stale __NFDBITS and related definitions 2012-08-09 08:31:39 -07:00
seq_file.c The following text was taken from the original review request: 2012-03-24 10:24:31 -07:00
signalfd.c
splice.c splice: sendfile() at once fails for big files 2016-04-27 18:55:30 +08:00
stack.c
stat.c VFS: make vfs_fstat() use f[get|put]_light() 2014-06-07 16:02:04 -07:00
statfs.c vfs: allow O_PATH file descriptors for fstatfs() 2013-10-22 09:02:25 +01:00
super.c get rid of s_files and files_lock 2016-03-21 09:17:55 +08:00
sync.c
timerfd.c
utimes.c
xattr.c fs/xattr.c:setxattr(): improve handling of allocation failures 2012-04-05 15:25:50 -07:00
xattr_acl.c