summary refs log tree commit diff
path: root/fs/ceph
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-09-05 22:20:03 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-12-10 14:24:45 -0500
commitb9de313cf05fe08fa59efaf19756ec5283af672a (patch)
treec57749e0221aff9d8fb07786d7821f2ce80fcdfa /fs/ceph
parentc0cf3ef5e0f47e385920450b245d22bead93e7ad (diff)
downloadlinux-b9de313cf05fe08fa59efaf19756ec5283af672a.tar.gz
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>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/addr.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index ef3ebd780aff..834be0943a26 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1276,25 +1276,27 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
 			  struct page *page, void *fsdata)
 {
 	struct inode *inode = file_inode(file);
-	unsigned from = pos & (PAGE_SIZE - 1);
 	int check_cap = 0;
 
 	dout("write_end file %p inode %p page %p %d~%d (%d)\n", file,
 	     inode, page, (int)pos, (int)copied, (int)len);
 
 	/* zero the stale part of the page if we did a short copy */
-	if (copied < len)
-		zero_user_segment(page, from+copied, len);
+	if (!PageUptodate(page)) {
+		if (copied < len) {
+			copied = 0;
+			goto out;
+		}
+		SetPageUptodate(page);
+	}
 
 	/* did file size increase? */
 	if (pos+copied > i_size_read(inode))
 		check_cap = ceph_inode_set_size(inode, pos+copied);
 
-	if (!PageUptodate(page))
-		SetPageUptodate(page);
-
 	set_page_dirty(page);
 
+out:
 	unlock_page(page);
 	put_page(page);