diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-09-17 22:56:25 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-03 20:40:56 -0400 |
commit | d82718e348fee15dbce8f578ff2588982b7cc7ca (patch) | |
tree | d9628878f9a140bef13a2e1e3c974aeb63451758 /fs/fuse | |
parent | 25869262ef7af24ccde988867ac3eb1c3d4b88d4 (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.c | 46 |
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 | |||
1401 | out_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; | ||
1410 | out: | 1382 | out: |
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); |