提交 c64610ba 编写于 作者: A Andrew Morton 提交者: Linus Torvalds

[PATCH] block_read_full_page() get_block() error handling fix

If block_read_full_page() detects an error when running get_block() it will
run SetPageError(), then it will zero out the block in pagecache and will mark
the buffer_head uptodate.

So at the end of readahead we end up with a non-uptodate pagecache page which
is marked PageError.  But it has uptodate buffers.

The pagefault code will run ClearPageError, will launch readpage a second time
and block_read_full_page() will notice the uptodate buffers and will mark the
page uptodate as well.  We end up with an uptodate, !PageError page full of
zeros and the error is lost.

(It seems a little odd that filemap_nopage() runs ClearPageError().  I guess
all of this adds up to meaning that for each attempted access to the page, the
pagefault handler will retry the I/O.  Which is good and bad.  If the app is
ignoring SIGBUS for some reason we could get a lot of back-to-back I/O
errors.)

Fix it by not marking the pagecache buffer_head as uptodate if the attempt to
map that buffer to a disk block failed.

Credit-to: Qu Fuping <fs@ercist.iscas.ac.cn>

  For reporting the bug and identifying its source.
Signed-off-by: NQu Fuping <fs@ercist.iscas.ac.cn>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 3c0547ba
......@@ -2094,9 +2094,12 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
continue;
if (!buffer_mapped(bh)) {
int err = 0;
fully_mapped = 0;
if (iblock < lblock) {
if (get_block(inode, iblock, bh, 0))
err = get_block(inode, iblock, bh, 0);
if (err)
SetPageError(page);
}
if (!buffer_mapped(bh)) {
......@@ -2104,7 +2107,8 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
memset(kaddr + i * blocksize, 0, blocksize);
flush_dcache_page(page);
kunmap_atomic(kaddr, KM_USER0);
set_buffer_uptodate(bh);
if (!err)
set_buffer_uptodate(bh);
continue;
}
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册