From 88bd02c9472a166b706284a34a84f1243322d782 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 15 Sep 2014 14:50:48 -0700 Subject: f2fs: fix conditions to remain recovery information in f2fs_sync_file This patch revisited whole the recovery information during the f2fs_sync_file. In this patch, there are three information to make a decision. a) IS_CHECKPOINTED, /* is it checkpointed before? */ b) HAS_FSYNCED_INODE, /* is the inode fsynced before? */ c) HAS_LAST_FSYNC, /* has the latest node fsync mark? */ And, the scenarios for our rule are based on: [Term] F: fsync_mark, D: dentry_mark 1. inode(x) | CP | inode(x) | dnode(F) 2. inode(x) | CP | inode(F) | dnode(F) 3. inode(x) | CP | dnode(F) | inode(x) | inode(F) 4. inode(x) | CP | dnode(F) | inode(F) 5. CP | inode(x) | dnode(F) | inode(DF) 6. CP | inode(DF) | dnode(F) 7. CP | dnode(F) | inode(DF) 8. CP | dnode(F) | inode(x) | inode(DF) For example, #3, the three conditions should be changed as follows. inode(x) | CP | dnode(F) | inode(x) | inode(F) a) x o o o o b) x x x x o c) x o o x o If f2fs_sync_file stops ------^, it should write inode(F) --------------^ So, the need_inode_block_update should return true, since c) get_nat_flag(e, HAS_LAST_FSYNC), is false. For example, #8, CP | alloc | dnode(F) | inode(x) | inode(DF) a) o x x x x b) x x x o c) o o x o If f2fs_sync_file stops -------^, it should write inode(DF) --------------^ Note that, the roll-forward policy should follow this rule, which means, if there are any missing blocks, we doesn't need to recover that inode. Signed-off-by: Huang Ying Signed-off-by: Jaegeuk Kim --- fs/f2fs/node.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'fs/f2fs/node.h') diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 3043778d805b..b8ba63c43b99 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -41,7 +41,8 @@ struct node_info { enum { IS_CHECKPOINTED, /* is it checkpointed before? */ - HAS_FSYNC_MARK, /* has the latest node fsync mark? */ + HAS_FSYNCED_INODE, /* is the inode fsynced before? */ + HAS_LAST_FSYNC, /* has the latest node fsync mark? */ }; struct nat_entry { @@ -60,15 +61,9 @@ struct nat_entry { #define nat_set_version(nat, v) (nat->ni.version = v) #define __set_nat_cache_dirty(nm_i, ne) \ - do { \ - set_nat_flag(ne, IS_CHECKPOINTED, false); \ - list_move_tail(&ne->list, &nm_i->dirty_nat_entries); \ - } while (0) + list_move_tail(&ne->list, &nm_i->dirty_nat_entries); #define __clear_nat_cache_dirty(nm_i, ne) \ - do { \ - set_nat_flag(ne, IS_CHECKPOINTED, true); \ - list_move_tail(&ne->list, &nm_i->nat_entries); \ - } while (0) + list_move_tail(&ne->list, &nm_i->nat_entries); #define inc_node_version(version) (++version) static inline void set_nat_flag(struct nat_entry *ne, @@ -87,6 +82,14 @@ static inline bool get_nat_flag(struct nat_entry *ne, unsigned int type) return ne->flag & mask; } +static inline void nat_reset_flag(struct nat_entry *ne) +{ + /* these states can be set only after checkpoint was done */ + set_nat_flag(ne, IS_CHECKPOINTED, true); + set_nat_flag(ne, HAS_FSYNCED_INODE, false); + set_nat_flag(ne, HAS_LAST_FSYNC, true); +} + static inline void node_info_from_raw_nat(struct node_info *ni, struct f2fs_nat_entry *raw_ne) { -- cgit v1.2.3