return ERR_PTR(err);
 }
 
-static void del_fsync_inode(struct fsync_inode_entry *entry)
+static void del_fsync_inode(struct fsync_inode_entry *entry, int drop)
 {
+       if (drop) {
+               /* inode should not be recovered, drop it */
+               f2fs_inode_synced(entry->inode);
+       }
        iput(entry->inode);
        list_del(&entry->list);
        kmem_cache_free(fsync_entry_slab, entry);
        return err;
 }
 
-static void destroy_fsync_dnodes(struct list_head *head)
+static void destroy_fsync_dnodes(struct list_head *head, int drop)
 {
        struct fsync_inode_entry *entry, *tmp;
 
        list_for_each_entry_safe(entry, tmp, head, list)
-               del_fsync_inode(entry);
+               del_fsync_inode(entry, drop);
 }
 
 static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
 }
 
 static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
-                                               struct list_head *dir_list)
+               struct list_head *tmp_inode_list, struct list_head *dir_list)
 {
        struct curseg_info *curseg;
        struct page *page = NULL;
                }
 
                if (entry->blkaddr == blkaddr)
-                       del_fsync_inode(entry);
+                       list_move_tail(&entry->list, tmp_inode_list);
 next:
                /* check next segment */
                blkaddr = next_blkaddr_of_node(page);
 
 int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
 {
-       struct list_head inode_list;
+       struct list_head inode_list, tmp_inode_list;
        struct list_head dir_list;
        int err;
        int ret = 0;
        }
 
        INIT_LIST_HEAD(&inode_list);
+       INIT_LIST_HEAD(&tmp_inode_list);
        INIT_LIST_HEAD(&dir_list);
 
        /* prevent checkpoint */
        need_writecp = true;
 
        /* step #2: recover data */
-       err = recover_data(sbi, &inode_list, &dir_list);
+       err = recover_data(sbi, &inode_list, &tmp_inode_list, &dir_list);
        if (!err)
                f2fs_bug_on(sbi, !list_empty(&inode_list));
+       else {
+               /* restore s_flags to let iput() trash data */
+               sbi->sb->s_flags = s_flags;
+       }
 skip:
-       destroy_fsync_dnodes(&inode_list);
+       destroy_fsync_dnodes(&inode_list, err);
+       destroy_fsync_dnodes(&tmp_inode_list, err);
 
        /* truncate meta pages to be used by the recovery */
        truncate_inode_pages_range(META_MAPPING(sbi),
        if (err) {
                truncate_inode_pages_final(NODE_MAPPING(sbi));
                truncate_inode_pages_final(META_MAPPING(sbi));
+       } else {
+               clear_sbi_flag(sbi, SBI_POR_DOING);
        }
-
-       clear_sbi_flag(sbi, SBI_POR_DOING);
        mutex_unlock(&sbi->cp_mutex);
 
        /* let's drop all the directory inodes for clean checkpoint */
-       destroy_fsync_dnodes(&dir_list);
+       destroy_fsync_dnodes(&dir_list, err);
 
        if (need_writecp) {
                set_sbi_flag(sbi, SBI_IS_RECOVERED);
 
        }
 }
 
+static void f2fs_truncate_quota_inode_pages(struct super_block *sb)
+{
+       struct quota_info *dqopt = sb_dqopt(sb);
+       int type;
+
+       for (type = 0; type < MAXQUOTAS; type++) {
+               if (!dqopt->files[type])
+                       continue;
+               f2fs_inode_synced(dqopt->files[type]);
+       }
+}
+
+
 static int f2fs_get_projid(struct inode *inode, kprojid_t *projid)
 {
        *projid = F2FS_I(inode)->i_projid;
 
 free_meta:
 #ifdef CONFIG_QUOTA
+       f2fs_truncate_quota_inode_pages(sb);
        if (f2fs_sb_has_quota_ino(sb) && !f2fs_readonly(sb))
                f2fs_quota_off_umount(sbi->sb);
 #endif
-       f2fs_sync_inode_meta(sbi);
        /*
         * Some dirty meta pages can be produced by f2fs_recover_orphan_inodes()
         * failed by EIO. Then, iput(node_inode) can trigger balance_fs_bg()