]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/exofs/inode.c
exofs: simple fsync race fix
[karo-tx-linux.git] / fs / exofs / inode.c
index a7555238c41aaf942237b2aafb780c8605244812..fb9d380561037040b40052d24be3364210ebf934 100644 (file)
@@ -350,8 +350,10 @@ static int readpage_strip(void *data, struct page *page)
 
                if (!pcol->read_4_write)
                        unlock_page(page);
-               EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page,"
-                            " splitting\n", inode->i_ino, page->index);
+               EXOFS_DBGMSG("readpage_strip(0x%lx) empty page len=%zx "
+                            "read_4_write=%d index=0x%lx end_index=0x%lx "
+                            "splitting\n", inode->i_ino, len,
+                            pcol->read_4_write, page->index, end_index);
 
                return read_exec(pcol);
        }
@@ -722,11 +724,28 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
 
         /* read modify write */
        if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) {
+               loff_t i_size = i_size_read(mapping->host);
+               pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
+               size_t rlen;
+
+               if (page->index < end_index)
+                       rlen = PAGE_CACHE_SIZE;
+               else if (page->index == end_index)
+                       rlen = i_size & ~PAGE_CACHE_MASK;
+               else
+                       rlen = 0;
+
+               if (!rlen) {
+                       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_filler failed\n");
+                       EXOFS_DBGMSG("__readpage failed\n");
                }
        }
 out:
@@ -1271,7 +1290,8 @@ out:
 
 int exofs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
-       return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
+       /* FIXME: fix fsync and use wbc->sync_mode == WB_SYNC_ALL */
+       return exofs_update_inode(inode, 1);
 }
 
 /*