Commit 73861c9c authored by Dave Jones's avatar Dave Jones

[PATCH] Detect get_block() errors in block_read_full_page()

Originally from Anton Altaparmakov..

This causes errors from get_block() in block_read_full_page() to be
detected and handled properly (by setting page error flag).  Without the
patch the page (or parts of the page) will contain random data on
get_block() failing without any form of error being signalled which can
be catastrophic for filesystems using block_read_full_page() for
accessing their metadata.  And for normal data it would mean the user
would see random data instead of what they expected.
parent 1e4f2ef4
...@@ -795,8 +795,11 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate) ...@@ -795,8 +795,11 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate)
unlock_buffer(bh); unlock_buffer(bh);
tmp = bh->b_this_page; tmp = bh->b_this_page;
while (tmp != bh) { while (tmp != bh) {
if (buffer_async(tmp) && buffer_locked(tmp)) if (buffer_locked(tmp)) {
if (buffer_async(tmp))
goto still_busy; goto still_busy;
} else if (!buffer_uptodate(tmp))
SetPageError(page);
tmp = tmp->b_this_page; tmp = tmp->b_this_page;
} }
...@@ -1716,7 +1719,7 @@ int block_read_full_page(struct page *page, get_block_t *get_block) ...@@ -1716,7 +1719,7 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
if (!buffer_mapped(bh)) { if (!buffer_mapped(bh)) {
if (iblock < lblock) { if (iblock < lblock) {
if (get_block(inode, iblock, bh, 0)) if (get_block(inode, iblock, bh, 0))
continue; SetPageError(page);
} }
if (!buffer_mapped(bh)) { if (!buffer_mapped(bh)) {
memset(kmap(page) + i*blocksize, 0, blocksize); memset(kmap(page) + i*blocksize, 0, blocksize);
...@@ -1736,9 +1739,10 @@ int block_read_full_page(struct page *page, get_block_t *get_block) ...@@ -1736,9 +1739,10 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
if (!nr) { if (!nr) {
/* /*
* all buffers are uptodate - we can set the page * All buffers are uptodate - we can set the page uptodate
* uptodate as well. * as well. But not if get_block() returned an error.
*/ */
if (!PageError(page))
SetPageUptodate(page); SetPageUptodate(page);
UnlockPage(page); UnlockPage(page);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment