]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/f2fs/data.c
Merge remote-tracking branch 'regulator/fix/doc' into regulator-linus
[karo-tx-linux.git] / fs / f2fs / data.c
index 8e8b14d714fc8c024d763a78da0385d4485f6a96..91ff93b0b0f403300f951f0d26fa2698ac535c9a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/f2fs_fs.h>
 #include <linux/buffer_head.h>
 #include <linux/mpage.h>
+#include <linux/aio.h>
 #include <linux/writeback.h>
 #include <linux/backing-dev.h>
 #include <linux/blkdev.h>
@@ -55,6 +56,8 @@ int reserve_new_block(struct dnode_of_data *dn)
        if (!inc_valid_block_count(sbi, dn->inode, 1))
                return -ENOSPC;
 
+       trace_f2fs_reserve_new_block(dn->inode, dn->nid, dn->ofs_in_node);
+
        __set_data_blkaddr(dn, NEW_ADDR);
        dn->data_blkaddr = NEW_ADDR;
        sync_inode_page(dn);
@@ -170,7 +173,7 @@ end_update:
        return;
 }
 
-struct page *find_data_page(struct inode *inode, pgoff_t index)
+struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync)
 {
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        struct address_space *mapping = inode->i_mapping;
@@ -205,11 +208,14 @@ struct page *find_data_page(struct inode *inode, pgoff_t index)
                return page;
        }
 
-       err = f2fs_readpage(sbi, page, dn.data_blkaddr, READ_SYNC);
-       wait_on_page_locked(page);
-       if (!PageUptodate(page)) {
-               f2fs_put_page(page, 0);
-               return ERR_PTR(-EIO);
+       err = f2fs_readpage(sbi, page, dn.data_blkaddr,
+                                       sync ? READ_SYNC : READA);
+       if (sync) {
+               wait_on_page_locked(page);
+               if (!PageUptodate(page)) {
+                       f2fs_put_page(page, 0);
+                       return ERR_PTR(-EIO);
+               }
        }
        return page;
 }
@@ -235,7 +241,7 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
 
        if (dn.data_blkaddr == NULL_ADDR)
                return ERR_PTR(-ENOENT);
-
+repeat:
        page = grab_cache_page(mapping, index);
        if (!page)
                return ERR_PTR(-ENOMEM);
@@ -255,6 +261,10 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index)
                f2fs_put_page(page, 1);
                return ERR_PTR(-EIO);
        }
+       if (page->mapping != mapping) {
+               f2fs_put_page(page, 1);
+               goto repeat;
+       }
        return page;
 }
 
@@ -286,7 +296,7 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index,
                }
        }
        f2fs_put_dnode(&dn);
-
+repeat:
        page = grab_cache_page(mapping, index);
        if (!page)
                return ERR_PTR(-ENOMEM);
@@ -306,6 +316,10 @@ struct page *get_new_data_page(struct inode *inode, pgoff_t index,
                        f2fs_put_page(page, 1);
                        return ERR_PTR(-EIO);
                }
+               if (page->mapping != mapping) {
+                       f2fs_put_page(page, 1);
+                       goto repeat;
+               }
        }
 
        if (new_i_size &&
@@ -564,6 +578,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,
 {
        struct inode *inode = mapping->host;
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
+       bool locked = false;
        int ret;
        long excess_nrtw = 0, desired_nrtw;
 
@@ -577,10 +592,12 @@ static int f2fs_write_data_pages(struct address_space *mapping,
                wbc->nr_to_write = desired_nrtw;
        }
 
-       if (!S_ISDIR(inode->i_mode))
+       if (!S_ISDIR(inode->i_mode)) {
                mutex_lock(&sbi->writepages);
+               locked = true;
+       }
        ret = write_cache_pages(mapping, wbc, __f2fs_writepage, mapping);
-       if (!S_ISDIR(inode->i_mode))
+       if (locked)
                mutex_unlock(&sbi->writepages);
        f2fs_submit_bio(sbi, DATA, (wbc->sync_mode == WB_SYNC_ALL));
 
@@ -606,7 +623,7 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
        *fsdata = NULL;
 
        f2fs_balance_fs(sbi);
-
+repeat:
        page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page)
                return -ENOMEM;
@@ -651,6 +668,10 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
                        f2fs_put_page(page, 1);
                        return -EIO;
                }
+               if (page->mapping != mapping) {
+                       f2fs_put_page(page, 1);
+                       goto repeat;
+               }
        }
 out:
        SetPageUptodate(page);