f2fs: flush inode metadata when checkpoint is doing
[deliverable/linux.git] / fs / f2fs / checkpoint.c
index 02e0522beccfba8900636f2387d257fb7e31e5d1..5ddd15cd6c6cbdf4976e81cc9288069909e5cff0 100644 (file)
@@ -859,6 +859,34 @@ retry:
        goto retry;
 }
 
+int f2fs_sync_inode_meta(struct f2fs_sb_info *sbi)
+{
+       struct list_head *head = &sbi->inode_list[DIRTY_META];
+       struct inode *inode;
+       struct f2fs_inode_info *fi;
+       s64 total = get_pages(sbi, F2FS_DIRTY_IMETA);
+
+       while (total--) {
+               if (unlikely(f2fs_cp_error(sbi)))
+                       return -EIO;
+
+               spin_lock(&sbi->inode_lock[DIRTY_META]);
+               if (list_empty(head)) {
+                       spin_unlock(&sbi->inode_lock[DIRTY_META]);
+                       return 0;
+               }
+               fi = list_entry(head->next, struct f2fs_inode_info,
+                                                       gdirty_list);
+               inode = igrab(&fi->vfs_inode);
+               spin_unlock(&sbi->inode_lock[DIRTY_META]);
+               if (inode) {
+                       update_inode_page(inode);
+                       iput(inode);
+               }
+       };
+       return 0;
+}
+
 /*
  * Freeze all the FS-operations for checkpoint.
  */
@@ -885,6 +913,14 @@ retry_flush_dents:
                goto retry_flush_dents;
        }
 
+       if (get_pages(sbi, F2FS_DIRTY_IMETA)) {
+               f2fs_unlock_all(sbi);
+               err = f2fs_sync_inode_meta(sbi);
+               if (err)
+                       goto out;
+               goto retry_flush_dents;
+       }
+
        /*
         * POR: we should ensure that there are no dirty node pages
         * until finishing nat/sit flush.
This page took 0.027905 seconds and 5 git commands to generate.