Message ID | d87ac02081f2d698dde10da7da51336afc59b480.1703126594.git.nabijaczleweli@nabijaczleweli.xyz |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-7774-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2483:b0:fb:cd0c:d3e with SMTP id q3csp155970dyi; Wed, 20 Dec 2023 19:09:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IFObRfQ0LuQ3EpCZkworfdtNMaCsjiKgdwZou7RNKbvZlNqtfp5QCpfniOQOgKZj9kck8c6 X-Received: by 2002:a05:6358:3423:b0:170:f159:d4bf with SMTP id h35-20020a056358342300b00170f159d4bfmr734850rwd.42.1703128173535; Wed, 20 Dec 2023 19:09:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1703128173; cv=none; d=google.com; s=arc-20160816; b=H1Q794EpgKfDay/CaUwvdNZ79aEqBTTfLf20utD9UKUcfDNxDNQp5hMiM0FQUixSSG iqlJ8tVubfpueRdXW7eSBPID7x1etUEiTnhsGTR5Ezwk9dtRKbmy65SxUvS785LWvmgN F1aZnzvCIx1oGzf9r5MHwAq+GRnXrREJmZkgNcPuQkAtPMwM535Smci7B6MI6bmKCexF t8LYzWmlBisnoG/XWM3SfTMe0NJjXWXFED0hA4E69JB4w9sKJpd20gUfafeN4ay8fnVP PDbsaD0ONZYSiIL7YWEyOunOcJ2t7hnv+pY9Yu7/bUEZXs80uYUpeqduvUs1d6ftBBJW 1nqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=user-agent:in-reply-to:content-disposition:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:references :message-id:subject:cc:from:date:dkim-signature; bh=puVy0eL4mazF3YfU0MnCZKxPvH+UcvA9zFvIXYJI8d8=; fh=1Wj/MAh+jnvZF/aMM1lYrKEgLZZd91YUwFaRXMvcDWA=; b=RDIAasniX1WV8R7HyRHcBt1Aw7NYQrrXmN1+4I2h4tqU+IBHfg+olZigmsmoEAGiqV ke0IzJ21GuAftnR7eH/BPjjiIk0jCrZihCrjBhntk6w5VTJidAMcs9rt5e+SaFrVzT4o Z5zucWNLMKiFIP3tR489cc0pVVifT4ETBpJ4fE6BWnb6lmXMcV0aTj7fpONttSegb6Am OFL4ng7Dj17gu/y4Ilg3tKApOLR7A/zuGuikGpGaYYJcINfrVO0BMRs+FyyH8CR5az2W K9rAEFBS5aF2USga5ZbZdQTlFQDt1Q+saBPYl1GV4x16uyWY4NgldwYfbkn45XQyTnSP CRUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nabijaczleweli.xyz header.s=202305 header.b=ediueyH5; spf=pass (google.com: domain of linux-kernel+bounces-7774-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-7774-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nabijaczleweli.xyz Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id s19-20020a05622a1a9300b004259cd2773asi1255643qtc.94.2023.12.20.19.09.33 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Dec 2023 19:09:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-7774-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@nabijaczleweli.xyz header.s=202305 header.b=ediueyH5; spf=pass (google.com: domain of linux-kernel+bounces-7774-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-7774-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nabijaczleweli.xyz Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 270B61C23EDE for <ouuuleilei@gmail.com>; Thu, 21 Dec 2023 03:09:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 60F6BAD21; Thu, 21 Dec 2023 03:08:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nabijaczleweli.xyz header.i=@nabijaczleweli.xyz header.b="ediueyH5" X-Original-To: linux-kernel@vger.kernel.org Received: from tarta.nabijaczleweli.xyz (tarta.nabijaczleweli.xyz [139.28.40.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C7224404; Thu, 21 Dec 2023 03:08:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nabijaczleweli.xyz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nabijaczleweli.xyz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nabijaczleweli.xyz; s=202305; t=1703128126; bh=ybIdi0gMPgMmtj3200db5CwiLm00xeI7NHXtjlFkAIo=; h=Date:From:Cc:Subject:References:In-Reply-To:From; b=ediueyH5QEM2+HRkyZx4r28DFAwiicXxhNwbwe+bf/itVrncIEDncK2IBL+WyxqsB WYQZaksBXFw8HKQyinNsue1UzUlAJDZmTfXW3mK7LckZfT+NZFPGKsAzVIubWuVTSa 7oD6Jr1u+OWvSjYK7r7jriaN6hUqfLfDexIcD8DNn8GVIRaAc9cOlpp9AkMzp8pq1+ gS/DzMM8Yl1z8jnWZLBE4McHEy+z4IqXKZayA/MANTXJvVGkWsdDD1wvykD9aKpfl4 ApOnk0BTRUEP3hXTrOlt6irzt2KC1KVqJdYwmzxYjErRDb8nhu0cnKgfT9yPNhmIdh /zoRAlkZpkvaA== Received: from tarta.nabijaczleweli.xyz (unknown [192.168.1.250]) by tarta.nabijaczleweli.xyz (Postfix) with ESMTPSA id F318313DAE; Thu, 21 Dec 2023 04:08:45 +0100 (CET) Date: Thu, 21 Dec 2023 04:08:45 +0100 From: Ahelenia =?utf-8?q?Ziemia=C5=84ska?= <nabijaczleweli@nabijaczleweli.xyz> Cc: Jens Axboe <axboe@kernel.dk>, Christian Brauner <brauner@kernel.org>, Alexander Viro <viro@zeniv.linux.org.uk>, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 01/11] splice: copy_splice_read: do the I/O with IOCB_NOWAIT Message-ID: <d87ac02081f2d698dde10da7da51336afc59b480.1703126594.git.nabijaczleweli@nabijaczleweli.xyz> References: <cover.1703126594.git.nabijaczleweli@nabijaczleweli.xyz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="w6med5uoq7ajniqd" Content-Disposition: inline In-Reply-To: <cover.1703126594.git.nabijaczleweli@nabijaczleweli.xyz> User-Agent: NeoMutt/20231103-116-3b855e-dirty X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1785859327720774106 X-GMAIL-MSGID: 1785859327720774106 |
Series |
Avoid unprivileged splice(file->)/(->socket) pipe exclusion
|
|
Commit Message
Ahelenia Ziemiańska
Dec. 21, 2023, 3:08 a.m. UTC
Otherwise we risk sleeping with the pipe locked for indeterminate
lengths of time ‒ given:
cat > udp.c <<^D
#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
int main()
{
int s = socket(AF_INET, SOCK_DGRAM, 0);
bind(s,
&(struct sockaddr_in){ .sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY) },
sizeof(struct sockaddr_in));
for (;;)
splice(s, 0, 1, 0, 128 * 1024 * 1024, 0);
}
^D
cc udp.c -o udp
mkfifo fifo
./udp > fifo &
read -r _ < fifo &
sleep 0.1
echo zupa > fifo
udp used to sleep in splice and the shell used to enter an
uninterruptible sleep in open("fifo");
now the splice returns -EAGAIN and the whole program completes.
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
---
fs/splice.c | 1 +
1 file changed, 1 insertion(+)
Comments
On Thu, Dec 21, 2023 at 04:08:45AM +0100, Ahelenia Ziemiańska wrote:
> Otherwise we risk sleeping with the pipe locked for indeterminate
You can't just assume that any ->read_iter support IOCB_NOWAIT.
On Thu, Dec 21, 2023 at 12:27:12AM -0800, Christoph Hellwig wrote: > On Thu, Dec 21, 2023 at 04:08:45AM +0100, Ahelenia Ziemiańska wrote: > > Otherwise we risk sleeping with the pipe locked for indeterminate > You can't just assume that any ->read_iter support IOCB_NOWAIT. Let's see. zero_fops drivers/char/mem.c: .splice_read = copy_splice_read, full_fops drivers/char/mem.c: .splice_read = copy_splice_read, random_fops drivers/char/random.c: .splice_read = copy_splice_read, random_read_iter checks urandom_fops drivers/char/random.c: .splice_read = copy_splice_read, urandom_read_iter returns instantly if ((in->f_flags & O_DIRECT) || IS_DAX(in->f_mapping->host)) fs/splice.c: return copy_splice_read(in, ppos, pipe, len, flags); FMODE_CAN_ODIRECT is set by filesystems and blockdevs, so trusted fs/9p/vfs_file.c: return copy_splice_read(in, ppos, pipe, len, flags); fs/ceph/file.c: return copy_splice_read(in, ppos, pipe, len, flags); fs/ceph/file.c: return copy_splice_read(in, ppos, pipe, len, flags); fs/gfs2/file.c: .splice_read = copy_splice_read, fs/gfs2/file.c: .splice_read = copy_splice_read, fs/kernfs/file.c: .splice_read = copy_splice_read, fs/smb/client/cifsfs.c: .splice_read = copy_splice_read, fs/smb/client/cifsfs.c: .splice_read = copy_splice_read, fs/proc/inode.c: .splice_read = copy_splice_read, fs/proc/inode.c: .splice_read = copy_splice_read, fs/proc/proc_sysctl.c: .splice_read = copy_splice_read, fs/proc_namespace.c: .splice_read = copy_splice_read, fs/proc_namespace.c: .splice_read = copy_splice_read, fs/proc_namespace.c: .splice_read = copy_splice_read, filesystems => trusted tracing_fops kernel/trace/trace.c: .splice_read = copy_splice_read, used in /sys/kernel/debug/tracing/per_cpu/cpu*/trace and /sys/kernel/debug/tracing/trace which are seq_read_iter and even if they did block, it's in tracefs so same logic as tracing_buffers_splice_read applies. net/socket.c: return copy_splice_read(file, ppos, pipe, len, flags); this is the default implementation for protocols without explicit splice_reads, and sock_read_iter translates IOCB_NOWAIT into MSG_DONTAIT. So I think I can, because the ~three implementations that we want to constrain do support it. If anything, this hints to me that to yield a more consistent API that doesn't arbitrarily distinguish between O_DIRECT files with and without IOCB_NOWAIT support, something to the effect of the following diff may be used. diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 11cd8d23f6f2..dc42837ee0af 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -392,7 +392,7 @@ static ssize_t v9fs_file_splice_read(struct file *in, loff_t *ppos, fid->fid, len, *ppos); if (fid->mode & P9L_DIRECT) - return copy_splice_read(in, ppos, pipe, len, flags); + return copy_splice_read_sleepok(in, ppos, pipe, len, flags); return filemap_splice_read(in, ppos, pipe, len, flags); } diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 3b5aae29e944..9a4679013135 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -2209,7 +2209,7 @@ static ssize_t ceph_splice_read(struct file *in, loff_t *ppos, if (ceph_has_inline_data(ci) || (fi->flags & CEPH_F_SYNC)) - return copy_splice_read(in, ppos, pipe, len, flags); + return copy_splice_read_sleepok(in, ppos, pipe, len, flags); ceph_start_io_read(inode); @@ -2228,7 +2228,7 @@ static ssize_t ceph_splice_read(struct file *in, loff_t *ppos, ceph_put_cap_refs(ci, got); ceph_end_io_read(inode); - return copy_splice_read(in, ppos, pipe, len, flags); + return copy_splice_read_sleepok(in, ppos, pipe, len, flags); } dout("splice_read %p %llx.%llx %llu~%zu got cap refs on %s\n", diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 4b66efc1a82a..5b0cbb6b95c4 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -1581,7 +1581,7 @@ const struct file_operations gfs2_file_fops = { .fsync = gfs2_fsync, .lock = gfs2_lock, .flock = gfs2_flock, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .splice_write = gfs2_file_splice_write, .setlease = simple_nosetlease, .fallocate = gfs2_fallocate, @@ -1612,7 +1612,7 @@ const struct file_operations gfs2_file_fops_nolock = { .open = gfs2_open, .release = gfs2_release, .fsync = gfs2_fsync, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .splice_write = gfs2_file_splice_write, .setlease = generic_setlease, .fallocate = gfs2_fallocate, diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index f0cb729e9a97..f0b6e85b2c5b 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -989,7 +989,7 @@ const struct file_operations kernfs_file_fops = { .release = kernfs_fop_release, .poll = kernfs_fop_poll, .fsync = noop_fsync, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .splice_write = iter_file_splice_write, }; diff --git a/fs/proc/inode.c b/fs/proc/inode.c index b33e490e3fd9..7ec2f4653299 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -588,7 +588,7 @@ static const struct file_operations proc_iter_file_ops = { .llseek = proc_reg_llseek, .read_iter = proc_reg_read_iter, .write = proc_reg_write, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .poll = proc_reg_poll, .unlocked_ioctl = proc_reg_unlocked_ioctl, .mmap = proc_reg_mmap, @@ -614,7 +614,7 @@ static const struct file_operations proc_reg_file_ops_compat = { static const struct file_operations proc_iter_file_ops_compat = { .llseek = proc_reg_llseek, .read_iter = proc_reg_read_iter, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .write = proc_reg_write, .poll = proc_reg_poll, .unlocked_ioctl = proc_reg_unlocked_ioctl, diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 8064ea76f80b..11d26fd14e7d 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -864,7 +864,7 @@ static const struct file_operations proc_sys_file_operations = { .poll = proc_sys_poll, .read_iter = proc_sys_read, .write_iter = proc_sys_write, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .splice_write = iter_file_splice_write, .llseek = default_llseek, }; diff --git a/fs/proc_namespace.c b/fs/proc_namespace.c index 250eb5bf7b52..e9d19a856dd7 100644 --- a/fs/proc_namespace.c +++ b/fs/proc_namespace.c @@ -324,7 +324,7 @@ static int mountstats_open(struct inode *inode, struct file *file) const struct file_operations proc_mounts_operations = { .open = mounts_open, .read_iter = seq_read_iter, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .llseek = seq_lseek, .release = mounts_release, .poll = mounts_poll, @@ -333,7 +333,7 @@ const struct file_operations proc_mounts_operations = { const struct file_operations proc_mountinfo_operations = { .open = mountinfo_open, .read_iter = seq_read_iter, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .llseek = seq_lseek, .release = mounts_release, .poll = mounts_poll, @@ -342,7 +342,7 @@ const struct file_operations proc_mountinfo_operations = { const struct file_operations proc_mountstats_operations = { .open = mountstats_open, .read_iter = seq_read_iter, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .llseek = seq_lseek, .release = mounts_release, }; diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 2131638f26d0..5f9fb3ce3bcb 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -1561,7 +1561,7 @@ const struct file_operations cifs_file_direct_ops = { .fsync = cifs_fsync, .flush = cifs_flush, .mmap = cifs_file_mmap, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .splice_write = iter_file_splice_write, .unlocked_ioctl = cifs_ioctl, .copy_file_range = cifs_copy_file_range, @@ -1615,7 +1615,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { .fsync = cifs_fsync, .flush = cifs_flush, .mmap = cifs_file_mmap, - .splice_read = copy_splice_read, + .splice_read = copy_splice_read_sleepok, .splice_write = iter_file_splice_write, .unlocked_ioctl = cifs_ioctl, .copy_file_range = cifs_copy_file_range, diff --git a/fs/splice.c b/fs/splice.c index 2871c6f9366f..90ebcf236c05 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -298,12 +298,14 @@ void splice_shrink_spd(struct splice_pipe_desc *spd) } /** - * copy_splice_read - Copy data from a file and splice the copy into a pipe + * __copy_splice_read - Copy data from a file and splice the copy into a pipe * @in: The file to read from * @ppos: Pointer to the file position to read from * @pipe: The pipe to splice into * @len: The amount to splice * @flags: The SPLICE_F_* flags + * @sleepok: Set if splicing from a trusted filesystem, + * don't set if splicing from an IPC mechanism * * This function allocates a bunch of pages sufficient to hold the requested * amount of data (but limited by the remaining pipe capacity), passes it to @@ -317,10 +319,11 @@ void splice_shrink_spd(struct splice_pipe_desc *spd) * if the pipe has insufficient space, we reach the end of the data or we hit a * hole. */ -ssize_t copy_splice_read(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, - size_t len, unsigned int flags) +static ssize_t __copy_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, unsigned int flags, bool sleepok) { + printk("__copy_splice_read(%d)\n", sleepok); struct iov_iter to; struct bio_vec *bv; struct kiocb kiocb; @@ -361,7 +364,8 @@ ssize_t copy_splice_read(struct file *in, loff_t *ppos, iov_iter_bvec(&to, ITER_DEST, bv, npages, len); init_sync_kiocb(&kiocb, in); kiocb.ki_pos = *ppos; - kiocb.ki_flags |= IOCB_NOWAIT; + if (!sleepok) + kiocb.ki_flags |= IOCB_NOWAIT; ret = call_read_iter(in, &kiocb, &to); if (ret > 0) { @@ -399,8 +403,21 @@ ssize_t copy_splice_read(struct file *in, loff_t *ppos, kfree(bv); return ret; } + +ssize_t copy_splice_read(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, unsigned int flags) { + return __copy_splice_read(in, ppos, pipe, len, flags, false); +} EXPORT_SYMBOL(copy_splice_read); +ssize_t copy_splice_read_sleepok(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, unsigned int flags) { + return __copy_splice_read(in, ppos, pipe, len, flags, true); +} +EXPORT_SYMBOL(copy_splice_read_sleepok); + const struct pipe_buf_operations default_pipe_buf_ops = { .release = generic_pipe_buf_release, .try_steal = generic_pipe_buf_try_steal, @@ -988,7 +1005,7 @@ long vfs_splice_read(struct file *in, loff_t *ppos, * buffer, copy into it and splice that into the pipe. */ if ((in->f_flags & O_DIRECT) || IS_DAX(in->f_mapping->host)) - return copy_splice_read(in, ppos, pipe, len, flags); + return copy_splice_read_sleepok(in, ppos, pipe, len, flags); return in->f_op->splice_read(in, ppos, pipe, len, flags); } EXPORT_SYMBOL_GPL(vfs_splice_read); diff --git a/include/linux/fs.h b/include/linux/fs.h index 98b7a7a8c42e..0980bf6ba8fd 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2989,6 +2989,9 @@ ssize_t filemap_splice_read(struct file *in, loff_t *ppos, ssize_t copy_splice_read(struct file *in, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); +ssize_t copy_splice_read_sleepok(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t len, unsigned int flags); extern ssize_t iter_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
diff --git a/fs/splice.c b/fs/splice.c index d983d375ff11..9d29664f23ee 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -361,6 +361,7 @@ ssize_t copy_splice_read(struct file *in, loff_t *ppos, iov_iter_bvec(&to, ITER_DEST, bv, npages, len); init_sync_kiocb(&kiocb, in); kiocb.ki_pos = *ppos; + kiocb.ki_flags |= IOCB_NOWAIT; ret = call_read_iter(in, &kiocb, &to); if (ret > 0) {