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

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
...@@ -106,7 +106,7 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = { ...@@ -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, static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
int nr_pages, unsigned long offset, int nr_pages, unsigned long offset,
unsigned long len) unsigned long len, unsigned int flags)
{ {
struct pipe_inode_info *info; struct pipe_inode_info *info;
int ret, do_wakeup, i; int ret, do_wakeup, i;
...@@ -159,6 +159,12 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, ...@@ -159,6 +159,12 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
break; break;
} }
if (flags & SPLICE_F_NONBLOCK) {
if (!ret)
ret = -EAGAIN;
break;
}
if (signal_pending(current)) { if (signal_pending(current)) {
if (!ret) if (!ret)
ret = -ERESTARTSYS; ret = -ERESTARTSYS;
...@@ -191,7 +197,7 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages, ...@@ -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, 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; struct address_space *mapping = in->f_mapping;
unsigned int offset, nr_pages; unsigned int offset, nr_pages;
...@@ -279,7 +285,7 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, ...@@ -279,7 +285,7 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
* Now we splice them into the pipe.. * Now we splice them into the pipe..
*/ */
splice_them: 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, 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, ...@@ -291,7 +297,7 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
ret = 0; ret = 0;
spliced = 0; spliced = 0;
while (len) { while (len) {
ret = __generic_file_splice_read(in, pipe, len); ret = __generic_file_splice_read(in, pipe, len, flags);
if (ret <= 0) if (ret <= 0)
break; break;
...@@ -299,6 +305,11 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, ...@@ -299,6 +305,11 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
in->f_pos += ret; in->f_pos += ret;
len -= ret; len -= ret;
spliced += ret; spliced += ret;
if (!(flags & SPLICE_F_NONBLOCK))
continue;
ret = -EAGAIN;
break;
} }
if (spliced) if (spliced)
...@@ -527,6 +538,12 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out, ...@@ -527,6 +538,12 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
break; break;
} }
if (flags & SPLICE_F_NONBLOCK) {
if (!ret)
ret = -EAGAIN;
break;
}
if (signal_pending(current)) { if (signal_pending(current)) {
if (!ret) if (!ret)
ret = -ERESTARTSYS; ret = -ERESTARTSYS;
......
...@@ -60,5 +60,8 @@ void free_pipe_info(struct inode* inode); ...@@ -60,5 +60,8 @@ void free_pipe_info(struct inode* inode);
* add the splice flags here. * add the splice flags here.
*/ */
#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */ #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 #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment