nfsd4: fix test_stateid error reply encoding
[firefly-linux-kernel-4.4.55.git] / fs / f2fs / checkpoint.c
index 2b6fc131e2ce44aceda047f83237a23b254cf590..b1de01da1a409b42ae5bc6aae4989c201c920639 100644 (file)
@@ -20,6 +20,7 @@
 #include "f2fs.h"
 #include "node.h"
 #include "segment.h"
+#include <trace/events/f2fs.h>
 
 static struct kmem_cache *orphan_entry_slab;
 static struct kmem_cache *inode_entry_slab;
@@ -57,13 +58,19 @@ repeat:
                cond_resched();
                goto repeat;
        }
-       if (f2fs_readpage(sbi, page, index, READ_SYNC)) {
+       if (PageUptodate(page))
+               goto out;
+
+       if (f2fs_readpage(sbi, page, index, READ_SYNC))
+               goto repeat;
+
+       lock_page(page);
+       if (page->mapping != mapping) {
                f2fs_put_page(page, 1);
                goto repeat;
        }
+out:
        mark_page_accessed(page);
-
-       /* We do not allow returning an errorneous page */
        return page;
 }
 
@@ -541,54 +548,44 @@ retry:
  */
 static void block_operations(struct f2fs_sb_info *sbi)
 {
-       int t;
        struct writeback_control wbc = {
                .sync_mode = WB_SYNC_ALL,
                .nr_to_write = LONG_MAX,
                .for_reclaim = 0,
        };
+       struct blk_plug plug;
 
-       /* Stop renaming operation */
-       mutex_lock_op(sbi, RENAME);
-       mutex_lock_op(sbi, DENTRY_OPS);
+       blk_start_plug(&plug);
 
-retry_dents:
-       /* write all the dirty dentry pages */
-       sync_dirty_dir_inodes(sbi);
+retry_flush_dents:
+       mutex_lock_all(sbi);
 
-       mutex_lock_op(sbi, DATA_WRITE);
+       /* write all the dirty dentry pages */
        if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
-               mutex_unlock_op(sbi, DATA_WRITE);
-               goto retry_dents;
+               mutex_unlock_all(sbi);
+               sync_dirty_dir_inodes(sbi);
+               goto retry_flush_dents;
        }
 
-       /* block all the operations */
-       for (t = DATA_NEW; t <= NODE_TRUNC; t++)
-               mutex_lock_op(sbi, t);
-
-       mutex_lock(&sbi->write_inode);
-
        /*
         * POR: we should ensure that there is no dirty node pages
         * until finishing nat/sit flush.
         */
-retry:
-       sync_node_pages(sbi, 0, &wbc);
-
-       mutex_lock_op(sbi, NODE_WRITE);
+retry_flush_nodes:
+       mutex_lock(&sbi->node_write);
 
        if (get_pages(sbi, F2FS_DIRTY_NODES)) {
-               mutex_unlock_op(sbi, NODE_WRITE);
-               goto retry;
+               mutex_unlock(&sbi->node_write);
+               sync_node_pages(sbi, 0, &wbc);
+               goto retry_flush_nodes;
        }
-       mutex_unlock(&sbi->write_inode);
+       blk_finish_plug(&plug);
 }
 
 static void unblock_operations(struct f2fs_sb_info *sbi)
 {
-       int t;
-       for (t = NODE_WRITE; t >= RENAME; t--)
-               mutex_unlock_op(sbi, t);
+       mutex_unlock(&sbi->node_write);
+       mutex_unlock_all(sbi);
 }
 
 static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
@@ -727,9 +724,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
        unsigned long long ckpt_ver;
 
+       trace_f2fs_write_checkpoint(sbi->sb, is_umount, "start block_ops");
+
        mutex_lock(&sbi->cp_mutex);
        block_operations(sbi);
 
+       trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops");
+
        f2fs_submit_bio(sbi, DATA, true);
        f2fs_submit_bio(sbi, NODE, true);
        f2fs_submit_bio(sbi, META, true);
@@ -746,13 +747,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
        flush_nat_entries(sbi);
        flush_sit_entries(sbi);
 
-       reset_victim_segmap(sbi);
-
        /* unlock all the fs_lock[] in do_checkpoint() */
        do_checkpoint(sbi, is_umount);
 
        unblock_operations(sbi);
        mutex_unlock(&sbi->cp_mutex);
+
+       trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish checkpoint");
 }
 
 void init_orphan_info(struct f2fs_sb_info *sbi)