18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * "splice": joining two ropes together by interweaving their strands.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * This is the "extended pipe" functionality, where a pipe is used as
68c2ecf20Sopenharmony_ci * an arbitrary in-memory buffer. Think of a pipe as a small kernel
78c2ecf20Sopenharmony_ci * buffer that you can use to transfer data from one end to the other.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * The traditional unix read/write is extended with a "splice()" operation
108c2ecf20Sopenharmony_ci * that transfers data buffers to or from a pipe buffer.
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * Named by Larry McVoy, original implementation from Linus, extended by
138c2ecf20Sopenharmony_ci * Jens to support splicing to files, network, direct splicing, etc and
148c2ecf20Sopenharmony_ci * fixing lots of bugs.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * Copyright (C) 2005-2006 Jens Axboe <axboe@kernel.dk>
178c2ecf20Sopenharmony_ci * Copyright (C) 2005-2006 Linus Torvalds <torvalds@osdl.org>
188c2ecf20Sopenharmony_ci * Copyright (C) 2006 Ingo Molnar <mingo@elte.hu>
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci */
218c2ecf20Sopenharmony_ci#include <linux/bvec.h>
228c2ecf20Sopenharmony_ci#include <linux/fs.h>
238c2ecf20Sopenharmony_ci#include <linux/file.h>
248c2ecf20Sopenharmony_ci#include <linux/pagemap.h>
258c2ecf20Sopenharmony_ci#include <linux/splice.h>
268c2ecf20Sopenharmony_ci#include <linux/memcontrol.h>
278c2ecf20Sopenharmony_ci#include <linux/mm_inline.h>
288c2ecf20Sopenharmony_ci#include <linux/swap.h>
298c2ecf20Sopenharmony_ci#include <linux/writeback.h>
308c2ecf20Sopenharmony_ci#include <linux/export.h>
318c2ecf20Sopenharmony_ci#include <linux/syscalls.h>
328c2ecf20Sopenharmony_ci#include <linux/uio.h>
338c2ecf20Sopenharmony_ci#include <linux/security.h>
348c2ecf20Sopenharmony_ci#include <linux/gfp.h>
358c2ecf20Sopenharmony_ci#include <linux/socket.h>
368c2ecf20Sopenharmony_ci#include <linux/sched/signal.h>
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#include "internal.h"
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*
418c2ecf20Sopenharmony_ci * Attempt to steal a page from a pipe buffer. This should perhaps go into
428c2ecf20Sopenharmony_ci * a vm helper function, it's already simplified quite a bit by the
438c2ecf20Sopenharmony_ci * addition of remove_mapping(). If success is returned, the caller may
448c2ecf20Sopenharmony_ci * attempt to reuse this page for another destination.
458c2ecf20Sopenharmony_ci */
468c2ecf20Sopenharmony_cistatic bool page_cache_pipe_buf_try_steal(struct pipe_inode_info *pipe,
478c2ecf20Sopenharmony_ci		struct pipe_buffer *buf)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	struct page *page = buf->page;
508c2ecf20Sopenharmony_ci	struct address_space *mapping;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	lock_page(page);
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	mapping = page_mapping(page);
558c2ecf20Sopenharmony_ci	if (mapping) {
568c2ecf20Sopenharmony_ci		WARN_ON(!PageUptodate(page));
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci		/*
598c2ecf20Sopenharmony_ci		 * At least for ext2 with nobh option, we need to wait on
608c2ecf20Sopenharmony_ci		 * writeback completing on this page, since we'll remove it
618c2ecf20Sopenharmony_ci		 * from the pagecache.  Otherwise truncate wont wait on the
628c2ecf20Sopenharmony_ci		 * page, allowing the disk blocks to be reused by someone else
638c2ecf20Sopenharmony_ci		 * before we actually wrote our data to them. fs corruption
648c2ecf20Sopenharmony_ci		 * ensues.
658c2ecf20Sopenharmony_ci		 */
668c2ecf20Sopenharmony_ci		wait_on_page_writeback(page);
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci		if (page_has_private(page) &&
698c2ecf20Sopenharmony_ci		    !try_to_release_page(page, GFP_KERNEL))
708c2ecf20Sopenharmony_ci			goto out_unlock;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci		/*
738c2ecf20Sopenharmony_ci		 * If we succeeded in removing the mapping, set LRU flag
748c2ecf20Sopenharmony_ci		 * and return good.
758c2ecf20Sopenharmony_ci		 */
768c2ecf20Sopenharmony_ci		if (remove_mapping(mapping, page)) {
778c2ecf20Sopenharmony_ci			buf->flags |= PIPE_BUF_FLAG_LRU;
788c2ecf20Sopenharmony_ci			return true;
798c2ecf20Sopenharmony_ci		}
808c2ecf20Sopenharmony_ci	}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	/*
838c2ecf20Sopenharmony_ci	 * Raced with truncate or failed to remove page from current
848c2ecf20Sopenharmony_ci	 * address space, unlock and return failure.
858c2ecf20Sopenharmony_ci	 */
868c2ecf20Sopenharmony_ciout_unlock:
878c2ecf20Sopenharmony_ci	unlock_page(page);
888c2ecf20Sopenharmony_ci	return false;
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic void page_cache_pipe_buf_release(struct pipe_inode_info *pipe,
928c2ecf20Sopenharmony_ci					struct pipe_buffer *buf)
938c2ecf20Sopenharmony_ci{
948c2ecf20Sopenharmony_ci	put_page(buf->page);
958c2ecf20Sopenharmony_ci	buf->flags &= ~PIPE_BUF_FLAG_LRU;
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci/*
998c2ecf20Sopenharmony_ci * Check whether the contents of buf is OK to access. Since the content
1008c2ecf20Sopenharmony_ci * is a page cache page, IO may be in flight.
1018c2ecf20Sopenharmony_ci */
1028c2ecf20Sopenharmony_cistatic int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe,
1038c2ecf20Sopenharmony_ci				       struct pipe_buffer *buf)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	struct page *page = buf->page;
1068c2ecf20Sopenharmony_ci	int err;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	if (!PageUptodate(page)) {
1098c2ecf20Sopenharmony_ci		lock_page(page);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci		/*
1128c2ecf20Sopenharmony_ci		 * Page got truncated/unhashed. This will cause a 0-byte
1138c2ecf20Sopenharmony_ci		 * splice, if this is the first page.
1148c2ecf20Sopenharmony_ci		 */
1158c2ecf20Sopenharmony_ci		if (!page->mapping) {
1168c2ecf20Sopenharmony_ci			err = -ENODATA;
1178c2ecf20Sopenharmony_ci			goto error;
1188c2ecf20Sopenharmony_ci		}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci		/*
1218c2ecf20Sopenharmony_ci		 * Uh oh, read-error from disk.
1228c2ecf20Sopenharmony_ci		 */
1238c2ecf20Sopenharmony_ci		if (!PageUptodate(page)) {
1248c2ecf20Sopenharmony_ci			err = -EIO;
1258c2ecf20Sopenharmony_ci			goto error;
1268c2ecf20Sopenharmony_ci		}
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci		/*
1298c2ecf20Sopenharmony_ci		 * Page is ok afterall, we are done.
1308c2ecf20Sopenharmony_ci		 */
1318c2ecf20Sopenharmony_ci		unlock_page(page);
1328c2ecf20Sopenharmony_ci	}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	return 0;
1358c2ecf20Sopenharmony_cierror:
1368c2ecf20Sopenharmony_ci	unlock_page(page);
1378c2ecf20Sopenharmony_ci	return err;
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ciconst struct pipe_buf_operations page_cache_pipe_buf_ops = {
1418c2ecf20Sopenharmony_ci	.confirm	= page_cache_pipe_buf_confirm,
1428c2ecf20Sopenharmony_ci	.release	= page_cache_pipe_buf_release,
1438c2ecf20Sopenharmony_ci	.try_steal	= page_cache_pipe_buf_try_steal,
1448c2ecf20Sopenharmony_ci	.get		= generic_pipe_buf_get,
1458c2ecf20Sopenharmony_ci};
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_cistatic bool user_page_pipe_buf_try_steal(struct pipe_inode_info *pipe,
1488c2ecf20Sopenharmony_ci		struct pipe_buffer *buf)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	if (!(buf->flags & PIPE_BUF_FLAG_GIFT))
1518c2ecf20Sopenharmony_ci		return false;
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci	buf->flags |= PIPE_BUF_FLAG_LRU;
1548c2ecf20Sopenharmony_ci	return generic_pipe_buf_try_steal(pipe, buf);
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic const struct pipe_buf_operations user_page_pipe_buf_ops = {
1588c2ecf20Sopenharmony_ci	.release	= page_cache_pipe_buf_release,
1598c2ecf20Sopenharmony_ci	.try_steal	= user_page_pipe_buf_try_steal,
1608c2ecf20Sopenharmony_ci	.get		= generic_pipe_buf_get,
1618c2ecf20Sopenharmony_ci};
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic void wakeup_pipe_readers(struct pipe_inode_info *pipe)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	smp_mb();
1668c2ecf20Sopenharmony_ci	if (waitqueue_active(&pipe->rd_wait))
1678c2ecf20Sopenharmony_ci		wake_up_interruptible(&pipe->rd_wait);
1688c2ecf20Sopenharmony_ci	kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
1698c2ecf20Sopenharmony_ci}
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci/**
1728c2ecf20Sopenharmony_ci * splice_to_pipe - fill passed data into a pipe
1738c2ecf20Sopenharmony_ci * @pipe:	pipe to fill
1748c2ecf20Sopenharmony_ci * @spd:	data to fill
1758c2ecf20Sopenharmony_ci *
1768c2ecf20Sopenharmony_ci * Description:
1778c2ecf20Sopenharmony_ci *    @spd contains a map of pages and len/offset tuples, along with
1788c2ecf20Sopenharmony_ci *    the struct pipe_buf_operations associated with these pages. This
1798c2ecf20Sopenharmony_ci *    function will link that data to the pipe.
1808c2ecf20Sopenharmony_ci *
1818c2ecf20Sopenharmony_ci */
1828c2ecf20Sopenharmony_cissize_t splice_to_pipe(struct pipe_inode_info *pipe,
1838c2ecf20Sopenharmony_ci		       struct splice_pipe_desc *spd)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	unsigned int spd_pages = spd->nr_pages;
1868c2ecf20Sopenharmony_ci	unsigned int tail = pipe->tail;
1878c2ecf20Sopenharmony_ci	unsigned int head = pipe->head;
1888c2ecf20Sopenharmony_ci	unsigned int mask = pipe->ring_size - 1;
1898c2ecf20Sopenharmony_ci	int ret = 0, page_nr = 0;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	if (!spd_pages)
1928c2ecf20Sopenharmony_ci		return 0;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	if (unlikely(!pipe->readers)) {
1958c2ecf20Sopenharmony_ci		send_sig(SIGPIPE, current, 0);
1968c2ecf20Sopenharmony_ci		ret = -EPIPE;
1978c2ecf20Sopenharmony_ci		goto out;
1988c2ecf20Sopenharmony_ci	}
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	while (!pipe_full(head, tail, pipe->max_usage)) {
2018c2ecf20Sopenharmony_ci		struct pipe_buffer *buf = &pipe->bufs[head & mask];
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci		buf->page = spd->pages[page_nr];
2048c2ecf20Sopenharmony_ci		buf->offset = spd->partial[page_nr].offset;
2058c2ecf20Sopenharmony_ci		buf->len = spd->partial[page_nr].len;
2068c2ecf20Sopenharmony_ci		buf->private = spd->partial[page_nr].private;
2078c2ecf20Sopenharmony_ci		buf->ops = spd->ops;
2088c2ecf20Sopenharmony_ci		buf->flags = 0;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci		head++;
2118c2ecf20Sopenharmony_ci		pipe->head = head;
2128c2ecf20Sopenharmony_ci		page_nr++;
2138c2ecf20Sopenharmony_ci		ret += buf->len;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci		if (!--spd->nr_pages)
2168c2ecf20Sopenharmony_ci			break;
2178c2ecf20Sopenharmony_ci	}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	if (!ret)
2208c2ecf20Sopenharmony_ci		ret = -EAGAIN;
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ciout:
2238c2ecf20Sopenharmony_ci	while (page_nr < spd_pages)
2248c2ecf20Sopenharmony_ci		spd->spd_release(spd, page_nr++);
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	return ret;
2278c2ecf20Sopenharmony_ci}
2288c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(splice_to_pipe);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_cissize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
2318c2ecf20Sopenharmony_ci{
2328c2ecf20Sopenharmony_ci	unsigned int head = pipe->head;
2338c2ecf20Sopenharmony_ci	unsigned int tail = pipe->tail;
2348c2ecf20Sopenharmony_ci	unsigned int mask = pipe->ring_size - 1;
2358c2ecf20Sopenharmony_ci	int ret;
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	if (unlikely(!pipe->readers)) {
2388c2ecf20Sopenharmony_ci		send_sig(SIGPIPE, current, 0);
2398c2ecf20Sopenharmony_ci		ret = -EPIPE;
2408c2ecf20Sopenharmony_ci	} else if (pipe_full(head, tail, pipe->max_usage)) {
2418c2ecf20Sopenharmony_ci		ret = -EAGAIN;
2428c2ecf20Sopenharmony_ci	} else {
2438c2ecf20Sopenharmony_ci		pipe->bufs[head & mask] = *buf;
2448c2ecf20Sopenharmony_ci		pipe->head = head + 1;
2458c2ecf20Sopenharmony_ci		return buf->len;
2468c2ecf20Sopenharmony_ci	}
2478c2ecf20Sopenharmony_ci	pipe_buf_release(pipe, buf);
2488c2ecf20Sopenharmony_ci	return ret;
2498c2ecf20Sopenharmony_ci}
2508c2ecf20Sopenharmony_ciEXPORT_SYMBOL(add_to_pipe);
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci/*
2538c2ecf20Sopenharmony_ci * Check if we need to grow the arrays holding pages and partial page
2548c2ecf20Sopenharmony_ci * descriptions.
2558c2ecf20Sopenharmony_ci */
2568c2ecf20Sopenharmony_ciint splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	unsigned int max_usage = READ_ONCE(pipe->max_usage);
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	spd->nr_pages_max = max_usage;
2618c2ecf20Sopenharmony_ci	if (max_usage <= PIPE_DEF_BUFFERS)
2628c2ecf20Sopenharmony_ci		return 0;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	spd->pages = kmalloc_array(max_usage, sizeof(struct page *), GFP_KERNEL);
2658c2ecf20Sopenharmony_ci	spd->partial = kmalloc_array(max_usage, sizeof(struct partial_page),
2668c2ecf20Sopenharmony_ci				     GFP_KERNEL);
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	if (spd->pages && spd->partial)
2698c2ecf20Sopenharmony_ci		return 0;
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	kfree(spd->pages);
2728c2ecf20Sopenharmony_ci	kfree(spd->partial);
2738c2ecf20Sopenharmony_ci	return -ENOMEM;
2748c2ecf20Sopenharmony_ci}
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_civoid splice_shrink_spd(struct splice_pipe_desc *spd)
2778c2ecf20Sopenharmony_ci{
2788c2ecf20Sopenharmony_ci	if (spd->nr_pages_max <= PIPE_DEF_BUFFERS)
2798c2ecf20Sopenharmony_ci		return;
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	kfree(spd->pages);
2828c2ecf20Sopenharmony_ci	kfree(spd->partial);
2838c2ecf20Sopenharmony_ci}
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci/**
2868c2ecf20Sopenharmony_ci * generic_file_splice_read - splice data from file to a pipe
2878c2ecf20Sopenharmony_ci * @in:		file to splice from
2888c2ecf20Sopenharmony_ci * @ppos:	position in @in
2898c2ecf20Sopenharmony_ci * @pipe:	pipe to splice to
2908c2ecf20Sopenharmony_ci * @len:	number of bytes to splice
2918c2ecf20Sopenharmony_ci * @flags:	splice modifier flags
2928c2ecf20Sopenharmony_ci *
2938c2ecf20Sopenharmony_ci * Description:
2948c2ecf20Sopenharmony_ci *    Will read pages from given file and fill them into a pipe. Can be
2958c2ecf20Sopenharmony_ci *    used as long as it has more or less sane ->read_iter().
2968c2ecf20Sopenharmony_ci *
2978c2ecf20Sopenharmony_ci */
2988c2ecf20Sopenharmony_cissize_t generic_file_splice_read(struct file *in, loff_t *ppos,
2998c2ecf20Sopenharmony_ci				 struct pipe_inode_info *pipe, size_t len,
3008c2ecf20Sopenharmony_ci				 unsigned int flags)
3018c2ecf20Sopenharmony_ci{
3028c2ecf20Sopenharmony_ci	struct iov_iter to;
3038c2ecf20Sopenharmony_ci	struct kiocb kiocb;
3048c2ecf20Sopenharmony_ci	unsigned int i_head;
3058c2ecf20Sopenharmony_ci	int ret;
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	iov_iter_pipe(&to, READ, pipe, len);
3088c2ecf20Sopenharmony_ci	i_head = to.head;
3098c2ecf20Sopenharmony_ci	init_sync_kiocb(&kiocb, in);
3108c2ecf20Sopenharmony_ci	kiocb.ki_pos = *ppos;
3118c2ecf20Sopenharmony_ci	ret = call_read_iter(in, &kiocb, &to);
3128c2ecf20Sopenharmony_ci	if (ret > 0) {
3138c2ecf20Sopenharmony_ci		*ppos = kiocb.ki_pos;
3148c2ecf20Sopenharmony_ci		file_accessed(in);
3158c2ecf20Sopenharmony_ci	} else if (ret < 0) {
3168c2ecf20Sopenharmony_ci		to.head = i_head;
3178c2ecf20Sopenharmony_ci		to.iov_offset = 0;
3188c2ecf20Sopenharmony_ci		iov_iter_advance(&to, 0); /* to free what was emitted */
3198c2ecf20Sopenharmony_ci		/*
3208c2ecf20Sopenharmony_ci		 * callers of ->splice_read() expect -EAGAIN on
3218c2ecf20Sopenharmony_ci		 * "can't put anything in there", rather than -EFAULT.
3228c2ecf20Sopenharmony_ci		 */
3238c2ecf20Sopenharmony_ci		if (ret == -EFAULT)
3248c2ecf20Sopenharmony_ci			ret = -EAGAIN;
3258c2ecf20Sopenharmony_ci	}
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	return ret;
3288c2ecf20Sopenharmony_ci}
3298c2ecf20Sopenharmony_ciEXPORT_SYMBOL(generic_file_splice_read);
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ciconst struct pipe_buf_operations default_pipe_buf_ops = {
3328c2ecf20Sopenharmony_ci	.release	= generic_pipe_buf_release,
3338c2ecf20Sopenharmony_ci	.try_steal	= generic_pipe_buf_try_steal,
3348c2ecf20Sopenharmony_ci	.get		= generic_pipe_buf_get,
3358c2ecf20Sopenharmony_ci};
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci/* Pipe buffer operations for a socket and similar. */
3388c2ecf20Sopenharmony_ciconst struct pipe_buf_operations nosteal_pipe_buf_ops = {
3398c2ecf20Sopenharmony_ci	.release	= generic_pipe_buf_release,
3408c2ecf20Sopenharmony_ci	.get		= generic_pipe_buf_get,
3418c2ecf20Sopenharmony_ci};
3428c2ecf20Sopenharmony_ciEXPORT_SYMBOL(nosteal_pipe_buf_ops);
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_ci/*
3458c2ecf20Sopenharmony_ci * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos'
3468c2ecf20Sopenharmony_ci * using sendpage(). Return the number of bytes sent.
3478c2ecf20Sopenharmony_ci */
3488c2ecf20Sopenharmony_cistatic int pipe_to_sendpage(struct pipe_inode_info *pipe,
3498c2ecf20Sopenharmony_ci			    struct pipe_buffer *buf, struct splice_desc *sd)
3508c2ecf20Sopenharmony_ci{
3518c2ecf20Sopenharmony_ci	struct file *file = sd->u.file;
3528c2ecf20Sopenharmony_ci	loff_t pos = sd->pos;
3538c2ecf20Sopenharmony_ci	int more;
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci	if (!likely(file->f_op->sendpage))
3568c2ecf20Sopenharmony_ci		return -EINVAL;
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci	more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	if (sd->len < sd->total_len &&
3618c2ecf20Sopenharmony_ci	    pipe_occupancy(pipe->head, pipe->tail) > 1)
3628c2ecf20Sopenharmony_ci		more |= MSG_SENDPAGE_NOTLAST;
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ci	return file->f_op->sendpage(file, buf->page, buf->offset,
3658c2ecf20Sopenharmony_ci				    sd->len, &pos, more);
3668c2ecf20Sopenharmony_ci}
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_cistatic void wakeup_pipe_writers(struct pipe_inode_info *pipe)
3698c2ecf20Sopenharmony_ci{
3708c2ecf20Sopenharmony_ci	smp_mb();
3718c2ecf20Sopenharmony_ci	if (waitqueue_active(&pipe->wr_wait))
3728c2ecf20Sopenharmony_ci		wake_up_interruptible(&pipe->wr_wait);
3738c2ecf20Sopenharmony_ci	kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
3748c2ecf20Sopenharmony_ci}
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci/**
3778c2ecf20Sopenharmony_ci * splice_from_pipe_feed - feed available data from a pipe to a file
3788c2ecf20Sopenharmony_ci * @pipe:	pipe to splice from
3798c2ecf20Sopenharmony_ci * @sd:		information to @actor
3808c2ecf20Sopenharmony_ci * @actor:	handler that splices the data
3818c2ecf20Sopenharmony_ci *
3828c2ecf20Sopenharmony_ci * Description:
3838c2ecf20Sopenharmony_ci *    This function loops over the pipe and calls @actor to do the
3848c2ecf20Sopenharmony_ci *    actual moving of a single struct pipe_buffer to the desired
3858c2ecf20Sopenharmony_ci *    destination.  It returns when there's no more buffers left in
3868c2ecf20Sopenharmony_ci *    the pipe or if the requested number of bytes (@sd->total_len)
3878c2ecf20Sopenharmony_ci *    have been copied.  It returns a positive number (one) if the
3888c2ecf20Sopenharmony_ci *    pipe needs to be filled with more data, zero if the required
3898c2ecf20Sopenharmony_ci *    number of bytes have been copied and -errno on error.
3908c2ecf20Sopenharmony_ci *
3918c2ecf20Sopenharmony_ci *    This, together with splice_from_pipe_{begin,end,next}, may be
3928c2ecf20Sopenharmony_ci *    used to implement the functionality of __splice_from_pipe() when
3938c2ecf20Sopenharmony_ci *    locking is required around copying the pipe buffers to the
3948c2ecf20Sopenharmony_ci *    destination.
3958c2ecf20Sopenharmony_ci */
3968c2ecf20Sopenharmony_cistatic int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd,
3978c2ecf20Sopenharmony_ci			  splice_actor *actor)
3988c2ecf20Sopenharmony_ci{
3998c2ecf20Sopenharmony_ci	unsigned int head = pipe->head;
4008c2ecf20Sopenharmony_ci	unsigned int tail = pipe->tail;
4018c2ecf20Sopenharmony_ci	unsigned int mask = pipe->ring_size - 1;
4028c2ecf20Sopenharmony_ci	int ret;
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	while (!pipe_empty(head, tail)) {
4058c2ecf20Sopenharmony_ci		struct pipe_buffer *buf = &pipe->bufs[tail & mask];
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci		sd->len = buf->len;
4088c2ecf20Sopenharmony_ci		if (sd->len > sd->total_len)
4098c2ecf20Sopenharmony_ci			sd->len = sd->total_len;
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci		ret = pipe_buf_confirm(pipe, buf);
4128c2ecf20Sopenharmony_ci		if (unlikely(ret)) {
4138c2ecf20Sopenharmony_ci			if (ret == -ENODATA)
4148c2ecf20Sopenharmony_ci				ret = 0;
4158c2ecf20Sopenharmony_ci			return ret;
4168c2ecf20Sopenharmony_ci		}
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci		ret = actor(pipe, buf, sd);
4198c2ecf20Sopenharmony_ci		if (ret <= 0)
4208c2ecf20Sopenharmony_ci			return ret;
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_ci		buf->offset += ret;
4238c2ecf20Sopenharmony_ci		buf->len -= ret;
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci		sd->num_spliced += ret;
4268c2ecf20Sopenharmony_ci		sd->len -= ret;
4278c2ecf20Sopenharmony_ci		sd->pos += ret;
4288c2ecf20Sopenharmony_ci		sd->total_len -= ret;
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci		if (!buf->len) {
4318c2ecf20Sopenharmony_ci			pipe_buf_release(pipe, buf);
4328c2ecf20Sopenharmony_ci			tail++;
4338c2ecf20Sopenharmony_ci			pipe->tail = tail;
4348c2ecf20Sopenharmony_ci			if (pipe->files)
4358c2ecf20Sopenharmony_ci				sd->need_wakeup = true;
4368c2ecf20Sopenharmony_ci		}
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci		if (!sd->total_len)
4398c2ecf20Sopenharmony_ci			return 0;
4408c2ecf20Sopenharmony_ci	}
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	return 1;
4438c2ecf20Sopenharmony_ci}
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci/* We know we have a pipe buffer, but maybe it's empty? */
4468c2ecf20Sopenharmony_cistatic inline bool eat_empty_buffer(struct pipe_inode_info *pipe)
4478c2ecf20Sopenharmony_ci{
4488c2ecf20Sopenharmony_ci	unsigned int tail = pipe->tail;
4498c2ecf20Sopenharmony_ci	unsigned int mask = pipe->ring_size - 1;
4508c2ecf20Sopenharmony_ci	struct pipe_buffer *buf = &pipe->bufs[tail & mask];
4518c2ecf20Sopenharmony_ci
4528c2ecf20Sopenharmony_ci	if (unlikely(!buf->len)) {
4538c2ecf20Sopenharmony_ci		pipe_buf_release(pipe, buf);
4548c2ecf20Sopenharmony_ci		pipe->tail = tail+1;
4558c2ecf20Sopenharmony_ci		return true;
4568c2ecf20Sopenharmony_ci	}
4578c2ecf20Sopenharmony_ci
4588c2ecf20Sopenharmony_ci	return false;
4598c2ecf20Sopenharmony_ci}
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci/**
4628c2ecf20Sopenharmony_ci * splice_from_pipe_next - wait for some data to splice from
4638c2ecf20Sopenharmony_ci * @pipe:	pipe to splice from
4648c2ecf20Sopenharmony_ci * @sd:		information about the splice operation
4658c2ecf20Sopenharmony_ci *
4668c2ecf20Sopenharmony_ci * Description:
4678c2ecf20Sopenharmony_ci *    This function will wait for some data and return a positive
4688c2ecf20Sopenharmony_ci *    value (one) if pipe buffers are available.  It will return zero
4698c2ecf20Sopenharmony_ci *    or -errno if no more data needs to be spliced.
4708c2ecf20Sopenharmony_ci */
4718c2ecf20Sopenharmony_cistatic int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
4728c2ecf20Sopenharmony_ci{
4738c2ecf20Sopenharmony_ci	/*
4748c2ecf20Sopenharmony_ci	 * Check for signal early to make process killable when there are
4758c2ecf20Sopenharmony_ci	 * always buffers available
4768c2ecf20Sopenharmony_ci	 */
4778c2ecf20Sopenharmony_ci	if (signal_pending(current))
4788c2ecf20Sopenharmony_ci		return -ERESTARTSYS;
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_cirepeat:
4818c2ecf20Sopenharmony_ci	while (pipe_empty(pipe->head, pipe->tail)) {
4828c2ecf20Sopenharmony_ci		if (!pipe->writers)
4838c2ecf20Sopenharmony_ci			return 0;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci		if (sd->num_spliced)
4868c2ecf20Sopenharmony_ci			return 0;
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci		if (sd->flags & SPLICE_F_NONBLOCK)
4898c2ecf20Sopenharmony_ci			return -EAGAIN;
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci		if (signal_pending(current))
4928c2ecf20Sopenharmony_ci			return -ERESTARTSYS;
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci		if (sd->need_wakeup) {
4958c2ecf20Sopenharmony_ci			wakeup_pipe_writers(pipe);
4968c2ecf20Sopenharmony_ci			sd->need_wakeup = false;
4978c2ecf20Sopenharmony_ci		}
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci		pipe_wait_readable(pipe);
5008c2ecf20Sopenharmony_ci	}
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	if (eat_empty_buffer(pipe))
5038c2ecf20Sopenharmony_ci		goto repeat;
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	return 1;
5068c2ecf20Sopenharmony_ci}
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci/**
5098c2ecf20Sopenharmony_ci * splice_from_pipe_begin - start splicing from pipe
5108c2ecf20Sopenharmony_ci * @sd:		information about the splice operation
5118c2ecf20Sopenharmony_ci *
5128c2ecf20Sopenharmony_ci * Description:
5138c2ecf20Sopenharmony_ci *    This function should be called before a loop containing
5148c2ecf20Sopenharmony_ci *    splice_from_pipe_next() and splice_from_pipe_feed() to
5158c2ecf20Sopenharmony_ci *    initialize the necessary fields of @sd.
5168c2ecf20Sopenharmony_ci */
5178c2ecf20Sopenharmony_cistatic void splice_from_pipe_begin(struct splice_desc *sd)
5188c2ecf20Sopenharmony_ci{
5198c2ecf20Sopenharmony_ci	sd->num_spliced = 0;
5208c2ecf20Sopenharmony_ci	sd->need_wakeup = false;
5218c2ecf20Sopenharmony_ci}
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci/**
5248c2ecf20Sopenharmony_ci * splice_from_pipe_end - finish splicing from pipe
5258c2ecf20Sopenharmony_ci * @pipe:	pipe to splice from
5268c2ecf20Sopenharmony_ci * @sd:		information about the splice operation
5278c2ecf20Sopenharmony_ci *
5288c2ecf20Sopenharmony_ci * Description:
5298c2ecf20Sopenharmony_ci *    This function will wake up pipe writers if necessary.  It should
5308c2ecf20Sopenharmony_ci *    be called after a loop containing splice_from_pipe_next() and
5318c2ecf20Sopenharmony_ci *    splice_from_pipe_feed().
5328c2ecf20Sopenharmony_ci */
5338c2ecf20Sopenharmony_cistatic void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc *sd)
5348c2ecf20Sopenharmony_ci{
5358c2ecf20Sopenharmony_ci	if (sd->need_wakeup)
5368c2ecf20Sopenharmony_ci		wakeup_pipe_writers(pipe);
5378c2ecf20Sopenharmony_ci}
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci/**
5408c2ecf20Sopenharmony_ci * __splice_from_pipe - splice data from a pipe to given actor
5418c2ecf20Sopenharmony_ci * @pipe:	pipe to splice from
5428c2ecf20Sopenharmony_ci * @sd:		information to @actor
5438c2ecf20Sopenharmony_ci * @actor:	handler that splices the data
5448c2ecf20Sopenharmony_ci *
5458c2ecf20Sopenharmony_ci * Description:
5468c2ecf20Sopenharmony_ci *    This function does little more than loop over the pipe and call
5478c2ecf20Sopenharmony_ci *    @actor to do the actual moving of a single struct pipe_buffer to
5488c2ecf20Sopenharmony_ci *    the desired destination. See pipe_to_file, pipe_to_sendpage, or
5498c2ecf20Sopenharmony_ci *    pipe_to_user.
5508c2ecf20Sopenharmony_ci *
5518c2ecf20Sopenharmony_ci */
5528c2ecf20Sopenharmony_cissize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
5538c2ecf20Sopenharmony_ci			   splice_actor *actor)
5548c2ecf20Sopenharmony_ci{
5558c2ecf20Sopenharmony_ci	int ret;
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci	splice_from_pipe_begin(sd);
5588c2ecf20Sopenharmony_ci	do {
5598c2ecf20Sopenharmony_ci		cond_resched();
5608c2ecf20Sopenharmony_ci		ret = splice_from_pipe_next(pipe, sd);
5618c2ecf20Sopenharmony_ci		if (ret > 0)
5628c2ecf20Sopenharmony_ci			ret = splice_from_pipe_feed(pipe, sd, actor);
5638c2ecf20Sopenharmony_ci	} while (ret > 0);
5648c2ecf20Sopenharmony_ci	splice_from_pipe_end(pipe, sd);
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	return sd->num_spliced ? sd->num_spliced : ret;
5678c2ecf20Sopenharmony_ci}
5688c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__splice_from_pipe);
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_ci/**
5718c2ecf20Sopenharmony_ci * splice_from_pipe - splice data from a pipe to a file
5728c2ecf20Sopenharmony_ci * @pipe:	pipe to splice from
5738c2ecf20Sopenharmony_ci * @out:	file to splice to
5748c2ecf20Sopenharmony_ci * @ppos:	position in @out
5758c2ecf20Sopenharmony_ci * @len:	how many bytes to splice
5768c2ecf20Sopenharmony_ci * @flags:	splice modifier flags
5778c2ecf20Sopenharmony_ci * @actor:	handler that splices the data
5788c2ecf20Sopenharmony_ci *
5798c2ecf20Sopenharmony_ci * Description:
5808c2ecf20Sopenharmony_ci *    See __splice_from_pipe. This function locks the pipe inode,
5818c2ecf20Sopenharmony_ci *    otherwise it's identical to __splice_from_pipe().
5828c2ecf20Sopenharmony_ci *
5838c2ecf20Sopenharmony_ci */
5848c2ecf20Sopenharmony_cissize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
5858c2ecf20Sopenharmony_ci			 loff_t *ppos, size_t len, unsigned int flags,
5868c2ecf20Sopenharmony_ci			 splice_actor *actor)
5878c2ecf20Sopenharmony_ci{
5888c2ecf20Sopenharmony_ci	ssize_t ret;
5898c2ecf20Sopenharmony_ci	struct splice_desc sd = {
5908c2ecf20Sopenharmony_ci		.total_len = len,
5918c2ecf20Sopenharmony_ci		.flags = flags,
5928c2ecf20Sopenharmony_ci		.pos = *ppos,
5938c2ecf20Sopenharmony_ci		.u.file = out,
5948c2ecf20Sopenharmony_ci	};
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ci	pipe_lock(pipe);
5978c2ecf20Sopenharmony_ci	ret = __splice_from_pipe(pipe, &sd, actor);
5988c2ecf20Sopenharmony_ci	pipe_unlock(pipe);
5998c2ecf20Sopenharmony_ci
6008c2ecf20Sopenharmony_ci	return ret;
6018c2ecf20Sopenharmony_ci}
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci/**
6048c2ecf20Sopenharmony_ci * iter_file_splice_write - splice data from a pipe to a file
6058c2ecf20Sopenharmony_ci * @pipe:	pipe info
6068c2ecf20Sopenharmony_ci * @out:	file to write to
6078c2ecf20Sopenharmony_ci * @ppos:	position in @out
6088c2ecf20Sopenharmony_ci * @len:	number of bytes to splice
6098c2ecf20Sopenharmony_ci * @flags:	splice modifier flags
6108c2ecf20Sopenharmony_ci *
6118c2ecf20Sopenharmony_ci * Description:
6128c2ecf20Sopenharmony_ci *    Will either move or copy pages (determined by @flags options) from
6138c2ecf20Sopenharmony_ci *    the given pipe inode to the given file.
6148c2ecf20Sopenharmony_ci *    This one is ->write_iter-based.
6158c2ecf20Sopenharmony_ci *
6168c2ecf20Sopenharmony_ci */
6178c2ecf20Sopenharmony_cissize_t
6188c2ecf20Sopenharmony_ciiter_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
6198c2ecf20Sopenharmony_ci			  loff_t *ppos, size_t len, unsigned int flags)
6208c2ecf20Sopenharmony_ci{
6218c2ecf20Sopenharmony_ci	struct splice_desc sd = {
6228c2ecf20Sopenharmony_ci		.total_len = len,
6238c2ecf20Sopenharmony_ci		.flags = flags,
6248c2ecf20Sopenharmony_ci		.pos = *ppos,
6258c2ecf20Sopenharmony_ci		.u.file = out,
6268c2ecf20Sopenharmony_ci	};
6278c2ecf20Sopenharmony_ci	int nbufs = pipe->max_usage;
6288c2ecf20Sopenharmony_ci	struct bio_vec *array = kcalloc(nbufs, sizeof(struct bio_vec),
6298c2ecf20Sopenharmony_ci					GFP_KERNEL);
6308c2ecf20Sopenharmony_ci	ssize_t ret;
6318c2ecf20Sopenharmony_ci
6328c2ecf20Sopenharmony_ci	if (unlikely(!array))
6338c2ecf20Sopenharmony_ci		return -ENOMEM;
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_ci	pipe_lock(pipe);
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci	splice_from_pipe_begin(&sd);
6388c2ecf20Sopenharmony_ci	while (sd.total_len) {
6398c2ecf20Sopenharmony_ci		struct iov_iter from;
6408c2ecf20Sopenharmony_ci		unsigned int head, tail, mask;
6418c2ecf20Sopenharmony_ci		size_t left;
6428c2ecf20Sopenharmony_ci		int n;
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_ci		ret = splice_from_pipe_next(pipe, &sd);
6458c2ecf20Sopenharmony_ci		if (ret <= 0)
6468c2ecf20Sopenharmony_ci			break;
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci		if (unlikely(nbufs < pipe->max_usage)) {
6498c2ecf20Sopenharmony_ci			kfree(array);
6508c2ecf20Sopenharmony_ci			nbufs = pipe->max_usage;
6518c2ecf20Sopenharmony_ci			array = kcalloc(nbufs, sizeof(struct bio_vec),
6528c2ecf20Sopenharmony_ci					GFP_KERNEL);
6538c2ecf20Sopenharmony_ci			if (!array) {
6548c2ecf20Sopenharmony_ci				ret = -ENOMEM;
6558c2ecf20Sopenharmony_ci				break;
6568c2ecf20Sopenharmony_ci			}
6578c2ecf20Sopenharmony_ci		}
6588c2ecf20Sopenharmony_ci
6598c2ecf20Sopenharmony_ci		head = pipe->head;
6608c2ecf20Sopenharmony_ci		tail = pipe->tail;
6618c2ecf20Sopenharmony_ci		mask = pipe->ring_size - 1;
6628c2ecf20Sopenharmony_ci
6638c2ecf20Sopenharmony_ci		/* build the vector */
6648c2ecf20Sopenharmony_ci		left = sd.total_len;
6658c2ecf20Sopenharmony_ci		for (n = 0; !pipe_empty(head, tail) && left && n < nbufs; tail++, n++) {
6668c2ecf20Sopenharmony_ci			struct pipe_buffer *buf = &pipe->bufs[tail & mask];
6678c2ecf20Sopenharmony_ci			size_t this_len = buf->len;
6688c2ecf20Sopenharmony_ci
6698c2ecf20Sopenharmony_ci			if (this_len > left)
6708c2ecf20Sopenharmony_ci				this_len = left;
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci			ret = pipe_buf_confirm(pipe, buf);
6738c2ecf20Sopenharmony_ci			if (unlikely(ret)) {
6748c2ecf20Sopenharmony_ci				if (ret == -ENODATA)
6758c2ecf20Sopenharmony_ci					ret = 0;
6768c2ecf20Sopenharmony_ci				goto done;
6778c2ecf20Sopenharmony_ci			}
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_ci			array[n].bv_page = buf->page;
6808c2ecf20Sopenharmony_ci			array[n].bv_len = this_len;
6818c2ecf20Sopenharmony_ci			array[n].bv_offset = buf->offset;
6828c2ecf20Sopenharmony_ci			left -= this_len;
6838c2ecf20Sopenharmony_ci		}
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_ci		iov_iter_bvec(&from, WRITE, array, n, sd.total_len - left);
6868c2ecf20Sopenharmony_ci		ret = vfs_iter_write(out, &from, &sd.pos, 0);
6878c2ecf20Sopenharmony_ci		if (ret <= 0)
6888c2ecf20Sopenharmony_ci			break;
6898c2ecf20Sopenharmony_ci
6908c2ecf20Sopenharmony_ci		sd.num_spliced += ret;
6918c2ecf20Sopenharmony_ci		sd.total_len -= ret;
6928c2ecf20Sopenharmony_ci		*ppos = sd.pos;
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci		/* dismiss the fully eaten buffers, adjust the partial one */
6958c2ecf20Sopenharmony_ci		tail = pipe->tail;
6968c2ecf20Sopenharmony_ci		while (ret) {
6978c2ecf20Sopenharmony_ci			struct pipe_buffer *buf = &pipe->bufs[tail & mask];
6988c2ecf20Sopenharmony_ci			if (ret >= buf->len) {
6998c2ecf20Sopenharmony_ci				ret -= buf->len;
7008c2ecf20Sopenharmony_ci				buf->len = 0;
7018c2ecf20Sopenharmony_ci				pipe_buf_release(pipe, buf);
7028c2ecf20Sopenharmony_ci				tail++;
7038c2ecf20Sopenharmony_ci				pipe->tail = tail;
7048c2ecf20Sopenharmony_ci				if (pipe->files)
7058c2ecf20Sopenharmony_ci					sd.need_wakeup = true;
7068c2ecf20Sopenharmony_ci			} else {
7078c2ecf20Sopenharmony_ci				buf->offset += ret;
7088c2ecf20Sopenharmony_ci				buf->len -= ret;
7098c2ecf20Sopenharmony_ci				ret = 0;
7108c2ecf20Sopenharmony_ci			}
7118c2ecf20Sopenharmony_ci		}
7128c2ecf20Sopenharmony_ci	}
7138c2ecf20Sopenharmony_cidone:
7148c2ecf20Sopenharmony_ci	kfree(array);
7158c2ecf20Sopenharmony_ci	splice_from_pipe_end(pipe, &sd);
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci	pipe_unlock(pipe);
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_ci	if (sd.num_spliced)
7208c2ecf20Sopenharmony_ci		ret = sd.num_spliced;
7218c2ecf20Sopenharmony_ci
7228c2ecf20Sopenharmony_ci	return ret;
7238c2ecf20Sopenharmony_ci}
7248c2ecf20Sopenharmony_ci
7258c2ecf20Sopenharmony_ciEXPORT_SYMBOL(iter_file_splice_write);
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci/**
7288c2ecf20Sopenharmony_ci * generic_splice_sendpage - splice data from a pipe to a socket
7298c2ecf20Sopenharmony_ci * @pipe:	pipe to splice from
7308c2ecf20Sopenharmony_ci * @out:	socket to write to
7318c2ecf20Sopenharmony_ci * @ppos:	position in @out
7328c2ecf20Sopenharmony_ci * @len:	number of bytes to splice
7338c2ecf20Sopenharmony_ci * @flags:	splice modifier flags
7348c2ecf20Sopenharmony_ci *
7358c2ecf20Sopenharmony_ci * Description:
7368c2ecf20Sopenharmony_ci *    Will send @len bytes from the pipe to a network socket. No data copying
7378c2ecf20Sopenharmony_ci *    is involved.
7388c2ecf20Sopenharmony_ci *
7398c2ecf20Sopenharmony_ci */
7408c2ecf20Sopenharmony_cissize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
7418c2ecf20Sopenharmony_ci				loff_t *ppos, size_t len, unsigned int flags)
7428c2ecf20Sopenharmony_ci{
7438c2ecf20Sopenharmony_ci	return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage);
7448c2ecf20Sopenharmony_ci}
7458c2ecf20Sopenharmony_ci
7468c2ecf20Sopenharmony_ciEXPORT_SYMBOL(generic_splice_sendpage);
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_cistatic int warn_unsupported(struct file *file, const char *op)
7498c2ecf20Sopenharmony_ci{
7508c2ecf20Sopenharmony_ci	pr_debug_ratelimited(
7518c2ecf20Sopenharmony_ci		"splice %s not supported for file %pD4 (pid: %d comm: %.20s)\n",
7528c2ecf20Sopenharmony_ci		op, file, current->pid, current->comm);
7538c2ecf20Sopenharmony_ci	return -EINVAL;
7548c2ecf20Sopenharmony_ci}
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ci/*
7578c2ecf20Sopenharmony_ci * Attempt to initiate a splice from pipe to file.
7588c2ecf20Sopenharmony_ci */
7598c2ecf20Sopenharmony_cistatic long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
7608c2ecf20Sopenharmony_ci			   loff_t *ppos, size_t len, unsigned int flags)
7618c2ecf20Sopenharmony_ci{
7628c2ecf20Sopenharmony_ci	if (unlikely(!out->f_op->splice_write))
7638c2ecf20Sopenharmony_ci		return warn_unsupported(out, "write");
7648c2ecf20Sopenharmony_ci	return out->f_op->splice_write(pipe, out, ppos, len, flags);
7658c2ecf20Sopenharmony_ci}
7668c2ecf20Sopenharmony_ci
7678c2ecf20Sopenharmony_ci/*
7688c2ecf20Sopenharmony_ci * Attempt to initiate a splice from a file to a pipe.
7698c2ecf20Sopenharmony_ci */
7708c2ecf20Sopenharmony_cistatic long do_splice_to(struct file *in, loff_t *ppos,
7718c2ecf20Sopenharmony_ci			 struct pipe_inode_info *pipe, size_t len,
7728c2ecf20Sopenharmony_ci			 unsigned int flags)
7738c2ecf20Sopenharmony_ci{
7748c2ecf20Sopenharmony_ci	int ret;
7758c2ecf20Sopenharmony_ci
7768c2ecf20Sopenharmony_ci	if (unlikely(!(in->f_mode & FMODE_READ)))
7778c2ecf20Sopenharmony_ci		return -EBADF;
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	ret = rw_verify_area(READ, in, ppos, len);
7808c2ecf20Sopenharmony_ci	if (unlikely(ret < 0))
7818c2ecf20Sopenharmony_ci		return ret;
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci	if (unlikely(len > MAX_RW_COUNT))
7848c2ecf20Sopenharmony_ci		len = MAX_RW_COUNT;
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_ci	if (unlikely(!in->f_op->splice_read))
7878c2ecf20Sopenharmony_ci		return warn_unsupported(in, "read");
7888c2ecf20Sopenharmony_ci	return in->f_op->splice_read(in, ppos, pipe, len, flags);
7898c2ecf20Sopenharmony_ci}
7908c2ecf20Sopenharmony_ci
7918c2ecf20Sopenharmony_ci/**
7928c2ecf20Sopenharmony_ci * splice_direct_to_actor - splices data directly between two non-pipes
7938c2ecf20Sopenharmony_ci * @in:		file to splice from
7948c2ecf20Sopenharmony_ci * @sd:		actor information on where to splice to
7958c2ecf20Sopenharmony_ci * @actor:	handles the data splicing
7968c2ecf20Sopenharmony_ci *
7978c2ecf20Sopenharmony_ci * Description:
7988c2ecf20Sopenharmony_ci *    This is a special case helper to splice directly between two
7998c2ecf20Sopenharmony_ci *    points, without requiring an explicit pipe. Internally an allocated
8008c2ecf20Sopenharmony_ci *    pipe is cached in the process, and reused during the lifetime of
8018c2ecf20Sopenharmony_ci *    that process.
8028c2ecf20Sopenharmony_ci *
8038c2ecf20Sopenharmony_ci */
8048c2ecf20Sopenharmony_cissize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
8058c2ecf20Sopenharmony_ci			       splice_direct_actor *actor)
8068c2ecf20Sopenharmony_ci{
8078c2ecf20Sopenharmony_ci	struct pipe_inode_info *pipe;
8088c2ecf20Sopenharmony_ci	long ret, bytes;
8098c2ecf20Sopenharmony_ci	umode_t i_mode;
8108c2ecf20Sopenharmony_ci	size_t len;
8118c2ecf20Sopenharmony_ci	int i, flags, more;
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_ci	/*
8148c2ecf20Sopenharmony_ci	 * We require the input being a regular file, as we don't want to
8158c2ecf20Sopenharmony_ci	 * randomly drop data for eg socket -> socket splicing. Use the
8168c2ecf20Sopenharmony_ci	 * piped splicing for that!
8178c2ecf20Sopenharmony_ci	 */
8188c2ecf20Sopenharmony_ci	i_mode = file_inode(in)->i_mode;
8198c2ecf20Sopenharmony_ci	if (unlikely(!S_ISREG(i_mode) && !S_ISBLK(i_mode)))
8208c2ecf20Sopenharmony_ci		return -EINVAL;
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_ci	/*
8238c2ecf20Sopenharmony_ci	 * neither in nor out is a pipe, setup an internal pipe attached to
8248c2ecf20Sopenharmony_ci	 * 'out' and transfer the wanted data from 'in' to 'out' through that
8258c2ecf20Sopenharmony_ci	 */
8268c2ecf20Sopenharmony_ci	pipe = current->splice_pipe;
8278c2ecf20Sopenharmony_ci	if (unlikely(!pipe)) {
8288c2ecf20Sopenharmony_ci		pipe = alloc_pipe_info();
8298c2ecf20Sopenharmony_ci		if (!pipe)
8308c2ecf20Sopenharmony_ci			return -ENOMEM;
8318c2ecf20Sopenharmony_ci
8328c2ecf20Sopenharmony_ci		/*
8338c2ecf20Sopenharmony_ci		 * We don't have an immediate reader, but we'll read the stuff
8348c2ecf20Sopenharmony_ci		 * out of the pipe right after the splice_to_pipe(). So set
8358c2ecf20Sopenharmony_ci		 * PIPE_READERS appropriately.
8368c2ecf20Sopenharmony_ci		 */
8378c2ecf20Sopenharmony_ci		pipe->readers = 1;
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci		current->splice_pipe = pipe;
8408c2ecf20Sopenharmony_ci	}
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci	/*
8438c2ecf20Sopenharmony_ci	 * Do the splice.
8448c2ecf20Sopenharmony_ci	 */
8458c2ecf20Sopenharmony_ci	ret = 0;
8468c2ecf20Sopenharmony_ci	bytes = 0;
8478c2ecf20Sopenharmony_ci	len = sd->total_len;
8488c2ecf20Sopenharmony_ci	flags = sd->flags;
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_ci	/*
8518c2ecf20Sopenharmony_ci	 * Don't block on output, we have to drain the direct pipe.
8528c2ecf20Sopenharmony_ci	 */
8538c2ecf20Sopenharmony_ci	sd->flags &= ~SPLICE_F_NONBLOCK;
8548c2ecf20Sopenharmony_ci	more = sd->flags & SPLICE_F_MORE;
8558c2ecf20Sopenharmony_ci
8568c2ecf20Sopenharmony_ci	WARN_ON_ONCE(!pipe_empty(pipe->head, pipe->tail));
8578c2ecf20Sopenharmony_ci
8588c2ecf20Sopenharmony_ci	while (len) {
8598c2ecf20Sopenharmony_ci		unsigned int p_space;
8608c2ecf20Sopenharmony_ci		size_t read_len;
8618c2ecf20Sopenharmony_ci		loff_t pos = sd->pos, prev_pos = pos;
8628c2ecf20Sopenharmony_ci
8638c2ecf20Sopenharmony_ci		/* Don't try to read more the pipe has space for. */
8648c2ecf20Sopenharmony_ci		p_space = pipe->max_usage -
8658c2ecf20Sopenharmony_ci			pipe_occupancy(pipe->head, pipe->tail);
8668c2ecf20Sopenharmony_ci		read_len = min_t(size_t, len, p_space << PAGE_SHIFT);
8678c2ecf20Sopenharmony_ci		ret = do_splice_to(in, &pos, pipe, read_len, flags);
8688c2ecf20Sopenharmony_ci		if (unlikely(ret <= 0))
8698c2ecf20Sopenharmony_ci			goto out_release;
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_ci		read_len = ret;
8728c2ecf20Sopenharmony_ci		sd->total_len = read_len;
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci		/*
8758c2ecf20Sopenharmony_ci		 * If more data is pending, set SPLICE_F_MORE
8768c2ecf20Sopenharmony_ci		 * If this is the last data and SPLICE_F_MORE was not set
8778c2ecf20Sopenharmony_ci		 * initially, clears it.
8788c2ecf20Sopenharmony_ci		 */
8798c2ecf20Sopenharmony_ci		if (read_len < len)
8808c2ecf20Sopenharmony_ci			sd->flags |= SPLICE_F_MORE;
8818c2ecf20Sopenharmony_ci		else if (!more)
8828c2ecf20Sopenharmony_ci			sd->flags &= ~SPLICE_F_MORE;
8838c2ecf20Sopenharmony_ci		/*
8848c2ecf20Sopenharmony_ci		 * NOTE: nonblocking mode only applies to the input. We
8858c2ecf20Sopenharmony_ci		 * must not do the output in nonblocking mode as then we
8868c2ecf20Sopenharmony_ci		 * could get stuck data in the internal pipe:
8878c2ecf20Sopenharmony_ci		 */
8888c2ecf20Sopenharmony_ci		ret = actor(pipe, sd);
8898c2ecf20Sopenharmony_ci		if (unlikely(ret <= 0)) {
8908c2ecf20Sopenharmony_ci			sd->pos = prev_pos;
8918c2ecf20Sopenharmony_ci			goto out_release;
8928c2ecf20Sopenharmony_ci		}
8938c2ecf20Sopenharmony_ci
8948c2ecf20Sopenharmony_ci		bytes += ret;
8958c2ecf20Sopenharmony_ci		len -= ret;
8968c2ecf20Sopenharmony_ci		sd->pos = pos;
8978c2ecf20Sopenharmony_ci
8988c2ecf20Sopenharmony_ci		if (ret < read_len) {
8998c2ecf20Sopenharmony_ci			sd->pos = prev_pos + ret;
9008c2ecf20Sopenharmony_ci			goto out_release;
9018c2ecf20Sopenharmony_ci		}
9028c2ecf20Sopenharmony_ci	}
9038c2ecf20Sopenharmony_ci
9048c2ecf20Sopenharmony_cidone:
9058c2ecf20Sopenharmony_ci	pipe->tail = pipe->head = 0;
9068c2ecf20Sopenharmony_ci	file_accessed(in);
9078c2ecf20Sopenharmony_ci	return bytes;
9088c2ecf20Sopenharmony_ci
9098c2ecf20Sopenharmony_ciout_release:
9108c2ecf20Sopenharmony_ci	/*
9118c2ecf20Sopenharmony_ci	 * If we did an incomplete transfer we must release
9128c2ecf20Sopenharmony_ci	 * the pipe buffers in question:
9138c2ecf20Sopenharmony_ci	 */
9148c2ecf20Sopenharmony_ci	for (i = 0; i < pipe->ring_size; i++) {
9158c2ecf20Sopenharmony_ci		struct pipe_buffer *buf = &pipe->bufs[i];
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci		if (buf->ops)
9188c2ecf20Sopenharmony_ci			pipe_buf_release(pipe, buf);
9198c2ecf20Sopenharmony_ci	}
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_ci	if (!bytes)
9228c2ecf20Sopenharmony_ci		bytes = ret;
9238c2ecf20Sopenharmony_ci
9248c2ecf20Sopenharmony_ci	goto done;
9258c2ecf20Sopenharmony_ci}
9268c2ecf20Sopenharmony_ciEXPORT_SYMBOL(splice_direct_to_actor);
9278c2ecf20Sopenharmony_ci
9288c2ecf20Sopenharmony_cistatic int direct_splice_actor(struct pipe_inode_info *pipe,
9298c2ecf20Sopenharmony_ci			       struct splice_desc *sd)
9308c2ecf20Sopenharmony_ci{
9318c2ecf20Sopenharmony_ci	struct file *file = sd->u.file;
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_ci	return do_splice_from(pipe, file, sd->opos, sd->total_len,
9348c2ecf20Sopenharmony_ci			      sd->flags);
9358c2ecf20Sopenharmony_ci}
9368c2ecf20Sopenharmony_ci
9378c2ecf20Sopenharmony_ci/**
9388c2ecf20Sopenharmony_ci * do_splice_direct - splices data directly between two files
9398c2ecf20Sopenharmony_ci * @in:		file to splice from
9408c2ecf20Sopenharmony_ci * @ppos:	input file offset
9418c2ecf20Sopenharmony_ci * @out:	file to splice to
9428c2ecf20Sopenharmony_ci * @opos:	output file offset
9438c2ecf20Sopenharmony_ci * @len:	number of bytes to splice
9448c2ecf20Sopenharmony_ci * @flags:	splice modifier flags
9458c2ecf20Sopenharmony_ci *
9468c2ecf20Sopenharmony_ci * Description:
9478c2ecf20Sopenharmony_ci *    For use by do_sendfile(). splice can easily emulate sendfile, but
9488c2ecf20Sopenharmony_ci *    doing it in the application would incur an extra system call
9498c2ecf20Sopenharmony_ci *    (splice in + splice out, as compared to just sendfile()). So this helper
9508c2ecf20Sopenharmony_ci *    can splice directly through a process-private pipe.
9518c2ecf20Sopenharmony_ci *
9528c2ecf20Sopenharmony_ci */
9538c2ecf20Sopenharmony_cilong do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
9548c2ecf20Sopenharmony_ci		      loff_t *opos, size_t len, unsigned int flags)
9558c2ecf20Sopenharmony_ci{
9568c2ecf20Sopenharmony_ci	struct splice_desc sd = {
9578c2ecf20Sopenharmony_ci		.len		= len,
9588c2ecf20Sopenharmony_ci		.total_len	= len,
9598c2ecf20Sopenharmony_ci		.flags		= flags,
9608c2ecf20Sopenharmony_ci		.pos		= *ppos,
9618c2ecf20Sopenharmony_ci		.u.file		= out,
9628c2ecf20Sopenharmony_ci		.opos		= opos,
9638c2ecf20Sopenharmony_ci	};
9648c2ecf20Sopenharmony_ci	long ret;
9658c2ecf20Sopenharmony_ci
9668c2ecf20Sopenharmony_ci	if (unlikely(!(out->f_mode & FMODE_WRITE)))
9678c2ecf20Sopenharmony_ci		return -EBADF;
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_ci	if (unlikely(out->f_flags & O_APPEND))
9708c2ecf20Sopenharmony_ci		return -EINVAL;
9718c2ecf20Sopenharmony_ci
9728c2ecf20Sopenharmony_ci	ret = rw_verify_area(WRITE, out, opos, len);
9738c2ecf20Sopenharmony_ci	if (unlikely(ret < 0))
9748c2ecf20Sopenharmony_ci		return ret;
9758c2ecf20Sopenharmony_ci
9768c2ecf20Sopenharmony_ci	ret = splice_direct_to_actor(in, &sd, direct_splice_actor);
9778c2ecf20Sopenharmony_ci	if (ret > 0)
9788c2ecf20Sopenharmony_ci		*ppos = sd.pos;
9798c2ecf20Sopenharmony_ci
9808c2ecf20Sopenharmony_ci	return ret;
9818c2ecf20Sopenharmony_ci}
9828c2ecf20Sopenharmony_ciEXPORT_SYMBOL(do_splice_direct);
9838c2ecf20Sopenharmony_ci
9848c2ecf20Sopenharmony_cistatic int wait_for_space(struct pipe_inode_info *pipe, unsigned flags)
9858c2ecf20Sopenharmony_ci{
9868c2ecf20Sopenharmony_ci	for (;;) {
9878c2ecf20Sopenharmony_ci		if (unlikely(!pipe->readers)) {
9888c2ecf20Sopenharmony_ci			send_sig(SIGPIPE, current, 0);
9898c2ecf20Sopenharmony_ci			return -EPIPE;
9908c2ecf20Sopenharmony_ci		}
9918c2ecf20Sopenharmony_ci		if (!pipe_full(pipe->head, pipe->tail, pipe->max_usage))
9928c2ecf20Sopenharmony_ci			return 0;
9938c2ecf20Sopenharmony_ci		if (flags & SPLICE_F_NONBLOCK)
9948c2ecf20Sopenharmony_ci			return -EAGAIN;
9958c2ecf20Sopenharmony_ci		if (signal_pending(current))
9968c2ecf20Sopenharmony_ci			return -ERESTARTSYS;
9978c2ecf20Sopenharmony_ci		pipe_wait_writable(pipe);
9988c2ecf20Sopenharmony_ci	}
9998c2ecf20Sopenharmony_ci}
10008c2ecf20Sopenharmony_ci
10018c2ecf20Sopenharmony_cistatic int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
10028c2ecf20Sopenharmony_ci			       struct pipe_inode_info *opipe,
10038c2ecf20Sopenharmony_ci			       size_t len, unsigned int flags);
10048c2ecf20Sopenharmony_ci
10058c2ecf20Sopenharmony_ci/*
10068c2ecf20Sopenharmony_ci * Determine where to splice to/from.
10078c2ecf20Sopenharmony_ci */
10088c2ecf20Sopenharmony_cilong do_splice(struct file *in, loff_t *off_in, struct file *out,
10098c2ecf20Sopenharmony_ci	       loff_t *off_out, size_t len, unsigned int flags)
10108c2ecf20Sopenharmony_ci{
10118c2ecf20Sopenharmony_ci	struct pipe_inode_info *ipipe;
10128c2ecf20Sopenharmony_ci	struct pipe_inode_info *opipe;
10138c2ecf20Sopenharmony_ci	loff_t offset;
10148c2ecf20Sopenharmony_ci	long ret;
10158c2ecf20Sopenharmony_ci
10168c2ecf20Sopenharmony_ci	if (unlikely(!(in->f_mode & FMODE_READ) ||
10178c2ecf20Sopenharmony_ci		     !(out->f_mode & FMODE_WRITE)))
10188c2ecf20Sopenharmony_ci		return -EBADF;
10198c2ecf20Sopenharmony_ci
10208c2ecf20Sopenharmony_ci	ipipe = get_pipe_info(in, true);
10218c2ecf20Sopenharmony_ci	opipe = get_pipe_info(out, true);
10228c2ecf20Sopenharmony_ci
10238c2ecf20Sopenharmony_ci	if (ipipe && opipe) {
10248c2ecf20Sopenharmony_ci		if (off_in || off_out)
10258c2ecf20Sopenharmony_ci			return -ESPIPE;
10268c2ecf20Sopenharmony_ci
10278c2ecf20Sopenharmony_ci		/* Splicing to self would be fun, but... */
10288c2ecf20Sopenharmony_ci		if (ipipe == opipe)
10298c2ecf20Sopenharmony_ci			return -EINVAL;
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci		if ((in->f_flags | out->f_flags) & O_NONBLOCK)
10328c2ecf20Sopenharmony_ci			flags |= SPLICE_F_NONBLOCK;
10338c2ecf20Sopenharmony_ci
10348c2ecf20Sopenharmony_ci		return splice_pipe_to_pipe(ipipe, opipe, len, flags);
10358c2ecf20Sopenharmony_ci	}
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci	if (ipipe) {
10388c2ecf20Sopenharmony_ci		if (off_in)
10398c2ecf20Sopenharmony_ci			return -ESPIPE;
10408c2ecf20Sopenharmony_ci		if (off_out) {
10418c2ecf20Sopenharmony_ci			if (!(out->f_mode & FMODE_PWRITE))
10428c2ecf20Sopenharmony_ci				return -EINVAL;
10438c2ecf20Sopenharmony_ci			offset = *off_out;
10448c2ecf20Sopenharmony_ci		} else {
10458c2ecf20Sopenharmony_ci			offset = out->f_pos;
10468c2ecf20Sopenharmony_ci		}
10478c2ecf20Sopenharmony_ci
10488c2ecf20Sopenharmony_ci		if (unlikely(out->f_flags & O_APPEND))
10498c2ecf20Sopenharmony_ci			return -EINVAL;
10508c2ecf20Sopenharmony_ci
10518c2ecf20Sopenharmony_ci		ret = rw_verify_area(WRITE, out, &offset, len);
10528c2ecf20Sopenharmony_ci		if (unlikely(ret < 0))
10538c2ecf20Sopenharmony_ci			return ret;
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_ci		if (in->f_flags & O_NONBLOCK)
10568c2ecf20Sopenharmony_ci			flags |= SPLICE_F_NONBLOCK;
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_ci		file_start_write(out);
10598c2ecf20Sopenharmony_ci		ret = do_splice_from(ipipe, out, &offset, len, flags);
10608c2ecf20Sopenharmony_ci		file_end_write(out);
10618c2ecf20Sopenharmony_ci
10628c2ecf20Sopenharmony_ci		if (!off_out)
10638c2ecf20Sopenharmony_ci			out->f_pos = offset;
10648c2ecf20Sopenharmony_ci		else
10658c2ecf20Sopenharmony_ci			*off_out = offset;
10668c2ecf20Sopenharmony_ci
10678c2ecf20Sopenharmony_ci		return ret;
10688c2ecf20Sopenharmony_ci	}
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_ci	if (opipe) {
10718c2ecf20Sopenharmony_ci		if (off_out)
10728c2ecf20Sopenharmony_ci			return -ESPIPE;
10738c2ecf20Sopenharmony_ci		if (off_in) {
10748c2ecf20Sopenharmony_ci			if (!(in->f_mode & FMODE_PREAD))
10758c2ecf20Sopenharmony_ci				return -EINVAL;
10768c2ecf20Sopenharmony_ci			offset = *off_in;
10778c2ecf20Sopenharmony_ci		} else {
10788c2ecf20Sopenharmony_ci			offset = in->f_pos;
10798c2ecf20Sopenharmony_ci		}
10808c2ecf20Sopenharmony_ci
10818c2ecf20Sopenharmony_ci		if (out->f_flags & O_NONBLOCK)
10828c2ecf20Sopenharmony_ci			flags |= SPLICE_F_NONBLOCK;
10838c2ecf20Sopenharmony_ci
10848c2ecf20Sopenharmony_ci		pipe_lock(opipe);
10858c2ecf20Sopenharmony_ci		ret = wait_for_space(opipe, flags);
10868c2ecf20Sopenharmony_ci		if (!ret) {
10878c2ecf20Sopenharmony_ci			unsigned int p_space;
10888c2ecf20Sopenharmony_ci
10898c2ecf20Sopenharmony_ci			/* Don't try to read more the pipe has space for. */
10908c2ecf20Sopenharmony_ci			p_space = opipe->max_usage - pipe_occupancy(opipe->head, opipe->tail);
10918c2ecf20Sopenharmony_ci			len = min_t(size_t, len, p_space << PAGE_SHIFT);
10928c2ecf20Sopenharmony_ci
10938c2ecf20Sopenharmony_ci			ret = do_splice_to(in, &offset, opipe, len, flags);
10948c2ecf20Sopenharmony_ci		}
10958c2ecf20Sopenharmony_ci		pipe_unlock(opipe);
10968c2ecf20Sopenharmony_ci		if (ret > 0)
10978c2ecf20Sopenharmony_ci			wakeup_pipe_readers(opipe);
10988c2ecf20Sopenharmony_ci		if (!off_in)
10998c2ecf20Sopenharmony_ci			in->f_pos = offset;
11008c2ecf20Sopenharmony_ci		else
11018c2ecf20Sopenharmony_ci			*off_in = offset;
11028c2ecf20Sopenharmony_ci
11038c2ecf20Sopenharmony_ci		return ret;
11048c2ecf20Sopenharmony_ci	}
11058c2ecf20Sopenharmony_ci
11068c2ecf20Sopenharmony_ci	return -EINVAL;
11078c2ecf20Sopenharmony_ci}
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_cistatic long __do_splice(struct file *in, loff_t __user *off_in,
11108c2ecf20Sopenharmony_ci			struct file *out, loff_t __user *off_out,
11118c2ecf20Sopenharmony_ci			size_t len, unsigned int flags)
11128c2ecf20Sopenharmony_ci{
11138c2ecf20Sopenharmony_ci	struct pipe_inode_info *ipipe;
11148c2ecf20Sopenharmony_ci	struct pipe_inode_info *opipe;
11158c2ecf20Sopenharmony_ci	loff_t offset, *__off_in = NULL, *__off_out = NULL;
11168c2ecf20Sopenharmony_ci	long ret;
11178c2ecf20Sopenharmony_ci
11188c2ecf20Sopenharmony_ci	ipipe = get_pipe_info(in, true);
11198c2ecf20Sopenharmony_ci	opipe = get_pipe_info(out, true);
11208c2ecf20Sopenharmony_ci
11218c2ecf20Sopenharmony_ci	if (ipipe && off_in)
11228c2ecf20Sopenharmony_ci		return -ESPIPE;
11238c2ecf20Sopenharmony_ci	if (opipe && off_out)
11248c2ecf20Sopenharmony_ci		return -ESPIPE;
11258c2ecf20Sopenharmony_ci
11268c2ecf20Sopenharmony_ci	if (off_out) {
11278c2ecf20Sopenharmony_ci		if (copy_from_user(&offset, off_out, sizeof(loff_t)))
11288c2ecf20Sopenharmony_ci			return -EFAULT;
11298c2ecf20Sopenharmony_ci		__off_out = &offset;
11308c2ecf20Sopenharmony_ci	}
11318c2ecf20Sopenharmony_ci	if (off_in) {
11328c2ecf20Sopenharmony_ci		if (copy_from_user(&offset, off_in, sizeof(loff_t)))
11338c2ecf20Sopenharmony_ci			return -EFAULT;
11348c2ecf20Sopenharmony_ci		__off_in = &offset;
11358c2ecf20Sopenharmony_ci	}
11368c2ecf20Sopenharmony_ci
11378c2ecf20Sopenharmony_ci	ret = do_splice(in, __off_in, out, __off_out, len, flags);
11388c2ecf20Sopenharmony_ci	if (ret < 0)
11398c2ecf20Sopenharmony_ci		return ret;
11408c2ecf20Sopenharmony_ci
11418c2ecf20Sopenharmony_ci	if (__off_out && copy_to_user(off_out, __off_out, sizeof(loff_t)))
11428c2ecf20Sopenharmony_ci		return -EFAULT;
11438c2ecf20Sopenharmony_ci	if (__off_in && copy_to_user(off_in, __off_in, sizeof(loff_t)))
11448c2ecf20Sopenharmony_ci		return -EFAULT;
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci	return ret;
11478c2ecf20Sopenharmony_ci}
11488c2ecf20Sopenharmony_ci
11498c2ecf20Sopenharmony_cistatic int iter_to_pipe(struct iov_iter *from,
11508c2ecf20Sopenharmony_ci			struct pipe_inode_info *pipe,
11518c2ecf20Sopenharmony_ci			unsigned flags)
11528c2ecf20Sopenharmony_ci{
11538c2ecf20Sopenharmony_ci	struct pipe_buffer buf = {
11548c2ecf20Sopenharmony_ci		.ops = &user_page_pipe_buf_ops,
11558c2ecf20Sopenharmony_ci		.flags = flags
11568c2ecf20Sopenharmony_ci	};
11578c2ecf20Sopenharmony_ci	size_t total = 0;
11588c2ecf20Sopenharmony_ci	int ret = 0;
11598c2ecf20Sopenharmony_ci	bool failed = false;
11608c2ecf20Sopenharmony_ci
11618c2ecf20Sopenharmony_ci	while (iov_iter_count(from) && !failed) {
11628c2ecf20Sopenharmony_ci		struct page *pages[16];
11638c2ecf20Sopenharmony_ci		ssize_t copied;
11648c2ecf20Sopenharmony_ci		size_t start;
11658c2ecf20Sopenharmony_ci		int n;
11668c2ecf20Sopenharmony_ci
11678c2ecf20Sopenharmony_ci		copied = iov_iter_get_pages(from, pages, ~0UL, 16, &start);
11688c2ecf20Sopenharmony_ci		if (copied <= 0) {
11698c2ecf20Sopenharmony_ci			ret = copied;
11708c2ecf20Sopenharmony_ci			break;
11718c2ecf20Sopenharmony_ci		}
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_ci		for (n = 0; copied; n++, start = 0) {
11748c2ecf20Sopenharmony_ci			int size = min_t(int, copied, PAGE_SIZE - start);
11758c2ecf20Sopenharmony_ci			if (!failed) {
11768c2ecf20Sopenharmony_ci				buf.page = pages[n];
11778c2ecf20Sopenharmony_ci				buf.offset = start;
11788c2ecf20Sopenharmony_ci				buf.len = size;
11798c2ecf20Sopenharmony_ci				ret = add_to_pipe(pipe, &buf);
11808c2ecf20Sopenharmony_ci				if (unlikely(ret < 0)) {
11818c2ecf20Sopenharmony_ci					failed = true;
11828c2ecf20Sopenharmony_ci				} else {
11838c2ecf20Sopenharmony_ci					iov_iter_advance(from, ret);
11848c2ecf20Sopenharmony_ci					total += ret;
11858c2ecf20Sopenharmony_ci				}
11868c2ecf20Sopenharmony_ci			} else {
11878c2ecf20Sopenharmony_ci				put_page(pages[n]);
11888c2ecf20Sopenharmony_ci			}
11898c2ecf20Sopenharmony_ci			copied -= size;
11908c2ecf20Sopenharmony_ci		}
11918c2ecf20Sopenharmony_ci	}
11928c2ecf20Sopenharmony_ci	return total ? total : ret;
11938c2ecf20Sopenharmony_ci}
11948c2ecf20Sopenharmony_ci
11958c2ecf20Sopenharmony_cistatic int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
11968c2ecf20Sopenharmony_ci			struct splice_desc *sd)
11978c2ecf20Sopenharmony_ci{
11988c2ecf20Sopenharmony_ci	int n = copy_page_to_iter(buf->page, buf->offset, sd->len, sd->u.data);
11998c2ecf20Sopenharmony_ci	return n == sd->len ? n : -EFAULT;
12008c2ecf20Sopenharmony_ci}
12018c2ecf20Sopenharmony_ci
12028c2ecf20Sopenharmony_ci/*
12038c2ecf20Sopenharmony_ci * For lack of a better implementation, implement vmsplice() to userspace
12048c2ecf20Sopenharmony_ci * as a simple copy of the pipes pages to the user iov.
12058c2ecf20Sopenharmony_ci */
12068c2ecf20Sopenharmony_cistatic long vmsplice_to_user(struct file *file, struct iov_iter *iter,
12078c2ecf20Sopenharmony_ci			     unsigned int flags)
12088c2ecf20Sopenharmony_ci{
12098c2ecf20Sopenharmony_ci	struct pipe_inode_info *pipe = get_pipe_info(file, true);
12108c2ecf20Sopenharmony_ci	struct splice_desc sd = {
12118c2ecf20Sopenharmony_ci		.total_len = iov_iter_count(iter),
12128c2ecf20Sopenharmony_ci		.flags = flags,
12138c2ecf20Sopenharmony_ci		.u.data = iter
12148c2ecf20Sopenharmony_ci	};
12158c2ecf20Sopenharmony_ci	long ret = 0;
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_ci	if (!pipe)
12188c2ecf20Sopenharmony_ci		return -EBADF;
12198c2ecf20Sopenharmony_ci
12208c2ecf20Sopenharmony_ci	if (sd.total_len) {
12218c2ecf20Sopenharmony_ci		pipe_lock(pipe);
12228c2ecf20Sopenharmony_ci		ret = __splice_from_pipe(pipe, &sd, pipe_to_user);
12238c2ecf20Sopenharmony_ci		pipe_unlock(pipe);
12248c2ecf20Sopenharmony_ci	}
12258c2ecf20Sopenharmony_ci
12268c2ecf20Sopenharmony_ci	return ret;
12278c2ecf20Sopenharmony_ci}
12288c2ecf20Sopenharmony_ci
12298c2ecf20Sopenharmony_ci/*
12308c2ecf20Sopenharmony_ci * vmsplice splices a user address range into a pipe. It can be thought of
12318c2ecf20Sopenharmony_ci * as splice-from-memory, where the regular splice is splice-from-file (or
12328c2ecf20Sopenharmony_ci * to file). In both cases the output is a pipe, naturally.
12338c2ecf20Sopenharmony_ci */
12348c2ecf20Sopenharmony_cistatic long vmsplice_to_pipe(struct file *file, struct iov_iter *iter,
12358c2ecf20Sopenharmony_ci			     unsigned int flags)
12368c2ecf20Sopenharmony_ci{
12378c2ecf20Sopenharmony_ci	struct pipe_inode_info *pipe;
12388c2ecf20Sopenharmony_ci	long ret = 0;
12398c2ecf20Sopenharmony_ci	unsigned buf_flag = 0;
12408c2ecf20Sopenharmony_ci
12418c2ecf20Sopenharmony_ci	if (flags & SPLICE_F_GIFT)
12428c2ecf20Sopenharmony_ci		buf_flag = PIPE_BUF_FLAG_GIFT;
12438c2ecf20Sopenharmony_ci
12448c2ecf20Sopenharmony_ci	pipe = get_pipe_info(file, true);
12458c2ecf20Sopenharmony_ci	if (!pipe)
12468c2ecf20Sopenharmony_ci		return -EBADF;
12478c2ecf20Sopenharmony_ci
12488c2ecf20Sopenharmony_ci	pipe_lock(pipe);
12498c2ecf20Sopenharmony_ci	ret = wait_for_space(pipe, flags);
12508c2ecf20Sopenharmony_ci	if (!ret)
12518c2ecf20Sopenharmony_ci		ret = iter_to_pipe(iter, pipe, buf_flag);
12528c2ecf20Sopenharmony_ci	pipe_unlock(pipe);
12538c2ecf20Sopenharmony_ci	if (ret > 0)
12548c2ecf20Sopenharmony_ci		wakeup_pipe_readers(pipe);
12558c2ecf20Sopenharmony_ci	return ret;
12568c2ecf20Sopenharmony_ci}
12578c2ecf20Sopenharmony_ci
12588c2ecf20Sopenharmony_cistatic int vmsplice_type(struct fd f, int *type)
12598c2ecf20Sopenharmony_ci{
12608c2ecf20Sopenharmony_ci	if (!f.file)
12618c2ecf20Sopenharmony_ci		return -EBADF;
12628c2ecf20Sopenharmony_ci	if (f.file->f_mode & FMODE_WRITE) {
12638c2ecf20Sopenharmony_ci		*type = WRITE;
12648c2ecf20Sopenharmony_ci	} else if (f.file->f_mode & FMODE_READ) {
12658c2ecf20Sopenharmony_ci		*type = READ;
12668c2ecf20Sopenharmony_ci	} else {
12678c2ecf20Sopenharmony_ci		fdput(f);
12688c2ecf20Sopenharmony_ci		return -EBADF;
12698c2ecf20Sopenharmony_ci	}
12708c2ecf20Sopenharmony_ci	return 0;
12718c2ecf20Sopenharmony_ci}
12728c2ecf20Sopenharmony_ci
12738c2ecf20Sopenharmony_ci/*
12748c2ecf20Sopenharmony_ci * Note that vmsplice only really supports true splicing _from_ user memory
12758c2ecf20Sopenharmony_ci * to a pipe, not the other way around. Splicing from user memory is a simple
12768c2ecf20Sopenharmony_ci * operation that can be supported without any funky alignment restrictions
12778c2ecf20Sopenharmony_ci * or nasty vm tricks. We simply map in the user memory and fill them into
12788c2ecf20Sopenharmony_ci * a pipe. The reverse isn't quite as easy, though. There are two possible
12798c2ecf20Sopenharmony_ci * solutions for that:
12808c2ecf20Sopenharmony_ci *
12818c2ecf20Sopenharmony_ci *	- memcpy() the data internally, at which point we might as well just
12828c2ecf20Sopenharmony_ci *	  do a regular read() on the buffer anyway.
12838c2ecf20Sopenharmony_ci *	- Lots of nasty vm tricks, that are neither fast nor flexible (it
12848c2ecf20Sopenharmony_ci *	  has restriction limitations on both ends of the pipe).
12858c2ecf20Sopenharmony_ci *
12868c2ecf20Sopenharmony_ci * Currently we punt and implement it as a normal copy, see pipe_to_user().
12878c2ecf20Sopenharmony_ci *
12888c2ecf20Sopenharmony_ci */
12898c2ecf20Sopenharmony_ciSYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,
12908c2ecf20Sopenharmony_ci		unsigned long, nr_segs, unsigned int, flags)
12918c2ecf20Sopenharmony_ci{
12928c2ecf20Sopenharmony_ci	struct iovec iovstack[UIO_FASTIOV];
12938c2ecf20Sopenharmony_ci	struct iovec *iov = iovstack;
12948c2ecf20Sopenharmony_ci	struct iov_iter iter;
12958c2ecf20Sopenharmony_ci	ssize_t error;
12968c2ecf20Sopenharmony_ci	struct fd f;
12978c2ecf20Sopenharmony_ci	int type;
12988c2ecf20Sopenharmony_ci
12998c2ecf20Sopenharmony_ci	if (unlikely(flags & ~SPLICE_F_ALL))
13008c2ecf20Sopenharmony_ci		return -EINVAL;
13018c2ecf20Sopenharmony_ci
13028c2ecf20Sopenharmony_ci	f = fdget(fd);
13038c2ecf20Sopenharmony_ci	error = vmsplice_type(f, &type);
13048c2ecf20Sopenharmony_ci	if (error)
13058c2ecf20Sopenharmony_ci		return error;
13068c2ecf20Sopenharmony_ci
13078c2ecf20Sopenharmony_ci	error = import_iovec(type, uiov, nr_segs,
13088c2ecf20Sopenharmony_ci			     ARRAY_SIZE(iovstack), &iov, &iter);
13098c2ecf20Sopenharmony_ci	if (error < 0)
13108c2ecf20Sopenharmony_ci		goto out_fdput;
13118c2ecf20Sopenharmony_ci
13128c2ecf20Sopenharmony_ci	if (!iov_iter_count(&iter))
13138c2ecf20Sopenharmony_ci		error = 0;
13148c2ecf20Sopenharmony_ci	else if (iov_iter_rw(&iter) == WRITE)
13158c2ecf20Sopenharmony_ci		error = vmsplice_to_pipe(f.file, &iter, flags);
13168c2ecf20Sopenharmony_ci	else
13178c2ecf20Sopenharmony_ci		error = vmsplice_to_user(f.file, &iter, flags);
13188c2ecf20Sopenharmony_ci
13198c2ecf20Sopenharmony_ci	kfree(iov);
13208c2ecf20Sopenharmony_ciout_fdput:
13218c2ecf20Sopenharmony_ci	fdput(f);
13228c2ecf20Sopenharmony_ci	return error;
13238c2ecf20Sopenharmony_ci}
13248c2ecf20Sopenharmony_ci
13258c2ecf20Sopenharmony_ciSYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
13268c2ecf20Sopenharmony_ci		int, fd_out, loff_t __user *, off_out,
13278c2ecf20Sopenharmony_ci		size_t, len, unsigned int, flags)
13288c2ecf20Sopenharmony_ci{
13298c2ecf20Sopenharmony_ci	struct fd in, out;
13308c2ecf20Sopenharmony_ci	long error;
13318c2ecf20Sopenharmony_ci
13328c2ecf20Sopenharmony_ci	if (unlikely(!len))
13338c2ecf20Sopenharmony_ci		return 0;
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_ci	if (unlikely(flags & ~SPLICE_F_ALL))
13368c2ecf20Sopenharmony_ci		return -EINVAL;
13378c2ecf20Sopenharmony_ci
13388c2ecf20Sopenharmony_ci	error = -EBADF;
13398c2ecf20Sopenharmony_ci	in = fdget(fd_in);
13408c2ecf20Sopenharmony_ci	if (in.file) {
13418c2ecf20Sopenharmony_ci		out = fdget(fd_out);
13428c2ecf20Sopenharmony_ci		if (out.file) {
13438c2ecf20Sopenharmony_ci			error = __do_splice(in.file, off_in, out.file, off_out,
13448c2ecf20Sopenharmony_ci						len, flags);
13458c2ecf20Sopenharmony_ci			fdput(out);
13468c2ecf20Sopenharmony_ci		}
13478c2ecf20Sopenharmony_ci		fdput(in);
13488c2ecf20Sopenharmony_ci	}
13498c2ecf20Sopenharmony_ci	return error;
13508c2ecf20Sopenharmony_ci}
13518c2ecf20Sopenharmony_ci
13528c2ecf20Sopenharmony_ci/*
13538c2ecf20Sopenharmony_ci * Make sure there's data to read. Wait for input if we can, otherwise
13548c2ecf20Sopenharmony_ci * return an appropriate error.
13558c2ecf20Sopenharmony_ci */
13568c2ecf20Sopenharmony_cistatic int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
13578c2ecf20Sopenharmony_ci{
13588c2ecf20Sopenharmony_ci	int ret;
13598c2ecf20Sopenharmony_ci
13608c2ecf20Sopenharmony_ci	/*
13618c2ecf20Sopenharmony_ci	 * Check the pipe occupancy without the inode lock first. This function
13628c2ecf20Sopenharmony_ci	 * is speculative anyways, so missing one is ok.
13638c2ecf20Sopenharmony_ci	 */
13648c2ecf20Sopenharmony_ci	if (!pipe_empty(pipe->head, pipe->tail))
13658c2ecf20Sopenharmony_ci		return 0;
13668c2ecf20Sopenharmony_ci
13678c2ecf20Sopenharmony_ci	ret = 0;
13688c2ecf20Sopenharmony_ci	pipe_lock(pipe);
13698c2ecf20Sopenharmony_ci
13708c2ecf20Sopenharmony_ci	while (pipe_empty(pipe->head, pipe->tail)) {
13718c2ecf20Sopenharmony_ci		if (signal_pending(current)) {
13728c2ecf20Sopenharmony_ci			ret = -ERESTARTSYS;
13738c2ecf20Sopenharmony_ci			break;
13748c2ecf20Sopenharmony_ci		}
13758c2ecf20Sopenharmony_ci		if (!pipe->writers)
13768c2ecf20Sopenharmony_ci			break;
13778c2ecf20Sopenharmony_ci		if (flags & SPLICE_F_NONBLOCK) {
13788c2ecf20Sopenharmony_ci			ret = -EAGAIN;
13798c2ecf20Sopenharmony_ci			break;
13808c2ecf20Sopenharmony_ci		}
13818c2ecf20Sopenharmony_ci		pipe_wait_readable(pipe);
13828c2ecf20Sopenharmony_ci	}
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_ci	pipe_unlock(pipe);
13858c2ecf20Sopenharmony_ci	return ret;
13868c2ecf20Sopenharmony_ci}
13878c2ecf20Sopenharmony_ci
13888c2ecf20Sopenharmony_ci/*
13898c2ecf20Sopenharmony_ci * Make sure there's writeable room. Wait for room if we can, otherwise
13908c2ecf20Sopenharmony_ci * return an appropriate error.
13918c2ecf20Sopenharmony_ci */
13928c2ecf20Sopenharmony_cistatic int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
13938c2ecf20Sopenharmony_ci{
13948c2ecf20Sopenharmony_ci	int ret;
13958c2ecf20Sopenharmony_ci
13968c2ecf20Sopenharmony_ci	/*
13978c2ecf20Sopenharmony_ci	 * Check pipe occupancy without the inode lock first. This function
13988c2ecf20Sopenharmony_ci	 * is speculative anyways, so missing one is ok.
13998c2ecf20Sopenharmony_ci	 */
14008c2ecf20Sopenharmony_ci	if (!pipe_full(pipe->head, pipe->tail, pipe->max_usage))
14018c2ecf20Sopenharmony_ci		return 0;
14028c2ecf20Sopenharmony_ci
14038c2ecf20Sopenharmony_ci	ret = 0;
14048c2ecf20Sopenharmony_ci	pipe_lock(pipe);
14058c2ecf20Sopenharmony_ci
14068c2ecf20Sopenharmony_ci	while (pipe_full(pipe->head, pipe->tail, pipe->max_usage)) {
14078c2ecf20Sopenharmony_ci		if (!pipe->readers) {
14088c2ecf20Sopenharmony_ci			send_sig(SIGPIPE, current, 0);
14098c2ecf20Sopenharmony_ci			ret = -EPIPE;
14108c2ecf20Sopenharmony_ci			break;
14118c2ecf20Sopenharmony_ci		}
14128c2ecf20Sopenharmony_ci		if (flags & SPLICE_F_NONBLOCK) {
14138c2ecf20Sopenharmony_ci			ret = -EAGAIN;
14148c2ecf20Sopenharmony_ci			break;
14158c2ecf20Sopenharmony_ci		}
14168c2ecf20Sopenharmony_ci		if (signal_pending(current)) {
14178c2ecf20Sopenharmony_ci			ret = -ERESTARTSYS;
14188c2ecf20Sopenharmony_ci			break;
14198c2ecf20Sopenharmony_ci		}
14208c2ecf20Sopenharmony_ci		pipe_wait_writable(pipe);
14218c2ecf20Sopenharmony_ci	}
14228c2ecf20Sopenharmony_ci
14238c2ecf20Sopenharmony_ci	pipe_unlock(pipe);
14248c2ecf20Sopenharmony_ci	return ret;
14258c2ecf20Sopenharmony_ci}
14268c2ecf20Sopenharmony_ci
14278c2ecf20Sopenharmony_ci/*
14288c2ecf20Sopenharmony_ci * Splice contents of ipipe to opipe.
14298c2ecf20Sopenharmony_ci */
14308c2ecf20Sopenharmony_cistatic int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
14318c2ecf20Sopenharmony_ci			       struct pipe_inode_info *opipe,
14328c2ecf20Sopenharmony_ci			       size_t len, unsigned int flags)
14338c2ecf20Sopenharmony_ci{
14348c2ecf20Sopenharmony_ci	struct pipe_buffer *ibuf, *obuf;
14358c2ecf20Sopenharmony_ci	unsigned int i_head, o_head;
14368c2ecf20Sopenharmony_ci	unsigned int i_tail, o_tail;
14378c2ecf20Sopenharmony_ci	unsigned int i_mask, o_mask;
14388c2ecf20Sopenharmony_ci	int ret = 0;
14398c2ecf20Sopenharmony_ci	bool input_wakeup = false;
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_ci
14428c2ecf20Sopenharmony_ciretry:
14438c2ecf20Sopenharmony_ci	ret = ipipe_prep(ipipe, flags);
14448c2ecf20Sopenharmony_ci	if (ret)
14458c2ecf20Sopenharmony_ci		return ret;
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci	ret = opipe_prep(opipe, flags);
14488c2ecf20Sopenharmony_ci	if (ret)
14498c2ecf20Sopenharmony_ci		return ret;
14508c2ecf20Sopenharmony_ci
14518c2ecf20Sopenharmony_ci	/*
14528c2ecf20Sopenharmony_ci	 * Potential ABBA deadlock, work around it by ordering lock
14538c2ecf20Sopenharmony_ci	 * grabbing by pipe info address. Otherwise two different processes
14548c2ecf20Sopenharmony_ci	 * could deadlock (one doing tee from A -> B, the other from B -> A).
14558c2ecf20Sopenharmony_ci	 */
14568c2ecf20Sopenharmony_ci	pipe_double_lock(ipipe, opipe);
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_ci	i_tail = ipipe->tail;
14598c2ecf20Sopenharmony_ci	i_mask = ipipe->ring_size - 1;
14608c2ecf20Sopenharmony_ci	o_head = opipe->head;
14618c2ecf20Sopenharmony_ci	o_mask = opipe->ring_size - 1;
14628c2ecf20Sopenharmony_ci
14638c2ecf20Sopenharmony_ci	do {
14648c2ecf20Sopenharmony_ci		size_t o_len;
14658c2ecf20Sopenharmony_ci
14668c2ecf20Sopenharmony_ci		if (!opipe->readers) {
14678c2ecf20Sopenharmony_ci			send_sig(SIGPIPE, current, 0);
14688c2ecf20Sopenharmony_ci			if (!ret)
14698c2ecf20Sopenharmony_ci				ret = -EPIPE;
14708c2ecf20Sopenharmony_ci			break;
14718c2ecf20Sopenharmony_ci		}
14728c2ecf20Sopenharmony_ci
14738c2ecf20Sopenharmony_ci		i_head = ipipe->head;
14748c2ecf20Sopenharmony_ci		o_tail = opipe->tail;
14758c2ecf20Sopenharmony_ci
14768c2ecf20Sopenharmony_ci		if (pipe_empty(i_head, i_tail) && !ipipe->writers)
14778c2ecf20Sopenharmony_ci			break;
14788c2ecf20Sopenharmony_ci
14798c2ecf20Sopenharmony_ci		/*
14808c2ecf20Sopenharmony_ci		 * Cannot make any progress, because either the input
14818c2ecf20Sopenharmony_ci		 * pipe is empty or the output pipe is full.
14828c2ecf20Sopenharmony_ci		 */
14838c2ecf20Sopenharmony_ci		if (pipe_empty(i_head, i_tail) ||
14848c2ecf20Sopenharmony_ci		    pipe_full(o_head, o_tail, opipe->max_usage)) {
14858c2ecf20Sopenharmony_ci			/* Already processed some buffers, break */
14868c2ecf20Sopenharmony_ci			if (ret)
14878c2ecf20Sopenharmony_ci				break;
14888c2ecf20Sopenharmony_ci
14898c2ecf20Sopenharmony_ci			if (flags & SPLICE_F_NONBLOCK) {
14908c2ecf20Sopenharmony_ci				ret = -EAGAIN;
14918c2ecf20Sopenharmony_ci				break;
14928c2ecf20Sopenharmony_ci			}
14938c2ecf20Sopenharmony_ci
14948c2ecf20Sopenharmony_ci			/*
14958c2ecf20Sopenharmony_ci			 * We raced with another reader/writer and haven't
14968c2ecf20Sopenharmony_ci			 * managed to process any buffers.  A zero return
14978c2ecf20Sopenharmony_ci			 * value means EOF, so retry instead.
14988c2ecf20Sopenharmony_ci			 */
14998c2ecf20Sopenharmony_ci			pipe_unlock(ipipe);
15008c2ecf20Sopenharmony_ci			pipe_unlock(opipe);
15018c2ecf20Sopenharmony_ci			goto retry;
15028c2ecf20Sopenharmony_ci		}
15038c2ecf20Sopenharmony_ci
15048c2ecf20Sopenharmony_ci		ibuf = &ipipe->bufs[i_tail & i_mask];
15058c2ecf20Sopenharmony_ci		obuf = &opipe->bufs[o_head & o_mask];
15068c2ecf20Sopenharmony_ci
15078c2ecf20Sopenharmony_ci		if (len >= ibuf->len) {
15088c2ecf20Sopenharmony_ci			/*
15098c2ecf20Sopenharmony_ci			 * Simply move the whole buffer from ipipe to opipe
15108c2ecf20Sopenharmony_ci			 */
15118c2ecf20Sopenharmony_ci			*obuf = *ibuf;
15128c2ecf20Sopenharmony_ci			ibuf->ops = NULL;
15138c2ecf20Sopenharmony_ci			i_tail++;
15148c2ecf20Sopenharmony_ci			ipipe->tail = i_tail;
15158c2ecf20Sopenharmony_ci			input_wakeup = true;
15168c2ecf20Sopenharmony_ci			o_len = obuf->len;
15178c2ecf20Sopenharmony_ci			o_head++;
15188c2ecf20Sopenharmony_ci			opipe->head = o_head;
15198c2ecf20Sopenharmony_ci		} else {
15208c2ecf20Sopenharmony_ci			/*
15218c2ecf20Sopenharmony_ci			 * Get a reference to this pipe buffer,
15228c2ecf20Sopenharmony_ci			 * so we can copy the contents over.
15238c2ecf20Sopenharmony_ci			 */
15248c2ecf20Sopenharmony_ci			if (!pipe_buf_get(ipipe, ibuf)) {
15258c2ecf20Sopenharmony_ci				if (ret == 0)
15268c2ecf20Sopenharmony_ci					ret = -EFAULT;
15278c2ecf20Sopenharmony_ci				break;
15288c2ecf20Sopenharmony_ci			}
15298c2ecf20Sopenharmony_ci			*obuf = *ibuf;
15308c2ecf20Sopenharmony_ci
15318c2ecf20Sopenharmony_ci			/*
15328c2ecf20Sopenharmony_ci			 * Don't inherit the gift and merge flags, we need to
15338c2ecf20Sopenharmony_ci			 * prevent multiple steals of this page.
15348c2ecf20Sopenharmony_ci			 */
15358c2ecf20Sopenharmony_ci			obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
15368c2ecf20Sopenharmony_ci			obuf->flags &= ~PIPE_BUF_FLAG_CAN_MERGE;
15378c2ecf20Sopenharmony_ci
15388c2ecf20Sopenharmony_ci			obuf->len = len;
15398c2ecf20Sopenharmony_ci			ibuf->offset += len;
15408c2ecf20Sopenharmony_ci			ibuf->len -= len;
15418c2ecf20Sopenharmony_ci			o_len = len;
15428c2ecf20Sopenharmony_ci			o_head++;
15438c2ecf20Sopenharmony_ci			opipe->head = o_head;
15448c2ecf20Sopenharmony_ci		}
15458c2ecf20Sopenharmony_ci		ret += o_len;
15468c2ecf20Sopenharmony_ci		len -= o_len;
15478c2ecf20Sopenharmony_ci	} while (len);
15488c2ecf20Sopenharmony_ci
15498c2ecf20Sopenharmony_ci	pipe_unlock(ipipe);
15508c2ecf20Sopenharmony_ci	pipe_unlock(opipe);
15518c2ecf20Sopenharmony_ci
15528c2ecf20Sopenharmony_ci	/*
15538c2ecf20Sopenharmony_ci	 * If we put data in the output pipe, wakeup any potential readers.
15548c2ecf20Sopenharmony_ci	 */
15558c2ecf20Sopenharmony_ci	if (ret > 0)
15568c2ecf20Sopenharmony_ci		wakeup_pipe_readers(opipe);
15578c2ecf20Sopenharmony_ci
15588c2ecf20Sopenharmony_ci	if (input_wakeup)
15598c2ecf20Sopenharmony_ci		wakeup_pipe_writers(ipipe);
15608c2ecf20Sopenharmony_ci
15618c2ecf20Sopenharmony_ci	return ret;
15628c2ecf20Sopenharmony_ci}
15638c2ecf20Sopenharmony_ci
15648c2ecf20Sopenharmony_ci/*
15658c2ecf20Sopenharmony_ci * Link contents of ipipe to opipe.
15668c2ecf20Sopenharmony_ci */
15678c2ecf20Sopenharmony_cistatic int link_pipe(struct pipe_inode_info *ipipe,
15688c2ecf20Sopenharmony_ci		     struct pipe_inode_info *opipe,
15698c2ecf20Sopenharmony_ci		     size_t len, unsigned int flags)
15708c2ecf20Sopenharmony_ci{
15718c2ecf20Sopenharmony_ci	struct pipe_buffer *ibuf, *obuf;
15728c2ecf20Sopenharmony_ci	unsigned int i_head, o_head;
15738c2ecf20Sopenharmony_ci	unsigned int i_tail, o_tail;
15748c2ecf20Sopenharmony_ci	unsigned int i_mask, o_mask;
15758c2ecf20Sopenharmony_ci	int ret = 0;
15768c2ecf20Sopenharmony_ci
15778c2ecf20Sopenharmony_ci	/*
15788c2ecf20Sopenharmony_ci	 * Potential ABBA deadlock, work around it by ordering lock
15798c2ecf20Sopenharmony_ci	 * grabbing by pipe info address. Otherwise two different processes
15808c2ecf20Sopenharmony_ci	 * could deadlock (one doing tee from A -> B, the other from B -> A).
15818c2ecf20Sopenharmony_ci	 */
15828c2ecf20Sopenharmony_ci	pipe_double_lock(ipipe, opipe);
15838c2ecf20Sopenharmony_ci
15848c2ecf20Sopenharmony_ci	i_tail = ipipe->tail;
15858c2ecf20Sopenharmony_ci	i_mask = ipipe->ring_size - 1;
15868c2ecf20Sopenharmony_ci	o_head = opipe->head;
15878c2ecf20Sopenharmony_ci	o_mask = opipe->ring_size - 1;
15888c2ecf20Sopenharmony_ci
15898c2ecf20Sopenharmony_ci	do {
15908c2ecf20Sopenharmony_ci		if (!opipe->readers) {
15918c2ecf20Sopenharmony_ci			send_sig(SIGPIPE, current, 0);
15928c2ecf20Sopenharmony_ci			if (!ret)
15938c2ecf20Sopenharmony_ci				ret = -EPIPE;
15948c2ecf20Sopenharmony_ci			break;
15958c2ecf20Sopenharmony_ci		}
15968c2ecf20Sopenharmony_ci
15978c2ecf20Sopenharmony_ci		i_head = ipipe->head;
15988c2ecf20Sopenharmony_ci		o_tail = opipe->tail;
15998c2ecf20Sopenharmony_ci
16008c2ecf20Sopenharmony_ci		/*
16018c2ecf20Sopenharmony_ci		 * If we have iterated all input buffers or run out of
16028c2ecf20Sopenharmony_ci		 * output room, break.
16038c2ecf20Sopenharmony_ci		 */
16048c2ecf20Sopenharmony_ci		if (pipe_empty(i_head, i_tail) ||
16058c2ecf20Sopenharmony_ci		    pipe_full(o_head, o_tail, opipe->max_usage))
16068c2ecf20Sopenharmony_ci			break;
16078c2ecf20Sopenharmony_ci
16088c2ecf20Sopenharmony_ci		ibuf = &ipipe->bufs[i_tail & i_mask];
16098c2ecf20Sopenharmony_ci		obuf = &opipe->bufs[o_head & o_mask];
16108c2ecf20Sopenharmony_ci
16118c2ecf20Sopenharmony_ci		/*
16128c2ecf20Sopenharmony_ci		 * Get a reference to this pipe buffer,
16138c2ecf20Sopenharmony_ci		 * so we can copy the contents over.
16148c2ecf20Sopenharmony_ci		 */
16158c2ecf20Sopenharmony_ci		if (!pipe_buf_get(ipipe, ibuf)) {
16168c2ecf20Sopenharmony_ci			if (ret == 0)
16178c2ecf20Sopenharmony_ci				ret = -EFAULT;
16188c2ecf20Sopenharmony_ci			break;
16198c2ecf20Sopenharmony_ci		}
16208c2ecf20Sopenharmony_ci
16218c2ecf20Sopenharmony_ci		*obuf = *ibuf;
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci		/*
16248c2ecf20Sopenharmony_ci		 * Don't inherit the gift and merge flag, we need to prevent
16258c2ecf20Sopenharmony_ci		 * multiple steals of this page.
16268c2ecf20Sopenharmony_ci		 */
16278c2ecf20Sopenharmony_ci		obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
16288c2ecf20Sopenharmony_ci		obuf->flags &= ~PIPE_BUF_FLAG_CAN_MERGE;
16298c2ecf20Sopenharmony_ci
16308c2ecf20Sopenharmony_ci		if (obuf->len > len)
16318c2ecf20Sopenharmony_ci			obuf->len = len;
16328c2ecf20Sopenharmony_ci		ret += obuf->len;
16338c2ecf20Sopenharmony_ci		len -= obuf->len;
16348c2ecf20Sopenharmony_ci
16358c2ecf20Sopenharmony_ci		o_head++;
16368c2ecf20Sopenharmony_ci		opipe->head = o_head;
16378c2ecf20Sopenharmony_ci		i_tail++;
16388c2ecf20Sopenharmony_ci	} while (len);
16398c2ecf20Sopenharmony_ci
16408c2ecf20Sopenharmony_ci	pipe_unlock(ipipe);
16418c2ecf20Sopenharmony_ci	pipe_unlock(opipe);
16428c2ecf20Sopenharmony_ci
16438c2ecf20Sopenharmony_ci	/*
16448c2ecf20Sopenharmony_ci	 * If we put data in the output pipe, wakeup any potential readers.
16458c2ecf20Sopenharmony_ci	 */
16468c2ecf20Sopenharmony_ci	if (ret > 0)
16478c2ecf20Sopenharmony_ci		wakeup_pipe_readers(opipe);
16488c2ecf20Sopenharmony_ci
16498c2ecf20Sopenharmony_ci	return ret;
16508c2ecf20Sopenharmony_ci}
16518c2ecf20Sopenharmony_ci
16528c2ecf20Sopenharmony_ci/*
16538c2ecf20Sopenharmony_ci * This is a tee(1) implementation that works on pipes. It doesn't copy
16548c2ecf20Sopenharmony_ci * any data, it simply references the 'in' pages on the 'out' pipe.
16558c2ecf20Sopenharmony_ci * The 'flags' used are the SPLICE_F_* variants, currently the only
16568c2ecf20Sopenharmony_ci * applicable one is SPLICE_F_NONBLOCK.
16578c2ecf20Sopenharmony_ci */
16588c2ecf20Sopenharmony_cilong do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
16598c2ecf20Sopenharmony_ci{
16608c2ecf20Sopenharmony_ci	struct pipe_inode_info *ipipe = get_pipe_info(in, true);
16618c2ecf20Sopenharmony_ci	struct pipe_inode_info *opipe = get_pipe_info(out, true);
16628c2ecf20Sopenharmony_ci	int ret = -EINVAL;
16638c2ecf20Sopenharmony_ci
16648c2ecf20Sopenharmony_ci	if (unlikely(!(in->f_mode & FMODE_READ) ||
16658c2ecf20Sopenharmony_ci		     !(out->f_mode & FMODE_WRITE)))
16668c2ecf20Sopenharmony_ci		return -EBADF;
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ci	/*
16698c2ecf20Sopenharmony_ci	 * Duplicate the contents of ipipe to opipe without actually
16708c2ecf20Sopenharmony_ci	 * copying the data.
16718c2ecf20Sopenharmony_ci	 */
16728c2ecf20Sopenharmony_ci	if (ipipe && opipe && ipipe != opipe) {
16738c2ecf20Sopenharmony_ci		if ((in->f_flags | out->f_flags) & O_NONBLOCK)
16748c2ecf20Sopenharmony_ci			flags |= SPLICE_F_NONBLOCK;
16758c2ecf20Sopenharmony_ci
16768c2ecf20Sopenharmony_ci		/*
16778c2ecf20Sopenharmony_ci		 * Keep going, unless we encounter an error. The ipipe/opipe
16788c2ecf20Sopenharmony_ci		 * ordering doesn't really matter.
16798c2ecf20Sopenharmony_ci		 */
16808c2ecf20Sopenharmony_ci		ret = ipipe_prep(ipipe, flags);
16818c2ecf20Sopenharmony_ci		if (!ret) {
16828c2ecf20Sopenharmony_ci			ret = opipe_prep(opipe, flags);
16838c2ecf20Sopenharmony_ci			if (!ret)
16848c2ecf20Sopenharmony_ci				ret = link_pipe(ipipe, opipe, len, flags);
16858c2ecf20Sopenharmony_ci		}
16868c2ecf20Sopenharmony_ci	}
16878c2ecf20Sopenharmony_ci
16888c2ecf20Sopenharmony_ci	return ret;
16898c2ecf20Sopenharmony_ci}
16908c2ecf20Sopenharmony_ci
16918c2ecf20Sopenharmony_ciSYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
16928c2ecf20Sopenharmony_ci{
16938c2ecf20Sopenharmony_ci	struct fd in, out;
16948c2ecf20Sopenharmony_ci	int error;
16958c2ecf20Sopenharmony_ci
16968c2ecf20Sopenharmony_ci	if (unlikely(flags & ~SPLICE_F_ALL))
16978c2ecf20Sopenharmony_ci		return -EINVAL;
16988c2ecf20Sopenharmony_ci
16998c2ecf20Sopenharmony_ci	if (unlikely(!len))
17008c2ecf20Sopenharmony_ci		return 0;
17018c2ecf20Sopenharmony_ci
17028c2ecf20Sopenharmony_ci	error = -EBADF;
17038c2ecf20Sopenharmony_ci	in = fdget(fdin);
17048c2ecf20Sopenharmony_ci	if (in.file) {
17058c2ecf20Sopenharmony_ci		out = fdget(fdout);
17068c2ecf20Sopenharmony_ci		if (out.file) {
17078c2ecf20Sopenharmony_ci			error = do_tee(in.file, out.file, len, flags);
17088c2ecf20Sopenharmony_ci			fdput(out);
17098c2ecf20Sopenharmony_ci		}
17108c2ecf20Sopenharmony_ci 		fdput(in);
17118c2ecf20Sopenharmony_ci 	}
17128c2ecf20Sopenharmony_ci
17138c2ecf20Sopenharmony_ci	return error;
17148c2ecf20Sopenharmony_ci}
1715