Browse Source

f2fs: fix missing cold bit during recovery

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>
Jaegeuk Kim 10 năm trước cách đây
mục cha
commit
09eb483e89
2 tập tin đã thay đổi với 11 bổ sung1 xóa
  1. 9 1
      fs/f2fs/node.h
  2. 2 0
      include/linux/f2fs_fs.h

+ 9 - 1
fs/f2fs/node.h

@@ -212,11 +212,19 @@ static inline void fill_node_footer(struct page *page, nid_t nid,
 				nid_t ino, unsigned int ofs, bool reset)
 				nid_t ino, unsigned int ofs, bool reset)
 {
 {
 	struct f2fs_node *rn = F2FS_NODE(page);
 	struct f2fs_node *rn = F2FS_NODE(page);
+	unsigned int old_flag = 0;
+
 	if (reset)
 	if (reset)
 		memset(rn, 0, sizeof(*rn));
 		memset(rn, 0, sizeof(*rn));
+	else
+		old_flag = le32_to_cpu(rn->footer.flag);
+
 	rn->footer.nid = cpu_to_le32(nid);
 	rn->footer.nid = cpu_to_le32(nid);
 	rn->footer.ino = cpu_to_le32(ino);
 	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)
 static inline void copy_node_footer(struct page *dst, struct page *src)

+ 2 - 0
include/linux/f2fs_fs.h

@@ -224,6 +224,8 @@ enum {
 	OFFSET_BIT_SHIFT
 	OFFSET_BIT_SHIFT
 };
 };
 
 
+#define OFFSET_BIT_MASK		(0x07)	/* (0x01 << OFFSET_BIT_SHIFT) - 1 */
+
 struct node_footer {
 struct node_footer {
 	__le32 nid;		/* node id */
 	__le32 nid;		/* node id */
 	__le32 ino;		/* inode nunmber */
 	__le32 ino;		/* inode nunmber */