f2fs: fix fs corruption due to zero inode page
[GitHub/LineageOS/android_kernel_motorola_exynos9610.git] / fs / f2fs / inode.c
index 24bb8213d974b710b43f286b1089ccff7946a50e..0900814485c74d7247c115db984ba1a992b556e0 100644 (file)
@@ -316,7 +316,6 @@ retry:
                } else if (err != -ENOENT) {
                        f2fs_stop_checkpoint(sbi, false);
                }
-               f2fs_inode_synced(inode);
                return 0;
        }
        ret = update_inode(inode, node_page);
@@ -372,13 +371,6 @@ void f2fs_evict_inode(struct inode *inode)
        if (inode->i_nlink || is_bad_inode(inode))
                goto no_delete;
 
-#ifdef CONFIG_F2FS_FAULT_INJECTION
-       if (time_to_inject(sbi, FAULT_EVICT_INODE)) {
-               f2fs_show_injection_info(FAULT_EVICT_INODE);
-               goto no_delete;
-       }
-#endif
-
        remove_ino_entry(sbi, inode->i_ino, APPEND_INO);
        remove_ino_entry(sbi, inode->i_ino, UPDATE_INO);
 
@@ -389,6 +381,12 @@ retry:
        if (F2FS_HAS_BLOCKS(inode))
                err = f2fs_truncate(inode);
 
+#ifdef CONFIG_F2FS_FAULT_INJECTION
+       if (time_to_inject(sbi, FAULT_EVICT_INODE)) {
+               f2fs_show_injection_info(FAULT_EVICT_INODE);
+               err = -EIO;
+       }
+#endif
        if (!err) {
                f2fs_lock_op(sbi);
                err = remove_inode_page(inode);
@@ -411,7 +409,10 @@ no_delete:
        stat_dec_inline_dir(inode);
        stat_dec_inline_inode(inode);
 
-       invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino);
+       /* ino == 0, if f2fs_new_inode() was failed t*/
+       if (inode->i_ino)
+               invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino,
+                                                       inode->i_ino);
        if (xnid)
                invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid);
        if (inode->i_nlink) {
@@ -448,6 +449,7 @@ void handle_failed_inode(struct inode *inode)
         * in a panic when flushing dirty inodes in gdirty_list.
         */
        update_inode_page(inode);
+       f2fs_inode_synced(inode);
 
        /* don't make bad inode, since it becomes a regular file. */
        unlock_new_inode(inode);