Commit e89061de authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] async write errors: fix spurious fs truncate errors

From: Oliver Xymoron <oxymoron@waste.org>

Currently, a writepage() which detects that it is writing outside i_size (due
to concurrent truncate) will abandon the write, returning -EIO.

The return value will bogusly cause an error to be recorded in the
address_space.  So convert all those writepage() instances to return zero in
this case.
parent fcad2b42
......@@ -2610,7 +2610,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
*/
block_invalidatepage(page, 0);
unlock_page(page);
return -EIO;
return 0; /* don't care */
}
/*
......
......@@ -500,12 +500,19 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
write_data = kmap(page);
write_data += from;
if((to > PAGE_CACHE_SIZE) || (from > to) || (offset > mapping->host->i_size)) {
if((to > PAGE_CACHE_SIZE) || (from > to)) {
kunmap(page);
FreeXid(xid);
return -EIO;
}
/* racing with truncate? */
if(offset > mapping->host->i_size) {
kunmap(page);
FreeXid(xid);
return 0; /* don't care */
}
/* check to make sure that we are not extending the file */
if(mapping->host->i_size - offset < (loff_t)to)
to = (unsigned)(mapping->host->i_size - offset);
......
......@@ -242,7 +242,7 @@ nfs_writepage(struct page *page, struct writeback_control *wbc)
offset = i_size & (PAGE_CACHE_SIZE-1);
/* OK, are we completely out? */
err = -EIO;
err = 0; /* potential race with truncate - ignore */
if (page->index >= end_index+1 || !offset)
goto out;
do_it:
......
......@@ -811,8 +811,8 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
if (unlikely(page->index >= (vi->i_size + PAGE_CACHE_SIZE - 1) >>
PAGE_CACHE_SHIFT)) {
unlock_page(page);
ntfs_debug("Write outside i_size. Returning i/o error.");
return -EIO;
ntfs_debug("Write outside i_size - truncated?");
return 0;
}
ni = NTFS_I(vi);
......
......@@ -2048,8 +2048,8 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1) ;
/* no file contents in this page */
if (page->index >= end_index + 1 || !last_offset) {
error = -EIO ;
goto fail ;
error = 0 ;
goto done ;
}
kaddr = kmap_atomic(page, KM_USER0);
memset(kaddr + last_offset, 0, PAGE_CACHE_SIZE-last_offset) ;
......
......@@ -193,7 +193,7 @@ smb_writepage(struct page *page, struct writeback_control *wbc)
offset = inode->i_size & (PAGE_CACHE_SIZE-1);
/* OK, are we completely out? */
if (page->index >= end_index+1 || !offset)
return -EIO;
return 0; /* truncated - don't care */
do_it:
page_cache_get(page);
err = smb_writepage_sync(inode, page, 0, offset);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment