aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-04-27 18:33:54 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-04-27 18:33:54 -0400
commitba8b06e67ed7a560b0e7c80091bcadda4f4727a5 (patch)
treecd737661ffb38a614697b1e055d68e7b41a7e982 /fs
parent71d0a6112a363e703e383ae5b12c492485c39701 (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/write.c19
1 files changed, 4 insertions, 15 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index ccde2aeb3fec..3aea3ca98ab7 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1472,6 +1472,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
1472 1472
1473 BUG_ON(!PageLocked(page)); 1473 BUG_ON(!PageLocked(page));
1474 for (;;) { 1474 for (;;) {
1475 wait_on_page_writeback(page);
1475 req = nfs_page_find_request(page); 1476 req = nfs_page_find_request(page);
1476 if (req == NULL) 1477 if (req == NULL)
1477 break; 1478 break;
@@ -1506,30 +1507,18 @@ int nfs_wb_page(struct inode *inode, struct page *page)
1506 .range_start = range_start, 1507 .range_start = range_start,
1507 .range_end = range_end, 1508 .range_end = range_end,
1508 }; 1509 };
1509 struct nfs_page *req;
1510 int need_commit;
1511 int ret; 1510 int ret;
1512 1511
1513 while(PagePrivate(page)) { 1512 while(PagePrivate(page)) {
1513 wait_on_page_writeback(page);
1514 if (clear_page_dirty_for_io(page)) { 1514 if (clear_page_dirty_for_io(page)) {
1515 ret = nfs_writepage_locked(page, &wbc); 1515 ret = nfs_writepage_locked(page, &wbc);
1516 if (ret < 0) 1516 if (ret < 0)
1517 goto out_error; 1517 goto out_error;
1518 } 1518 }
1519 req = nfs_find_and_lock_request(page); 1519 ret = sync_inode(inode, &wbc);
1520 if (!req) 1520 if (ret < 0)
1521 break;
1522 if (IS_ERR(req)) {
1523 ret = PTR_ERR(req);
1524 goto out_error; 1521 goto out_error;
1525 }
1526 need_commit = test_bit(PG_CLEAN, &req->wb_flags);
1527 nfs_clear_page_tag_locked(req);
1528 if (need_commit) {
1529 ret = nfs_commit_inode(inode, FLUSH_SYNC);
1530 if (ret < 0)
1531 goto out_error;
1532 }
1533 } 1522 }
1534 return 0; 1523 return 0;
1535out_error: 1524out_error: