Skip to content

Commit

Permalink
splice: add SPLICE_F_NONBLOCK flag
Browse files Browse the repository at this point in the history
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: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Linus Torvalds committed Apr 2, 2006
1 parent b45e516 commit 29e3509
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
25 changes: 21 additions & 4 deletions fs/splice.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -291,14 +297,19 @@ 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;

in->f_pos += ret;
len -= ret;
spliced += ret;

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

if (spliced)
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions include/linux/pipe_fs_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 29e3509

Please sign in to comment.