aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-05-31 01:13:38 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-09 09:34:14 -0400
commitd2ccddf042c403b146159beea438c6bfc4a445e2 (patch)
treee38f5faeccb73cacd442e899328ae44b75f15559 /fs/nfs/write.c
parentc04871e6345e4c6dfda564e302d7fd8c66420fd5 (diff)
NFS: Flesh out nfs_invalidate_page()
In the case of a call to truncate_inode_pages(), we should really try to cancel any pending writes on the page. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index a515ec714bb6..e03abbd8302e 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -579,6 +579,17 @@ static int nfs_wait_on_requests(struct inode *inode, unsigned long idx_start, un
579 return ret; 579 return ret;
580} 580}
581 581
582static void nfs_cancel_requests(struct list_head *head)
583{
584 struct nfs_page *req;
585 while(!list_empty(head)) {
586 req = nfs_list_entry(head->next);
587 nfs_list_remove_request(req);
588 nfs_inode_remove_request(req);
589 nfs_clear_page_writeback(req);
590 }
591}
592
582/* 593/*
583 * nfs_scan_dirty - Scan an inode for dirty requests 594 * nfs_scan_dirty - Scan an inode for dirty requests
584 * @inode: NFS inode to scan 595 * @inode: NFS inode to scan
@@ -623,7 +634,7 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_st
623 int res = 0; 634 int res = 0;
624 635
625 if (nfsi->ncommit != 0) { 636 if (nfsi->ncommit != 0) {
626 res = nfs_scan_list(&nfsi->commit, dst, idx_start, npages); 637 res = nfs_scan_list(nfsi, &nfsi->commit, dst, idx_start, npages);
627 nfsi->ncommit -= res; 638 nfsi->ncommit -= res;
628 if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit)) 639 if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit))
629 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n"); 640 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n");
@@ -1491,15 +1502,25 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start,
1491 pages = nfs_scan_dirty(inode, &head, idx_start, npages); 1502 pages = nfs_scan_dirty(inode, &head, idx_start, npages);
1492 if (pages != 0) { 1503 if (pages != 0) {
1493 spin_unlock(&nfsi->req_lock); 1504 spin_unlock(&nfsi->req_lock);
1494 ret = nfs_flush_list(inode, &head, pages, how); 1505 if (how & FLUSH_INVALIDATE)
1506 nfs_cancel_requests(&head);
1507 else
1508 ret = nfs_flush_list(inode, &head, pages, how);
1495 spin_lock(&nfsi->req_lock); 1509 spin_lock(&nfsi->req_lock);
1496 continue; 1510 continue;
1497 } 1511 }
1498 if (nocommit) 1512 if (nocommit)
1499 break; 1513 break;
1500 pages = nfs_scan_commit(inode, &head, 0, 0); 1514 pages = nfs_scan_commit(inode, &head, idx_start, npages);
1501 if (pages == 0) 1515 if (pages == 0)
1502 break; 1516 break;
1517 if (how & FLUSH_INVALIDATE) {
1518 spin_unlock(&nfsi->req_lock);
1519 nfs_cancel_requests(&head);
1520 spin_lock(&nfsi->req_lock);
1521 continue;
1522 }
1523 pages += nfs_scan_commit(inode, &head, 0, 0);
1503 spin_unlock(&nfsi->req_lock); 1524 spin_unlock(&nfsi->req_lock);
1504 ret = nfs_commit_list(inode, &head, how); 1525 ret = nfs_commit_list(inode, &head, how);
1505 spin_lock(&nfsi->req_lock); 1526 spin_lock(&nfsi->req_lock);