f2fs: fix missing cold bit during recovery
authorJaegeuk Kim <jaegeuk@kernel.org>
Wed, 24 Dec 2014 00:26:31 +0000 (16:26 -0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Sat, 10 Jan 2015 01:02:25 +0000 (17:02 -0800)
In do_recover_data, we find and update previous node pages after updating
its new block addresses.
After then, we call fill_node_footer without reset field, we erase its
cold bit so that this new cold node block is written to wrong log area.
This patch fixes not to miss its old flag.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/node.h
include/linux/f2fs_fs.h

index fa6f95968b425ec609f87615c855927f04f422cd..cac8a3d9acbdf0a53dd9071c95cb1cabe01e33cb 100644 (file)
@@ -212,11 +212,19 @@ static inline void fill_node_footer(struct page *page, nid_t nid,
                                nid_t ino, unsigned int ofs, bool reset)
 {
        struct f2fs_node *rn = F2FS_NODE(page);
+       unsigned int old_flag = 0;
+
        if (reset)
                memset(rn, 0, sizeof(*rn));
+       else
+               old_flag = le32_to_cpu(rn->footer.flag);
+
        rn->footer.nid = cpu_to_le32(nid);
        rn->footer.ino = cpu_to_le32(ino);
-       rn->footer.flag = cpu_to_le32(ofs << OFFSET_BIT_SHIFT);
+
+       /* should remain old flag bits such as COLD_BIT_SHIFT */
+       rn->footer.flag = cpu_to_le32((ofs << OFFSET_BIT_SHIFT) |
+                                       (old_flag & OFFSET_BIT_MASK));
 }
 
 static inline void copy_node_footer(struct page *dst, struct page *src)
index 87f14e90e9848904da0cc326d17096f1ce6049f5..e993b0bc9abf424fa7ecc959b14b2caa26d1ece6 100644 (file)
@@ -224,6 +224,8 @@ enum {
        OFFSET_BIT_SHIFT
 };
 
+#define OFFSET_BIT_MASK                (0x07)  /* (0x01 << OFFSET_BIT_SHIFT) - 1 */
+
 struct node_footer {
        __le32 nid;             /* node id */
        __le32 ino;             /* inode nunmber */