mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
NFS: Ensure that nfs_wb_page() waits for Pg_writeback to clear
Neil Brown reports that he is seeing the BUG_ON(ret == 0) trigger in nfs_page_async_flush. According to the trace in https://bugzilla.novell.com/show_bug.cgi?id=599628 the problem appears to be due to nfs_wb_page() not waiting for the PG_writeback flag to clear. There is a ditto problem in nfs_wb_page_cancel() Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
71d0a6112a
commit
ba8b06e67e
@ -1472,6 +1472,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
|
||||
|
||||
BUG_ON(!PageLocked(page));
|
||||
for (;;) {
|
||||
wait_on_page_writeback(page);
|
||||
req = nfs_page_find_request(page);
|
||||
if (req == NULL)
|
||||
break;
|
||||
@ -1506,30 +1507,18 @@ int nfs_wb_page(struct inode *inode, struct page *page)
|
||||
.range_start = range_start,
|
||||
.range_end = range_end,
|
||||
};
|
||||
struct nfs_page *req;
|
||||
int need_commit;
|
||||
int ret;
|
||||
|
||||
while(PagePrivate(page)) {
|
||||
wait_on_page_writeback(page);
|
||||
if (clear_page_dirty_for_io(page)) {
|
||||
ret = nfs_writepage_locked(page, &wbc);
|
||||
if (ret < 0)
|
||||
goto out_error;
|
||||
}
|
||||
req = nfs_find_and_lock_request(page);
|
||||
if (!req)
|
||||
break;
|
||||
if (IS_ERR(req)) {
|
||||
ret = PTR_ERR(req);
|
||||
ret = sync_inode(inode, &wbc);
|
||||
if (ret < 0)
|
||||
goto out_error;
|
||||
}
|
||||
need_commit = test_bit(PG_CLEAN, &req->wb_flags);
|
||||
nfs_clear_page_tag_locked(req);
|
||||
if (need_commit) {
|
||||
ret = nfs_commit_inode(inode, FLUSH_SYNC);
|
||||
if (ret < 0)
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
out_error:
|
||||
|
Loading…
Reference in New Issue
Block a user