Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / fs / f2fs / file.c
index a4cc1d6bdd848f8f402d02286ecbd140855223d2..60e7d5448a1d8b705d6a30fb0ea266e0989d3201 100644 (file)
@@ -76,7 +76,7 @@ static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
        trace_f2fs_vm_page_mkwrite(page, DATA);
 mapped:
        /* fill the page */
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
 out:
        sb_end_pagefault(inode->i_sb);
        return block_page_mkwrite_return(err);
@@ -84,6 +84,7 @@ out:
 
 static const struct vm_operations_struct f2fs_file_vm_ops = {
        .fault          = filemap_fault,
+       .map_pages      = filemap_map_pages,
        .page_mkwrite   = f2fs_vm_page_mkwrite,
        .remap_pages    = generic_file_remap_pages,
 };
@@ -111,6 +112,7 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)
 int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 {
        struct inode *inode = file->f_mapping->host;
+       struct f2fs_inode_info *fi = F2FS_I(inode);
        struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
        int ret = 0;
        bool need_cp = false;
@@ -133,7 +135,7 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        /* guarantee free sections for fsync */
        f2fs_balance_fs(sbi);
 
-       mutex_lock(&inode->i_mutex);
+       down_read(&fi->i_sem);
 
        /*
         * Both of fdatasync() and fsync() are able to be recovered from
@@ -150,25 +152,33 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        else if (F2FS_I(inode)->xattr_ver == cur_cp_version(F2FS_CKPT(sbi)))
                need_cp = true;
 
+       up_read(&fi->i_sem);
+
        if (need_cp) {
                nid_t pino;
 
-               F2FS_I(inode)->xattr_ver = 0;
-
                /* all the dirty node pages should be flushed for POR */
                ret = f2fs_sync_fs(inode->i_sb, 1);
+
+               down_write(&fi->i_sem);
+               F2FS_I(inode)->xattr_ver = 0;
                if (file_wrong_pino(inode) && inode->i_nlink == 1 &&
                                        get_parent_ino(inode, &pino)) {
                        F2FS_I(inode)->i_pino = pino;
                        file_got_pino(inode);
+                       up_write(&fi->i_sem);
                        mark_inode_dirty_sync(inode);
                        ret = f2fs_write_inode(inode, NULL);
                        if (ret)
                                goto out;
+               } else {
+                       up_write(&fi->i_sem);
                }
        } else {
                /* if there is no written node page, write its inode page */
                while (!sync_node_pages(sbi, inode->i_ino, &wbc)) {
+                       if (fsync_mark_done(sbi, inode->i_ino))
+                               goto out;
                        mark_inode_dirty_sync(inode);
                        ret = f2fs_write_inode(inode, NULL);
                        if (ret)
@@ -177,10 +187,9 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
                ret = wait_on_node_pages_writeback(sbi, inode->i_ino);
                if (ret)
                        goto out;
-               ret = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+               ret = f2fs_issue_flush(F2FS_SB(inode->i_sb));
        }
 out:
-       mutex_unlock(&inode->i_mutex);
        trace_f2fs_sync_file_exit(inode, need_cp, datasync, ret);
        return ret;
 }
@@ -245,7 +254,7 @@ static void truncate_partial_data_page(struct inode *inode, u64 from)
                f2fs_put_page(page, 1);
                return;
        }
-       wait_on_page_writeback(page);
+       f2fs_wait_on_page_writeback(page, DATA);
        zero_user(page, offset, PAGE_CACHE_SIZE - offset);
        set_page_dirty(page);
        f2fs_put_page(page, 1);
@@ -422,7 +431,7 @@ static void fill_zero(struct inode *inode, pgoff_t index,
        f2fs_unlock_op(sbi);
 
        if (!IS_ERR(page)) {
-               wait_on_page_writeback(page);
+               f2fs_wait_on_page_writeback(page, DATA);
                zero_user(page, start, len);
                set_page_dirty(page);
                f2fs_put_page(page, 1);