- if (page->mapping == mapping) { /* truncate race? */
- wait_on_page_writeback(page);
- next = page->index + 1;
- if (page_mapped(page))
- clear_page_dirty(page);
- else
- invalidate_complete_page(mapping, page);
+ if (page->mapping != mapping) { /* truncate race? */
+ unlock_page(page);
+ continue;
+ }
+ wait_on_page_writeback(page);
+ next = page->index + 1;
+ while (page_mapped(page)) {
+ if (!did_full_unmap) {
+ /*
+ * Zap the rest of the file in one hit.
+ * FIXME: invalidate_inode_pages2()
+ * should take start/end offsets.
+ */
+ unmap_mapping_range(mapping,
+ page->index << PAGE_CACHE_SHIFT,
+ -1, 0);
+ did_full_unmap = 1;
+ } else {
+ /*
+ * Just zap this page
+ */
+ unmap_mapping_range(mapping,
+ page->index << PAGE_CACHE_SHIFT,
+ (page->index << PAGE_CACHE_SHIFT)+1,
+ 0);
+ }
+ }
+ was_dirty = test_clear_page_dirty(page);
+ if (!invalidate_complete_page(mapping, page)) {
+ if (was_dirty)
+ set_page_dirty(page);
+ ret = -EIO;