fix ceph_write_end()

don't zero on short copies; if the page was uptodate it's just plain
wrong, and if it wasn't we'll be better off just returning 0 and
buggering off.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro
2016-09-05 22:20:03 -04:00
parent c0cf3ef5e0
commit b9de313cf0

View File

@ -1276,25 +1276,27 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
struct page *page, void *fsdata) struct page *page, void *fsdata)
{ {
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
unsigned from = pos & (PAGE_SIZE - 1);
int check_cap = 0; int check_cap = 0;
dout("write_end file %p inode %p page %p %d~%d (%d)\n", file, dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
inode, page, (int)pos, (int)copied, (int)len); inode, page, (int)pos, (int)copied, (int)len);
/* zero the stale part of the page if we did a short copy */ /* zero the stale part of the page if we did a short copy */
if (copied < len) if (!PageUptodate(page)) {
zero_user_segment(page, from+copied, len); if (copied < len) {
copied = 0;
goto out;
}
SetPageUptodate(page);
}
/* did file size increase? */ /* did file size increase? */
if (pos+copied > i_size_read(inode)) if (pos+copied > i_size_read(inode))
check_cap = ceph_inode_set_size(inode, pos+copied); check_cap = ceph_inode_set_size(inode, pos+copied);
if (!PageUptodate(page))
SetPageUptodate(page);
set_page_dirty(page); set_page_dirty(page);
out:
unlock_page(page); unlock_page(page);
put_page(page); put_page(page);