/* This is a tee(1) implementation that works on pipes. It doesn't copy any data, it simply references the 'in' pages on the 'out' pipe. The 'flags' used are the SPLICE_F_* variants, currently the only applicable one is SPLICE_F_NONBLOCK.  */
static long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
/* This is a tee(1) implementation that works on pipes. It doesn't copy any data, it simply references the 'in' pages on the 'out' pipe. The 'flags' used are the SPLICE_F_* variants, currently the only applicable one is SPLICE_F_NONBLOCK.  */
static long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
{
	struct pipe_inode_info *ipipe = pipe_info(in->f_path.dentry->d_inode);
	struct pipe_inode_info *opipe = pipe_info(out->f_path.dentry->d_inode);
	int ret = -EINVAL;
	if (ipipe && opipe && ipipe != opipe) {
		ret = ipipe_prep(ipipe, flags);
		if (!ret) {
			ret = opipe_prep(opipe, flags);
			if (!ret)
				ret = link_pipe(ipipe, opipe, len, flags);
		}
	}
	return ret;
}