]> git.karo-electronics.de Git - linux-beck.git/commitdiff
exofs: don't mess with simple_write_{begin,end}
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 30 Aug 2016 02:04:51 +0000 (22:04 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 10 Dec 2016 19:25:19 +0000 (14:25 -0500)
... and don't zero anything on short copy; just unlock
and return 0 if that has happened on non-uptodate page.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/exofs/inode.c

index d8072bc074a44f74c09c47c2905eb0d1c7ac87dc..0ac62811b34118ab4889d4ee8807706818efadff 100644 (file)
@@ -870,46 +870,31 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
 
        page = *pagep;
        if (page == NULL) {
-               ret = simple_write_begin(file, mapping, pos, len, flags, pagep,
-                                        fsdata);
-               if (ret) {
-                       EXOFS_DBGMSG("simple_write_begin failed\n");
-                       goto out;
+               page = grab_cache_page_write_begin(mapping, pos >> PAGE_SHIFT,
+                                                  flags);
+               if (!page) {
+                       EXOFS_DBGMSG("grab_cache_page_write_begin failed\n");
+                       return -ENOMEM;
                }
-
-               page = *pagep;
+               *pagep = page;
        }
 
         /* read modify write */
        if (!PageUptodate(page) && (len != PAGE_SIZE)) {
                loff_t i_size = i_size_read(mapping->host);
                pgoff_t end_index = i_size >> PAGE_SHIFT;
-               size_t rlen;
 
-               if (page->index < end_index)
-                       rlen = PAGE_SIZE;
-               else if (page->index == end_index)
-                       rlen = i_size & ~PAGE_MASK;
-               else
-                       rlen = 0;
-
-               if (!rlen) {
+               if (page->index > end_index) {
                        clear_highpage(page);
                        SetPageUptodate(page);
-                       goto out;
-               }
-
-               ret = _readpage(page, true);
-               if (ret) {
-                       /*SetPageError was done by _readpage. Is it ok?*/
-                       unlock_page(page);
-                       EXOFS_DBGMSG("__readpage failed\n");
+               } else {
+                       ret = _readpage(page, true);
+                       if (ret) {
+                               unlock_page(page);
+                               EXOFS_DBGMSG("__readpage failed\n");
+                       }
                }
        }
-out:
-       if (unlikely(ret))
-               _write_failed(mapping->host, pos + len);
-
        return ret;
 }
 
@@ -929,18 +914,25 @@ static int exofs_write_end(struct file *file, struct address_space *mapping,
                        struct page *page, void *fsdata)
 {
        struct inode *inode = mapping->host;
-       /* According to comment in simple_write_end i_mutex is held */
-       loff_t i_size = inode->i_size;
-       int ret;
-
-       ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata);
-       if (unlikely(ret))
-               _write_failed(inode, pos + len);
+       loff_t last_pos = pos + copied;
 
-       /* TODO: once simple_write_end marks inode dirty remove */
-       if (i_size != inode->i_size)
+       if (!PageUptodate(page)) {
+               if (copied < len) {
+                       _write_failed(inode, pos + len);
+                       copied = 0;
+                       goto out;
+               }
+               SetPageUptodate(page);
+       }
+       if (last_pos > inode->i_size) {
+               i_size_write(inode, last_pos);
                mark_inode_dirty(inode);
-       return ret;
+       }
+       set_page_dirty(page);
+out:
+       unlock_page(page);
+       put_page(page);
+       return copied;
 }
 
 static int exofs_releasepage(struct page *page, gfp_t gfp)