Linux 4.4: Do not use splice()

splice() may return -ERESTARTSYS if there are pending signals, and
it's not even clear how this should be dealt with. This potential
problem has been present for a long time, but as of Linux 4.4
(commit c725bfce7968009756ed2836a8cd7ba4dc163011) seems much more
likely to happen.

Until resources are available to fix the code to handle such errors,
avoid the riskier uses of splice().

If there is a default implementation of file_splice_{write,read},
use that; on somewhat older kernels where it is not available,
use the generic version instead.

[kaduk@mit.edu: add test for default_file_splice_write]

Change-Id: Ib4477cdfb2cd0f49f516da75edc3cb9d1a8817dc
Reviewed-on: https://gerrit.openafs.org/12217
Reviewed-by: Chas Williams <3chas3@gmail.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
This commit is contained in:
Stephan Wiesand 2016-03-08 14:15:17 +01:00 committed by Benjamin Kaduk
parent 58d82226a5
commit ae5f411c3b
4 changed files with 9 additions and 4 deletions

View File

@ -1076,6 +1076,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
AC_CHECK_LINUX_FUNC([splice_direct_to_actor],
[#include <linux/splice.h>],
[splice_direct_to_actor(NULL,NULL,NULL);])
AC_CHECK_LINUX_FUNC([default_file_splice_read],
[#include <linux/fs.h>],
[default_file_splice_read(NULL,NULL,NULL, 0, 0);])
AC_CHECK_LINUX_FUNC([svc_addr_in],
[#include <linux/sunrpc/svc.h>],
[svc_addr_in(NULL);])

View File

@ -38,7 +38,7 @@
#include "afs/param.h"
#include <linux/fs.h>
#if defined(HAVE_LINUX_SPLICE_DIRECT_TO_ACTOR)
#if 0 && defined(HAVE_LINUX_SPLICE_DIRECT_TO_ACTOR)
# include <linux/splice.h>
#else
# include <linux/pipe_fs_i.h>
@ -47,7 +47,7 @@
#include "afs/sysincludes.h"
#include "afsincludes.h"
#if defined(HAVE_LINUX_SPLICE_DIRECT_TO_ACTOR)
#if 0 && defined(HAVE_LINUX_SPLICE_DIRECT_TO_ACTOR)
static int
afs_linux_splice_actor(struct pipe_inode_info *pipe,
struct pipe_buffer *buf,
@ -151,6 +151,7 @@ afs_linux_read_actor(read_descriptor_t *desc, struct page *page,
return size;
}
#if 0
afs_int32
afs_linux_storeproc(struct storeOps *ops, void *rock, struct dcache *tdc,
int *shouldwake, afs_size_t *bytesXferred)
@ -184,5 +185,6 @@ afs_linux_storeproc(struct storeOps *ops, void *rock, struct dcache *tdc,
return code;
}
#endif
#endif

View File

@ -846,7 +846,7 @@ struct file_operations afs_file_fops = {
#if defined(STRUCT_FILE_OPERATIONS_HAS_SENDFILE)
.sendfile = generic_file_sendfile,
#endif
#if defined(STRUCT_FILE_OPERATIONS_HAS_SPLICE)
#if defined(STRUCT_FILE_OPERATIONS_HAS_SPLICE) && !defined(HAVE_LINUX_DEFAULT_FILE_SPLICE_READ)
# if defined(HAVE_LINUX_ITER_FILE_SPLICE_WRITE)
.splice_write = iter_file_splice_write,
# else

View File

@ -326,7 +326,7 @@ struct storeOps rxfs_storeUfsOps = {
.padd = rxfs_storePadd,
.close = rxfs_storeClose,
.destroy = rxfs_storeDestroy,
#ifdef AFS_LINUX26_ENV
#if 0 && defined(AFS_LINUX26_ENV)
.storeproc = afs_linux_storeproc
#else
.storeproc = afs_GenericStoreProc