Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Linus Torvalds <torvalds@osdl.org>

+24 -4
+21 -4
fs/splice.c
··· 106 106 107 107 static ssize_t move_to_pipe(struct inode *inode, struct page **pages, 108 108 int nr_pages, unsigned long offset, 109 - unsigned long len) 109 + unsigned long len, unsigned int flags) 110 110 { 111 111 struct pipe_inode_info *info; 112 112 int ret, do_wakeup, i; ··· 159 159 break; 160 160 } 161 161 162 + if (flags & SPLICE_F_NONBLOCK) { 163 + if (!ret) 164 + ret = -EAGAIN; 165 + break; 166 + } 167 + 162 168 if (signal_pending(current)) { 163 169 if (!ret) 164 170 ret = -ERESTARTSYS; ··· 197 191 } 198 192 199 193 static int __generic_file_splice_read(struct file *in, struct inode *pipe, 200 - size_t len) 194 + size_t len, unsigned int flags) 201 195 { 202 196 struct address_space *mapping = in->f_mapping; 203 197 unsigned int offset, nr_pages; ··· 285 279 * Now we splice them into the pipe.. 286 280 */ 287 281 splice_them: 288 - return move_to_pipe(pipe, pages, i, offset, len); 282 + return move_to_pipe(pipe, pages, i, offset, len, flags); 289 283 } 290 284 291 285 ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, ··· 297 291 ret = 0; 298 292 spliced = 0; 299 293 while (len) { 300 - ret = __generic_file_splice_read(in, pipe, len); 294 + ret = __generic_file_splice_read(in, pipe, len, flags); 301 295 302 296 if (ret <= 0) 303 297 break; ··· 305 299 in->f_pos += ret; 306 300 len -= ret; 307 301 spliced += ret; 302 + 303 + if (!(flags & SPLICE_F_NONBLOCK)) 304 + continue; 305 + ret = -EAGAIN; 306 + break; 308 307 } 309 308 310 309 if (spliced) ··· 536 525 if (!PIPE_WAITING_WRITERS(*inode)) { 537 526 if (ret) 538 527 break; 528 + } 529 + 530 + if (flags & SPLICE_F_NONBLOCK) { 531 + if (!ret) 532 + ret = -EAGAIN; 533 + break; 539 534 } 540 535 541 536 if (signal_pending(current)) {
+3
include/linux/pipe_fs_i.h
··· 60 60 * add the splice flags here. 61 61 */ 62 62 #define SPLICE_F_MOVE (0x01) /* move pages instead of copying */ 63 + #define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */ 64 + /* we may still block on the fd we splice */ 65 + /* from/to, of course */ 63 66 64 67 #endif