Browse Source

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>
Al Viro 9 years ago
parent
commit
b9de313cf0
1 changed files with 8 additions and 6 deletions
  1. 8 6
      fs/ceph/addr.c

+ 8 - 6
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 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)
-		zero_user_segment(page, from+copied, len);
+	if (!PageUptodate(page)) {
+		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);