Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29e35094 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

splice: add SPLICE_F_NONBLOCK flag



It doesn't make the splice itself necessarily nonblocking (because the
actual file descriptors that are spliced from/to may block unless they
have the O_NONBLOCK flag set), but it makes the splice pipe operations
nonblocking.

Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b45e516f
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = {

static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
			    int nr_pages, unsigned long offset,
			    unsigned long len)
			    unsigned long len, unsigned int flags)
{
	struct pipe_inode_info *info;
	int ret, do_wakeup, i;
@@ -159,6 +159,12 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
			break;
		}

		if (flags & SPLICE_F_NONBLOCK) {
			if (!ret)
				ret = -EAGAIN;
			break;
		}

		if (signal_pending(current)) {
			if (!ret)
				ret = -ERESTARTSYS;
@@ -191,7 +197,7 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
}

static int __generic_file_splice_read(struct file *in, struct inode *pipe,
				      size_t len)
				      size_t len, unsigned int flags)
{
	struct address_space *mapping = in->f_mapping;
	unsigned int offset, nr_pages;
@@ -279,7 +285,7 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
	 * Now we splice them into the pipe..
	 */
splice_them:
	return move_to_pipe(pipe, pages, i, offset, len);
	return move_to_pipe(pipe, pages, i, offset, len, flags);
}

ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
@@ -291,7 +297,7 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
	ret = 0;
	spliced = 0;
	while (len) {
		ret = __generic_file_splice_read(in, pipe, len);
		ret = __generic_file_splice_read(in, pipe, len, flags);

		if (ret <= 0)
			break;
@@ -299,6 +305,11 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
		in->f_pos += ret;
		len -= ret;
		spliced += ret;

		if (!(flags & SPLICE_F_NONBLOCK))
			continue;
		ret = -EAGAIN;
		break;
	}

	if (spliced)
@@ -527,6 +538,12 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
				break;
		}

		if (flags & SPLICE_F_NONBLOCK) {
			if (!ret)
				ret = -EAGAIN;
			break;
		}

		if (signal_pending(current)) {
			if (!ret)
				ret = -ERESTARTSYS;
+3 −0
Original line number Diff line number Diff line
@@ -60,5 +60,8 @@ void free_pipe_info(struct inode* inode);
 * add the splice flags here.
 */
#define SPLICE_F_MOVE	(0x01)	/* move pages instead of copying */
#define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
				 /* we may still block on the fd we splice */
				 /* from/to, of course */

#endif