@@ -453,11 +453,12 @@ static int ll_prepare_partial_page(const struct lu_env *env, struct cl_io *io,
return result;
}
-static int ll_tiny_write_begin(struct page *vmpage)
+static int ll_tiny_write_begin(struct page *vmpage,
+ struct address_space *mapping)
{
/* Page must be present, up to date, dirty, and not in writeback. */
if (!vmpage || !PageUptodate(vmpage) || !PageDirty(vmpage) ||
- PageWriteback(vmpage))
+ PageWriteback(vmpage) || vmpage->mapping != mapping)
return -ENODATA;
return 0;
@@ -483,7 +484,7 @@ static int ll_write_begin(struct file *file, struct address_space *mapping,
lcc = ll_cl_find(file);
if (!lcc) {
vmpage = grab_cache_page_nowait(mapping, index);
- result = ll_tiny_write_begin(vmpage);
+ result = ll_tiny_write_begin(vmpage, mapping);
goto out;
}
@@ -547,6 +548,15 @@ static int ll_write_begin(struct file *file, struct address_space *mapping,
}
}
+ /* page was truncated */
+ if (mapping != vmpage->mapping) {
+ CDEBUG(D_VFSTRACE, "page: %lu was truncated\n", index);
+ unlock_page(vmpage);
+ put_page(vmpage);
+ vmpage = NULL;
+ goto again;
+ }
+
page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE);
if (IS_ERR(page)) {
result = PTR_ERR(page);
@@ -899,7 +899,7 @@ void vvp_set_pagevec_dirty(struct pagevec *pvec)
ClearPageReclaim(pvec->pages[i]);
LASSERTF(page->mapping,
- "mapping must be set. page %p, page->private (cl_page) %p",
+ "mapping must be set. page %p, page->private (cl_page) %p\n",
page, (void *) page->private);
/* Rest of code derived from __set_page_dirty_nobuffers */