diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2008-05-14 19:05:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-14 22:11:13 -0400 |
commit | 3ef0f720e47e895b613b0305eb0a483e3ec11f23 (patch) | |
tree | e696a950d76c90199661515e1068fc00102a15bf /mm/filemap.c | |
parent | 3b73a223661ed137c5d3d2635f954382e94f5a43 (diff) |
mm: fix infinite loop in filemap_fault
filemap_fault will go into an infinite loop if ->readpage() fails
asynchronously.
AFAICS the bug was introduced by this commit, which removed the wait after the
final readpage:
commit d00806b183152af6d24f46f0c33f14162ca1262a
Author: Nick Piggin <npiggin@suse.de>
Date: Thu Jul 19 01:46:57 2007 -0700
mm: fix fault vs invalidate race for linear mappings
Fix by reintroducing the wait_on_page_locked() after ->readpage() to make sure
the page is up-to-date before jumping back to the beginning of the function.
I've noticed this while testing nfs exporting on fuse. The patch
fixes it.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Cc: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 2dead9adf8b7..1e6a7d34874f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1461,6 +1461,11 @@ page_not_uptodate: | |||
1461 | */ | 1461 | */ |
1462 | ClearPageError(page); | 1462 | ClearPageError(page); |
1463 | error = mapping->a_ops->readpage(file, page); | 1463 | error = mapping->a_ops->readpage(file, page); |
1464 | if (!error) { | ||
1465 | wait_on_page_locked(page); | ||
1466 | if (!PageUptodate(page)) | ||
1467 | error = -EIO; | ||
1468 | } | ||
1464 | page_cache_release(page); | 1469 | page_cache_release(page); |
1465 | 1470 | ||
1466 | if (!error || error == AOP_TRUNCATED_PAGE) | 1471 | if (!error || error == AOP_TRUNCATED_PAGE) |