diff --git a/fs/splice.c b/fs/splice.c
index 7c2bbf18d7a7c3622679bbf6e6a7f0bc0a78c7fa..6081cf7d2d1ba91c0b5d613904994cdd6876b8b9 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -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;
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 75c7f55023ab67912452fad79330dfd36ad59e7c..d218fc72931997685eca76891afaf0c3a3e98730 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -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