fix ceph_write_end()
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 6 Sep 2016 02:20:03 +0000 (22:20 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 10 Dec 2016 19:24:45 +0000 (14:24 -0500)
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>
fs/ceph/addr.c

index ef3ebd780aff8bf8c9203ae366f3d4b688cd7af6..834be0943a263538bb12d8b49f76264d43d9163d 100644 (file)
@@ -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);