]> err.no Git - linux-2.6/blobdiff - fs/pipe.c
[PATCH] splice: fix bugs in pipe_to_file()
[linux-2.6] / fs / pipe.c
index e984beb93a0ea88c436037f6e17c0edfbad37d54..888f265011bf46b539510d8f9ffa13a5eb844c7f 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -99,8 +99,6 @@ static void anon_pipe_buf_release(struct pipe_inode_info *pipe,
 {
        struct page *page = buf->page;
 
-       buf->flags &= ~PIPE_BUF_FLAG_STOLEN;
-
        /*
         * If nobody else uses this page, and we don't already have a
         * temporary page, let's keep track of it as a one-deep
@@ -127,8 +125,20 @@ static void anon_pipe_buf_unmap(struct pipe_inode_info *pipe,
 static int anon_pipe_buf_steal(struct pipe_inode_info *pipe,
                               struct pipe_buffer *buf)
 {
-       buf->flags |= PIPE_BUF_FLAG_STOLEN;
-       return 0;
+       struct page *page = buf->page;
+
+       if (page_count(page) == 1) {
+               lock_page(page);
+               return 0;
+       }
+
+       return 1;
+}
+
+static void anon_pipe_buf_get(struct pipe_inode_info *info,
+                             struct pipe_buffer *buf)
+{
+       page_cache_get(buf->page);
 }
 
 static struct pipe_buf_operations anon_pipe_buf_ops = {
@@ -137,6 +147,7 @@ static struct pipe_buf_operations anon_pipe_buf_ops = {
        .unmap = anon_pipe_buf_unmap,
        .release = anon_pipe_buf_release,
        .steal = anon_pipe_buf_steal,
+       .get = anon_pipe_buf_get,
 };
 
 static ssize_t