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;