f2fs: checkpoint disabling
[sfrench/cifs-2.6.git] / fs / f2fs / inode.c
index 740988bc250de206c30c66d426d4f1f0e40dda90..4ee9d6c4b71916afab0200297400ed44701d1011 100644 (file)
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * fs/f2fs/inode.c
  *
  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
  */
 #include <linux/fs.h>
 #include <linux/f2fs_fs.h>
@@ -68,14 +65,16 @@ static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
        }
 }
 
-static bool __written_first_block(struct f2fs_sb_info *sbi,
+static int __written_first_block(struct f2fs_sb_info *sbi,
                                        struct f2fs_inode *ri)
 {
        block_t addr = le32_to_cpu(ri->i_addr[offset_in_addr(ri)]);
 
-       if (is_valid_data_blkaddr(sbi, addr))
-               return true;
-       return false;
+       if (!__is_valid_data_blkaddr(addr))
+               return 1;
+       if (!f2fs_is_valid_blkaddr(sbi, addr, DATA_GENERIC))
+               return -EFAULT;
+       return 0;
 }
 
 static void __set_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
@@ -265,6 +264,26 @@ static bool sanity_check_inode(struct inode *inode, struct page *node_page)
                        return false;
                }
        }
+
+       if (f2fs_has_inline_data(inode) &&
+                       (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode))) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: inode (ino=%lx, mode=%u) should not have "
+                       "inline_data, run fsck to fix",
+                       __func__, inode->i_ino, inode->i_mode);
+               return false;
+       }
+
+       if (f2fs_has_inline_dentry(inode) && !S_ISDIR(inode->i_mode)) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "%s: inode (ino=%lx, mode=%u) should not have "
+                       "inline_dentry, run fsck to fix",
+                       __func__, inode->i_ino, inode->i_mode);
+               return false;
+       }
+
        return true;
 }
 
@@ -275,6 +294,7 @@ static int do_read_inode(struct inode *inode)
        struct page *node_page;
        struct f2fs_inode *ri;
        projid_t i_projid;
+       int err;
 
        /* Check if ino is within scope */
        if (f2fs_check_nid_range(sbi, inode->i_ino))
@@ -348,8 +368,15 @@ static int do_read_inode(struct inode *inode)
        /* get rdev by using inline_info */
        __get_inode_rdev(inode, ri);
 
-       if (__written_first_block(sbi, ri))
-               set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+       if (S_ISREG(inode->i_mode)) {
+               err = __written_first_block(sbi, ri);
+               if (err < 0) {
+                       f2fs_put_page(node_page, 1);
+                       return err;
+               }
+               if (!err)
+                       set_inode_flag(inode, FI_FIRST_BLOCK_WRITTEN);
+       }
 
        if (!f2fs_need_inode_block_update(sbi, inode->i_ino))
                fi->last_disk_size = inode->i_size;
@@ -580,6 +607,9 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
        if (!is_inode_flag_set(inode, FI_DIRTY_INODE))
                return 0;
 
+       if (f2fs_is_checkpoint_ready(sbi))
+               return -ENOSPC;
+
        /*
         * We need to balance fs here to prevent from producing dirty node pages
         * during the urgent cleaning time when runing out of free sections.
@@ -631,12 +661,11 @@ 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 = f2fs_remove_inode_page(inode);
@@ -662,7 +691,8 @@ no_delete:
        stat_dec_inline_dir(inode);
        stat_dec_inline_inode(inode);
 
-       if (likely(!is_set_ckpt_flags(sbi, CP_ERROR_FLAG)))
+       if (likely(!is_set_ckpt_flags(sbi, CP_ERROR_FLAG) &&
+                               !is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
                f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE));
        else
                f2fs_inode_synced(inode);
@@ -699,6 +729,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct node_info ni;
+       int err;
 
        /*
         * clear nlink of inode in order to release resource of inode
@@ -721,10 +752,16 @@ void f2fs_handle_failed_inode(struct inode *inode)
         * so we can prevent losing this orphan when encoutering checkpoint
         * and following suddenly power-off.
         */
-       f2fs_get_node_info(sbi, inode->i_ino, &ni);
+       err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
+       if (err) {
+               set_sbi_flag(sbi, SBI_NEED_FSCK);
+               f2fs_msg(sbi->sb, KERN_WARNING,
+                       "May loss orphan inode, run fsck to fix.");
+               goto out;
+       }
 
        if (ni.blk_addr != NULL_ADDR) {
-               int err = f2fs_acquire_orphan_inode(sbi);
+               err = f2fs_acquire_orphan_inode(sbi);
                if (err) {
                        set_sbi_flag(sbi, SBI_NEED_FSCK);
                        f2fs_msg(sbi->sb, KERN_WARNING,
@@ -737,6 +774,7 @@ void f2fs_handle_failed_inode(struct inode *inode)
                set_inode_flag(inode, FI_FREE_NID);
        }
 
+out:
        f2fs_unlock_op(sbi);
 
        /* iput will drop the inode object */