diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 36265d42ccec8fa0ca3ef9dfa9f2664650075008..fb897c043753eceee589576b2a7ccf447d99600a 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -12,6 +12,13 @@ tbd  Sun Microsystems, Inc.
        * RHEL 4 and RHEL 5/SLES 10 clients behaves differently on 'cd' to a
         removed cwd "./" (refer to Bugzilla 14399).
 
+Severity   : normal
+Bugzilla   : 15443
+Description: wait until IO finished before start new when do lock cancel.
+Details    : VM protocol want old IO finished before start new, in this case
+             need wait until PG_writeback is cleared until check dirty flag and
+             call writepages in lock cancel callback.
+
 Severity   : enhancement
 Bugzilla   : 14929
 Description: using special macro for print time and cleanup in includes.
diff --git a/lustre/llite/file.c b/lustre/llite/file.c
index 80ac03b90158a434b6f7af1bc3bc204f0b10ea67..32360dc1e655973f14d46b7a28cfbb018d67cfcd 100644
--- a/lustre/llite/file.c
+++ b/lustre/llite/file.c
@@ -840,12 +840,13 @@ void ll_pgcache_remove_extent(struct inode *inode, struct lov_stripe_md *lsm,
 
                 cond_resched();
 
-                page = find_get_page(mapping, i);
+                page = find_lock_page(mapping, i);
                 if (page == NULL)
                         continue;
                 LL_CDEBUG_PAGE(D_PAGE, page, "lock page idx %lu ext "LPU64"\n",
                                i, tmpex.l_extent.start);
-                lock_page(page);
+                if (!discard && PageWriteback(page))
+                        wait_on_page_writeback(page);
 
                 /* page->mapping to check with racing against teardown */
                 if (!discard && clear_page_dirty_for_io(page)) {
@@ -854,7 +855,7 @@ void ll_pgcache_remove_extent(struct inode *inode, struct lov_stripe_md *lsm,
                          * the lock that the failed writepage released */
                         lock_page(page);
                         wait_on_page_writeback(page);
-                        if (rc != 0) {
+                        if (rc < 0) {
                                 CERROR("writepage inode %lu(%p) of page %p "
                                        "failed: %d\n", inode->i_ino, inode,
                                        page, rc);