diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-12-02 21:33:21 -0800 |
---|---|---|
committer | Greg Wallace <greg@gregtwallace.com> | 2016-01-19 22:02:20 -0500 |
commit | 3b01e520de3ac9bf3d1745e2da43977590704ef0 (patch) | |
tree | 39b464af93f8d5e3ccb4b56709b213fce2d12d1f | |
parent | ee06528c0346041b3555dd337a80a022dce3cb88 (diff) | |
download | android_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.c | 34 |
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; } |