struct pipe_buffer *buf)
 {
        struct page *page = buf->page;
-
-       lock_page(page);
+       int err;
 
        if (!PageUptodate(page)) {
-               unlock_page(page);
-               return ERR_PTR(-EIO);
-       }
+               lock_page(page);
+
+               /*
+                * Page got truncated/unhashed. This will cause a 0-byte
+                * splice, if this is the first page
+                */
+               if (!page->mapping) {
+                       err = -ENODATA;
+                       goto error;
+               }
+
+               /*
+                * uh oh, read-error from disk
+                */
+               if (!PageUptodate(page)) {
+                       err = -EIO;
+                       goto error;
+               }
 
-       if (!page->mapping) {
+               /*
+                * page is ok afterall, fall through to mapping
+                */
                unlock_page(page);
-               return ERR_PTR(-ENODATA);
        }
 
-       return kmap(buf->page);
+       return kmap(page);
+error:
+       unlock_page(page);
+       return ERR_PTR(err);
 }
 
 static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
                                      struct pipe_buffer *buf)
 {
-       unlock_page(buf->page);
        kunmap(buf->page);
 }
 
        int ret;
 
        /*
-        * after this, page will be locked and unmapped
+        * make sure the data in this buffer is uptodate
         */
        src = buf->ops->map(file, info, buf);
        if (IS_ERR(src))
                if (buf->ops->steal(info, buf))
                        goto find_page;
 
+               /*
+                * this will also set the page locked
+                */
                page = buf->page;
                if (add_to_page_cache(page, mapping, index, gfp_mask))
                        goto find_page;