]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
f2fs: recover directory operations by fsync
authorJaegeuk Kim <jaegeuk@kernel.org>
Thu, 28 Dec 2017 16:09:44 +0000 (08:09 -0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Wed, 3 Jan 2018 03:27:31 +0000 (19:27 -0800)
This fixes generic/342 which doesn't recover renamed file which was fsynced
before. It will be done via another fsync on newly created file.

Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/dir.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/namei.c
include/trace/events/f2fs.h

index 724304dc6143cbfec3d50de353dbfd6dc87e9983..f00b5ed8c01157e415450d6160b41880d23d5252 100644 (file)
@@ -713,6 +713,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
 
        f2fs_update_time(F2FS_I_SB(dir), REQ_TIME);
 
+       add_ino_entry(F2FS_I_SB(dir), dir->i_ino, TRANS_DIR_INO);
+
        if (f2fs_has_inline_dentry(dir))
                return f2fs_delete_inline_entry(dentry, page, dir, inode);
 
index df00affe1450b9dd5a7b9ae0e35ae7917ec57f40..46d3d89f3ac55631756ffa8e8f780cf40f782e72 100644 (file)
@@ -180,6 +180,7 @@ enum {
        ORPHAN_INO,             /* for orphan ino list */
        APPEND_INO,             /* for append ino list */
        UPDATE_INO,             /* for update ino list */
+       TRANS_DIR_INO,          /* for trasactions dir ino list */
        FLUSH_INO,              /* for multiple device flushing */
        MAX_INO_ENTRY,          /* max. list */
 };
@@ -924,6 +925,7 @@ enum cp_reason_type {
        CP_NODE_NEED_CP,
        CP_FASTBOOT_MODE,
        CP_SPEC_LOG_NUM,
+       CP_RECOVER_DIR,
 };
 
 enum iostat_type {
index 1db68f1bcd7757fd2a286da9ea206a882798e07b..322aab9d91b535e3047467005a9d735685acd12e 100644 (file)
@@ -165,6 +165,9 @@ static inline enum cp_reason_type need_do_checkpoint(struct inode *inode)
                cp_reason = CP_FASTBOOT_MODE;
        else if (sbi->active_logs == 2)
                cp_reason = CP_SPEC_LOG_NUM;
+       else if (need_dentry_mark(sbi, inode->i_ino) &&
+               exist_written_data(sbi, F2FS_I(inode)->i_pino, TRANS_DIR_INO))
+               cp_reason = CP_RECOVER_DIR;
 
        return cp_reason;
 }
index e3a0f4f658516f22172ac1f69e48902b338ab950..a885c6e659f81e8c8267ad3ee5556d9da7ba1612 100644 (file)
@@ -935,6 +935,7 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
                }
                f2fs_i_links_write(old_dir, false);
        }
+       add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
 
        f2fs_unlock_op(sbi);
 
@@ -1089,6 +1090,9 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
        }
        f2fs_mark_inode_dirty_sync(new_dir, false);
 
+       add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
+       add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
+
        f2fs_unlock_op(sbi);
 
        if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
index 8f8dd42fa57bd39c0a07cb15ece2249e8bb8928e..06c87f9f720c2ee9775eb707784c375bdcea4fd5 100644 (file)
@@ -147,7 +147,8 @@ TRACE_DEFINE_ENUM(CP_TRIMMED);
                { CP_NO_SPC_ROLL,       "no space roll forward" },      \
                { CP_NODE_NEED_CP,      "node needs cp" },              \
                { CP_FASTBOOT_MODE,     "fastboot mode" },              \
-               { CP_SPEC_LOG_NUM,      "log type is 2" })
+               { CP_SPEC_LOG_NUM,      "log type is 2" },              \
+               { CP_RECOVER_DIR,       "dir needs recovery" })
 
 struct victim_sel_policy;
 struct f2fs_map_blocks;