aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2015-12-02 21:33:21 -0800
committerGreg Wallace <greg@gregtwallace.com>2016-01-19 22:02:20 -0500
commit3b01e520de3ac9bf3d1745e2da43977590704ef0 (patch)
tree39b464af93f8d5e3ccb4b56709b213fce2d12d1f
parentee06528c0346041b3555dd337a80a022dce3cb88 (diff)
downloadandroid_external_f2fs-tools-3b01e520de3ac9bf3d1745e2da43977590704ef0.tar.gz
android_external_f2fs-tools-3b01e520de3ac9bf3d1745e2da43977590704ef0.tar.bz2
android_external_f2fs-tools-3b01e520de3ac9bf3d1745e2da43977590704ef0.zip
mkfs.f2fs: discard obsolete blocks to avoid roll-forward recovery
If there are many obsolete blocks written by previous usage, we can recover wrong blocks with them. So, mkfs should discard whole wrong information correctly by removing possible same checkpoint versions. Change-Id: Ic7a4d88e985e93056a225a586396a75f8dee2a69 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--mkfs/f2fs_format.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 212df60..d82ed64 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -783,6 +783,32 @@ static int f2fs_write_super_block(void)
return 0;
}
+static int discard_obsolete_dnode(struct f2fs_node *raw_node, u_int64_t offset)
+{
+ do {
+ if (offset < get_sb(main_blkaddr) ||
+ offset >= get_sb(main_blkaddr) + get_sb(block_count))
+ break;
+
+ if (dev_read_block(raw_node, offset)) {
+ MSG(1, "\tError: While traversing direct node!!!\n");
+ return -1;
+ }
+
+ if (le64_to_cpu(raw_node->footer.cp_ver) == 1)
+ raw_node->footer.cp_ver = 0;
+
+ DBG(1, "\tDiscard dnode, at offset 0x%08"PRIx64"\n", offset);
+ if (dev_write_block(raw_node, offset)) {
+ MSG(1, "\tError: While discarding direct node!!!\n");
+ return -1;
+ }
+ offset = le32_to_cpu(raw_node->footer.next_blkaddr);
+ } while (1);
+
+ return 0;
+}
+
static int f2fs_write_root_inode(void)
{
struct f2fs_node *raw_node = NULL;
@@ -844,20 +870,16 @@ static int f2fs_write_root_inode(void)
return -1;
}
- memset(raw_node, 0xff, sizeof(struct f2fs_node));
-
/* avoid power-off-recovery based on roll-forward policy */
main_area_node_seg_blk_offset = get_sb(main_blkaddr);
main_area_node_seg_blk_offset += config.cur_seg[CURSEG_WARM_NODE] *
config.blks_per_seg;
- main_area_node_seg_blk_offset *= blk_size_bytes;
- DBG(1, "\tWriting root inode (warm node), at offset 0x%08"PRIx64"\n", main_area_node_seg_blk_offset);
- if (dev_write(raw_node, main_area_node_seg_blk_offset, F2FS_BLKSIZE)) {
- MSG(1, "\tError: While writing the raw_node to disk!!!\n");
+ if (discard_obsolete_dnode(raw_node, main_area_node_seg_blk_offset)) {
free(raw_node);
return -1;
}
+
free(raw_node);
return 0;
}