diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-09-17 20:44:45 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-03 20:40:55 -0400 |
commit | 8924feff66f35fe22ce77aafe3f21eb8e5cff881 (patch) | |
tree | 77d74a5edba4d1a30f484e0cffdecfcfcc113d79 /fs/fuse/dev.c | |
parent | db85a9eb2e364e24e71f94798e85dbaa8111bb4d (diff) | |
download | op-kernel-dev-8924feff66f35fe22ce77aafe3f21eb8e5cff881.zip op-kernel-dev-8924feff66f35fe22ce77aafe3f21eb8e5cff881.tar.gz |
splice: lift pipe_lock out of splice_to_pipe()
* splice_to_pipe() stops at pipe overflow and does *not* take pipe_lock
* ->splice_read() instances do the same
* vmsplice_to_pipe() and do_splice() (ultimate callers of splice_to_pipe())
arrange for waiting, looping, etc. themselves.
That should make pipe_lock the outermost one.
Unfortunately, existing rules for the amount passed by vmsplice_to_pipe()
and do_splice() are quite ugly _and_ userland code can be easily broken
by changing those. It's not even "no more than the maximal capacity of
this pipe" - it's "once we'd fed pipe->nr_buffers pages into the pipe,
leave instead of waiting".
Considering how poorly these rules are documented, let's try "wait for some
space to appear, unless given SPLICE_F_NONBLOCK, then push into pipe
and if we run into overflow, we are done".
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse/dev.c')
-rw-r--r-- | fs/fuse/dev.c | 2 |
1 files changed, 0 insertions, 2 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index a94d2ed..eaf56c6 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1364,7 +1364,6 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, goto out; ret = 0; - pipe_lock(pipe); if (!pipe->readers) { send_sig(SIGPIPE, current, 0); @@ -1400,7 +1399,6 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, } out_unlock: - pipe_unlock(pipe); if (do_wakeup) { smp_mb(); |