summaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-09-17 22:56:25 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-10-03 20:40:56 -0400
commitd82718e348fee15dbce8f578ff2588982b7cc7ca (patch)
treed9628878f9a140bef13a2e1e3c974aeb63451758 /fs/fuse
parent25869262ef7af24ccde988867ac3eb1c3d4b88d4 (diff)
fuse_dev_splice_read(): switch to add_to_pipe()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/dev.c46
1 files changed, 9 insertions, 37 deletions
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index eaf56c6e9123..0a6a808d561c 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1342,9 +1342,8 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1342 struct pipe_inode_info *pipe, 1342 struct pipe_inode_info *pipe,
1343 size_t len, unsigned int flags) 1343 size_t len, unsigned int flags)
1344{ 1344{
1345 int ret; 1345 int total, ret;
1346 int page_nr = 0; 1346 int page_nr = 0;
1347 int do_wakeup = 0;
1348 struct pipe_buffer *bufs; 1347 struct pipe_buffer *bufs;
1349 struct fuse_copy_state cs; 1348 struct fuse_copy_state cs;
1350 struct fuse_dev *fud = fuse_get_dev(in); 1349 struct fuse_dev *fud = fuse_get_dev(in);
@@ -1363,50 +1362,23 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
1363 if (ret < 0) 1362 if (ret < 0)
1364 goto out; 1363 goto out;
1365 1364
1366 ret = 0;
1367
1368 if (!pipe->readers) {
1369 send_sig(SIGPIPE, current, 0);
1370 if (!ret)
1371 ret = -EPIPE;
1372 goto out_unlock;
1373 }
1374
1375 if (pipe->nrbufs + cs.nr_segs > pipe->buffers) { 1365 if (pipe->nrbufs + cs.nr_segs > pipe->buffers) {
1376 ret = -EIO; 1366 ret = -EIO;
1377 goto out_unlock; 1367 goto out;
1378 } 1368 }
1379 1369
1380 while (page_nr < cs.nr_segs) { 1370 for (ret = total = 0; page_nr < cs.nr_segs; total += ret) {
1381 int newbuf = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1);
1382 struct pipe_buffer *buf = pipe->bufs + newbuf;
1383
1384 buf->page = bufs[page_nr].page;
1385 buf->offset = bufs[page_nr].offset;
1386 buf->len = bufs[page_nr].len;
1387 /* 1371 /*
1388 * Need to be careful about this. Having buf->ops in module 1372 * Need to be careful about this. Having buf->ops in module
1389 * code can Oops if the buffer persists after module unload. 1373 * code can Oops if the buffer persists after module unload.
1390 */ 1374 */
1391 buf->ops = &nosteal_pipe_buf_ops; 1375 bufs[page_nr].ops = &nosteal_pipe_buf_ops;
1392 1376 ret = add_to_pipe(pipe, &bufs[page_nr++]);
1393 pipe->nrbufs++; 1377 if (unlikely(ret < 0))
1394 page_nr++; 1378 break;
1395 ret += buf->len;
1396
1397 if (pipe->files)
1398 do_wakeup = 1;
1399 }
1400
1401out_unlock:
1402
1403 if (do_wakeup) {
1404 smp_mb();
1405 if (waitqueue_active(&pipe->wait))
1406 wake_up_interruptible(&pipe->wait);
1407 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1408 } 1379 }
1409 1380 if (total)
1381 ret = total;
1410out: 1382out:
1411 for (; page_nr < cs.nr_segs; page_nr++) 1383 for (; page_nr < cs.nr_segs; page_nr++)
1412 put_page(bufs[page_nr].page); 1384 put_page(bufs[page_nr].page);