17f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee/**
27f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * mount.c
37f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee *
47f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * Copyright (c) 2013 Samsung Electronics Co., Ltd.
57f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee *             http://www.samsung.com/
67f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee *
77f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * This program is free software; you can redistribute it and/or modify
87f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * it under the terms of the GNU General Public License version 2 as
97f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * published by the Free Software Foundation.
107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee */
117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee#include "fsck.h"
127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid print_inode_info(struct f2fs_inode *inode)
147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
153c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	unsigned int i = 0;
167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int namelen = le32_to_cpu(inode->i_namelen);
177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_mode);
197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_uid);
207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_gid);
217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_links);
227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(inode, i_size);
237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(inode, i_blocks);
247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(inode, i_atime);
267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_atime_nsec);
277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(inode, i_ctime);
287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_ctime_nsec);
297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(inode, i_mtime);
307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_mtime_nsec);
317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_generation);
337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_current_depth);
347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_xattr_nid);
357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_flags);
3620cc47abbad6e8aa7c0301ffa0f9947dad32a0ddJaegeuk Kim	DISP_u32(inode, i_inline);
377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_pino);
387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (namelen) {
407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		DISP_u32(inode, i_namelen);
417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		inode->i_name[namelen] = '\0';
427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		DISP_utf(inode, i_name);
437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("i_ext: fofs:%x blkaddr:%x len:%x\n",
467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			inode->i_ext.fofs,
477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			inode->i_ext.blk_addr,
487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			inode->i_ext.len);
497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[0]);	/* Pointers to data blocks */
517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[1]);	/* Pointers to data blocks */
527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[2]);	/* Pointers to data blocks */
537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[3]);	/* Pointers to data blocks */
547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
55cd1e4704d0cbf1cbb49b3f33c576566b4b1e296eJaegeuk Kim	for (i = 4; i < ADDRS_PER_INODE(inode); i++) {
567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (inode->i_addr[i] != 0x0) {
5759c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			printf("i_addr[0x%x] points data block\r\t\t[0x%4x]\n",
587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					i, inode->i_addr[i]);
597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			break;
607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[0]);	/* direct */
647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[1]);	/* direct */
657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[2]);	/* indirect */
667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[3]);	/* indirect */
677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[4]);	/* double indirect */
687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid print_node_info(struct f2fs_node *node_block)
737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nid_t ino = le32_to_cpu(node_block->footer.ino);
757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nid_t nid = le32_to_cpu(node_block->footer.nid);
767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Is this inode? */
777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (ino == nid) {
787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		DBG(0, "Node ID [0x%x:%u] is inode\n", nid, nid);
797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		print_inode_info(&node_block->i);
807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else {
818843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee		int i;
828843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee		u32 *dump_blk = (u32 *)node_block;
8359c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim		DBG(0, "Node ID [0x%x:%u] is direct node or indirect node.\n",
8459c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim								nid, nid);
858843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee		for (i = 0; i <= 10; i++)
8659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			MSG(0, "[%d]\t\t\t[0x%8x : %d]\n",
8759c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim						i, dump_blk[i], dump_blk[i]);
887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid print_raw_sb_info(struct f2fs_sb_info *sbi)
927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
94223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee
95223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee	if (!config.dbg_lv)
96223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee		return;
97223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee
987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
1007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("| Super block                                            |\n");
1017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
1027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, magic);
1047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, major_ver);
1057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, minor_ver);
1067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_sectorsize);
1077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_sectors_per_block);
1087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_blocksize);
1107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_blocks_per_seg);
1117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segs_per_sec);
1127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, secs_per_zone);
1137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, checksum_offset);
1147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(sb, block_count);
1157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, section_count);
1177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count);
1187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_ckpt);
1197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_sit);
1207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_nat);
1217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_ssa);
1237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_main);
1247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment0_blkaddr);
1257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, cp_blkaddr);
1277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, sit_blkaddr);
1287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, nat_blkaddr);
1297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, ssa_blkaddr);
1307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, main_blkaddr);
1317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, root_ino);
1337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, node_ino);
1347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, meta_ino);
135fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee	DISP_u32(sb, cp_payload);
1367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
1377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
1387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid print_ckpt_info(struct f2fs_sb_info *sbi)
1407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
1417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
1427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
143223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee	if (!config.dbg_lv)
144223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee		return;
145223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee
1467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
1477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
1487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("| Checkpoint                                             |\n");
1497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
1507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, checkpoint_ver);
1527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, user_block_count);
1537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, valid_block_count);
1547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, rsvd_segment_count);
1557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, overprov_segment_count);
1567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, free_segment_count);
1577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_HOT_NODE]);
1597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_WARM_NODE]);
1607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_COLD_NODE]);
1617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_segno[0]);
1627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_segno[1]);
1637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_segno[2]);
1647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_blkoff[0]);
1667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_blkoff[1]);
1677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_blkoff[2]);
1687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_HOT_DATA]);
1717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_WARM_DATA]);
1727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_COLD_DATA]);
1737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_segno[0]);
1747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_segno[1]);
1757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_segno[2]);
1767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_blkoff[0]);
1787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_blkoff[1]);
1797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_blkoff[2]);
1807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, ckpt_flags);
1827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cp_pack_total_block_count);
1837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cp_pack_start_sum);
1847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, valid_node_count);
1857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, valid_inode_count);
1867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, next_free_nid);
1877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, sit_ver_bitmap_bytesize);
1887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, nat_ver_bitmap_bytesize);
1897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, checksum_offset);
1907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, elapsed_time);
1917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, sit_nat_version_bitmap[0]);
1937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n\n");
1947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
1957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint sanity_check_raw_super(struct f2fs_super_block *raw_super)
1977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
1987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int blocksize;
1997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) {
2017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) {
2057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	blocksize = 1 << le32_to_cpu(raw_super->log_blocksize);
2097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_BLKSIZE != blocksize) {
2107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_LOG_SECTOR_SIZE != le32_to_cpu(raw_super->log_sectorsize)) {
2147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
21759c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	if (F2FS_LOG_SECTORS_PER_BLOCK !=
21859c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				le32_to_cpu(raw_super->log_sectors_per_block)) {
2197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
2237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
2247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint validate_super_block(struct f2fs_sb_info *sbi, int block)
2267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
2274c992fe23ae6739767f584a96157d0585282d8e2Jaegeuk Kim	u64 offset;
2287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->raw_super = malloc(sizeof(struct f2fs_super_block));
2297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2304c992fe23ae6739767f584a96157d0585282d8e2Jaegeuk Kim	if (block == 0)
2314c992fe23ae6739767f584a96157d0585282d8e2Jaegeuk Kim		offset = F2FS_SUPER_OFFSET;
2324c992fe23ae6739767f584a96157d0585282d8e2Jaegeuk Kim	else
2334c992fe23ae6739767f584a96157d0585282d8e2Jaegeuk Kim		offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET;
2344c992fe23ae6739767f584a96157d0585282d8e2Jaegeuk Kim
2357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (dev_read(sbi->raw_super, offset, sizeof(struct f2fs_super_block)))
2367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sanity_check_raw_super(sbi->raw_super))
2397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return 0;
2407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->raw_super);
24259c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	MSG(0, "\tCan't find a valid F2FS superblock at 0x%x\n", block);
2437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return -EINVAL;
2457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
2467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint init_sb_info(struct f2fs_sb_info *sbi)
2487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
2497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_super = sbi->raw_super;
2507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->log_sectors_per_block =
2527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		le32_to_cpu(raw_super->log_sectors_per_block);
2537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->log_blocksize = le32_to_cpu(raw_super->log_blocksize);
2547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->blocksize = 1 << sbi->log_blocksize;
2557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
2567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->blocks_per_seg = 1 << sbi->log_blocks_per_seg;
2577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
2587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
2597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_sections = le32_to_cpu(raw_super->section_count);
2607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_node_count =
2617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		(le32_to_cpu(raw_super->segment_count_nat) / 2)
2627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		* sbi->blocks_per_seg * NAT_ENTRY_PER_BLOCK;
2637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->root_ino_num = le32_to_cpu(raw_super->root_ino);
2647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->node_ino_num = le32_to_cpu(raw_super->node_ino);
2657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino);
2667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->cur_victim_sec = NULL_SEGNO;
2677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
2687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
2697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
27059c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kimvoid *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr,
27159c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				unsigned long long *version)
2727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
2737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	void *cp_page_1, *cp_page_2;
2747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *cp_block;
2757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long blk_size = sbi->blocksize;
2767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long long cur_version = 0, pre_version = 0;
2777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int crc = 0;
2787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	size_t crc_offset;
2797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Read the 1st cp block in this CP pack */
2817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_page_1 = malloc(PAGE_SIZE);
2827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (dev_read_block(cp_page_1, cp_addr) < 0)
2837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return NULL;
2847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_block = (struct f2fs_checkpoint *)cp_page_1;
2867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc_offset = le32_to_cpu(cp_block->checksum_offset);
2877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (crc_offset >= blk_size)
2887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp1;
2897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
2917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_crc_valid(crc, cp_block, crc_offset))
2927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp1;
2937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pre_version = le64_to_cpu(cp_block->checkpoint_ver);
2957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Read the 2nd cp block in this CP pack */
2977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_page_2 = malloc(PAGE_SIZE);
2987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
299fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee
3007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (dev_read_block(cp_page_2, cp_addr) < 0)
3017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp2;
3027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_block = (struct f2fs_checkpoint *)cp_page_2;
3047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc_offset = le32_to_cpu(cp_block->checksum_offset);
3057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (crc_offset >= blk_size)
3067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp2;
3077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
3097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_crc_valid(crc, cp_block, crc_offset))
310fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee		goto invalid_cp2;
3117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cur_version = le64_to_cpu(cp_block->checkpoint_ver);
3137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (cur_version == pre_version) {
3157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		*version = cur_version;
3167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(cp_page_2);
3177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return cp_page_1;
3187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
3197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeinvalid_cp2:
3217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp_page_2);
3227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeinvalid_cp1:
3237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp_page_1);
3247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return NULL;
3257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
3267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint get_valid_checkpoint(struct f2fs_sb_info *sbi)
3287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
3297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_sb = sbi->raw_super;
3307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	void *cp1, *cp2, *cur_page;
3317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long blk_size = sbi->blocksize;
3327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long long cp1_version = 0, cp2_version = 0;
3337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long long cp_start_blk_no;
334fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee	unsigned int cp_blks = 1 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
335893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	int ret;
3367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
337fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee	sbi->ckpt = malloc(cp_blks * blk_size);
3387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sbi->ckpt)
3397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
3407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/*
3417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	 * Finding out valid cp block involves read both
3427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	 * sets( cp pack1 and cp pack 2)
3437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	 */
3447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_start_blk_no = le32_to_cpu(raw_sb->cp_blkaddr);
3457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp1 = validate_checkpoint(sbi, cp_start_blk_no, &cp1_version);
3467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* The second checkpoint pack should start at the next segment */
3487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_start_blk_no += 1 << le32_to_cpu(raw_sb->log_blocks_per_seg);
3497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp2 = validate_checkpoint(sbi, cp_start_blk_no, &cp2_version);
3507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (cp1 && cp2) {
352893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		if (ver_after(cp2_version, cp1_version)) {
3537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			cur_page = cp2;
354893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			sbi->cur_cp = 2;
355893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		} else {
3567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			cur_page = cp1;
357893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			sbi->cur_cp = 1;
358893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		}
3597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else if (cp1) {
3607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		cur_page = cp1;
361893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		sbi->cur_cp = 1;
3627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else if (cp2) {
3637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		cur_page = cp2;
364893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		sbi->cur_cp = 2;
3657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else {
3667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(cp1);
3677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(cp2);
3687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto fail_no_cp;
3697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
3707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(sbi->ckpt, cur_page, blk_size);
3727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
373fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee	if (cp_blks > 1) {
374c246ccf8447c47801ae0912ca356831a18c77895Mark Salyzyn		unsigned int i;
375fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee		unsigned long long cp_blk_no;
376fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee
377fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee		cp_blk_no = le32_to_cpu(raw_sb->cp_blkaddr);
378fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee		if (cur_page == cp2)
37959c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			cp_blk_no += 1 <<
38059c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				le32_to_cpu(raw_sb->log_blocks_per_seg);
381fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee		/* copy sit bitmap */
382fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee		for (i = 1; i < cp_blks; i++) {
383fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee			unsigned char *ckpt = (unsigned char *)sbi->ckpt;
384893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			ret = dev_read_block(cur_page, cp_blk_no + i);
385893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			ASSERT(ret >= 0);
386fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee			memcpy(ckpt + i * blk_size, cur_page, blk_size);
387fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee		}
388fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee	}
3897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp1);
3907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp2);
3917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
3927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leefail_no_cp:
3947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->ckpt);
3957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return -EINVAL;
3967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
3977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint sanity_check_ckpt(struct f2fs_sb_info *sbi)
3997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int total, fsmeta;
4017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
4027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
4037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	total = le32_to_cpu(raw_super->segment_count);
4057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
4067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(raw_super->segment_count_sit);
4077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(raw_super->segment_count_nat);
4087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(ckpt->rsvd_segment_count);
4097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(raw_super->segment_count_ssa);
4107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (fsmeta >= total)
4127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return 1;
4137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
4157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
4167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint init_node_manager(struct f2fs_sb_info *sbi)
4187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *sb_raw = F2FS_RAW_SUPER(sbi);
4207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
4217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned char *version_bitmap;
4227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int nat_segs, nat_blocks;
4237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->nat_blkaddr = le32_to_cpu(sb_raw->nat_blkaddr);
4257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* segment_count_nat includes pair segment so divide to 2. */
4277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_segs = le32_to_cpu(sb_raw->segment_count_nat) >> 1;
4287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_blocks = nat_segs << le32_to_cpu(sb_raw->log_blocks_per_seg);
4297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks;
4307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->fcnt = 0;
4317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->nat_cnt = 0;
4327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->init_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid);
4337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid);
4347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP);
4367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->nat_bitmap = malloc(nm_i->bitmap_size);
4387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!nm_i->nat_bitmap)
4397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
4407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	version_bitmap = __bitmap_ptr(sbi, NAT_BITMAP);
4417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!version_bitmap)
4427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -EFAULT;
4437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* copy version bitmap */
4457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(nm_i->nat_bitmap, version_bitmap, nm_i->bitmap_size);
4467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
4477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
4487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_node_manager(struct f2fs_sb_info *sbi)
4507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int err;
4527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->nm_info = malloc(sizeof(struct f2fs_nm_info));
4537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sbi->nm_info)
4547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
4557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	err = init_node_manager(sbi);
4577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (err)
4587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return err;
4597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
4617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
4627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_sit_info(struct f2fs_sb_info *sbi)
4647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_sb = F2FS_RAW_SUPER(sbi);
4667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
4677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i;
4687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int sit_segs, start;
4697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	char *src_bitmap, *dst_bitmap;
4707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int bitmap_size;
4717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i = malloc(sizeof(struct sit_info));
4737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sit_i)
4747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
4757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	SM_I(sbi)->sit_info = sit_i;
4777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sentries = calloc(TOTAL_SEGS(sbi) * sizeof(struct seg_entry), 1);
4797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (start = 0; start < TOTAL_SEGS(sbi); start++) {
4817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit_i->sentries[start].cur_valid_map
4827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			= calloc(SIT_VBLOCK_MAP_SIZE, 1);
4837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit_i->sentries[start].ckpt_valid_map
4847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			= calloc(SIT_VBLOCK_MAP_SIZE, 1);
4857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (!sit_i->sentries[start].cur_valid_map
4867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				|| !sit_i->sentries[start].ckpt_valid_map)
4877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return -ENOMEM;
4887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
4897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_segs = le32_to_cpu(raw_sb->segment_count_sit) >> 1;
4917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	bitmap_size = __bitmap_size(sbi, SIT_BITMAP);
4927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	src_bitmap = __bitmap_ptr(sbi, SIT_BITMAP);
4937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	dst_bitmap = malloc(bitmap_size);
4957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(dst_bitmap, src_bitmap, bitmap_size);
4967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sit_base_addr = le32_to_cpu(raw_sb->sit_blkaddr);
4987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sit_blocks = sit_segs << sbi->log_blocks_per_seg;
4997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->written_valid_blocks = le64_to_cpu(ckpt->valid_block_count);
5007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sit_bitmap = dst_bitmap;
5017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->bitmap_size = bitmap_size;
5027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->dirty_sentries = 0;
5037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sents_per_block = SIT_ENTRY_PER_BLOCK;
5047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->elapsed_time = le64_to_cpu(ckpt->elapsed_time);
5057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
5067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
5077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5083c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrallvoid reset_curseg(struct f2fs_sb_info *sbi, int type)
5097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
5107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg = CURSEG_I(sbi, type);
5116591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	struct summary_footer *sum_footer;
512893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct seg_entry *se;
5137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5146591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	sum_footer = &(curseg->sum_blk->footer);
5156591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	memset(sum_footer, 0, sizeof(struct summary_footer));
5166591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	if (IS_DATASEG(type))
5176591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		SET_SUM_TYPE(sum_footer, SUM_TYPE_DATA);
5186591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	if (IS_NODESEG(type))
5196591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		SET_SUM_TYPE(sum_footer, SUM_TYPE_NODE);
520893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	se = get_seg_entry(sbi, curseg->segno);
521893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	se->type = type;
5227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
5237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5246591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kimstatic void read_compacted_summaries(struct f2fs_sb_info *sbi)
5257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
5267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg;
5276591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	unsigned int i, j, offset;
5287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t start;
5297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	char *kaddr;
5306591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	int ret;
5317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	start = start_sum_block(sbi);
5337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	kaddr = (char *)malloc(PAGE_SIZE);
5356591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	ret = dev_read_block(kaddr, start++);
5366591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	ASSERT(ret >= 0);
5377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
5397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(&curseg->sum_blk->n_nats, kaddr, SUM_JOURNAL_SIZE);
5407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
54259c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	memcpy(&curseg->sum_blk->n_sits, kaddr + SUM_JOURNAL_SIZE,
54359c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim						SUM_JOURNAL_SIZE);
5447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	offset = 2 * SUM_JOURNAL_SIZE;
5467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
5477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		unsigned short blk_off;
54810d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		struct curseg_info *curseg = CURSEG_I(sbi, i);
5497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5503c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall		reset_curseg(sbi, i);
5517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (curseg->alloc_type == SSR)
5537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_off = sbi->blocks_per_seg;
55410d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		else
55510d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim			blk_off = curseg->next_blkoff;
5567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		for (j = 0; j < blk_off; j++) {
5587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			struct f2fs_summary *s;
5597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			s = (struct f2fs_summary *)(kaddr + offset);
5607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			curseg->sum_blk->entries[j] = *s;
5617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			offset += SUMMARY_SIZE;
56259c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			if (offset + SUMMARY_SIZE <=
56359c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim					PAGE_CACHE_SIZE - SUM_FOOTER_SIZE)
5647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				continue;
5657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			memset(kaddr, 0, PAGE_SIZE);
5666591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim			ret = dev_read_block(kaddr, start++);
5676591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim			ASSERT(ret >= 0);
5687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			offset = 0;
5697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
5707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
5717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(kaddr);
5727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
5737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5746591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kimstatic void restore_node_summary(struct f2fs_sb_info *sbi,
5757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		unsigned int segno, struct f2fs_summary_block *sum_blk)
5767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
5777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_node *node_blk;
5787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary *sum_entry;
5797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t addr;
5803c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	unsigned int i;
5816591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	int ret;
5827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5836591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	node_blk = malloc(F2FS_BLKSIZE);
5846591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	ASSERT(node_blk);
5857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* scan the node segment */
5877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	addr = START_BLOCK(sbi, segno);
5887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sum_entry = &sum_blk->entries[0];
5897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < sbi->blocks_per_seg; i++, sum_entry++) {
5916591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		ret = dev_read_block(node_blk, addr);
5926591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		ASSERT(ret >= 0);
5937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sum_entry->nid = node_blk->footer.nid;
5947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		addr++;
5957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
5966591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	free(node_blk);
5977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
5987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5996591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kimstatic void read_normal_summaries(struct f2fs_sb_info *sbi, int type)
6007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
6027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum_blk;
6037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg;
6047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int segno = 0;
6057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t blk_addr = 0;
6066591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	int ret;
6077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (IS_DATASEG(type)) {
6097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		segno = le32_to_cpu(ckpt->cur_data_segno[type]);
6107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
6117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
6127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		else
6137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
6147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else {
61559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim		segno = le32_to_cpu(ckpt->cur_node_segno[type -
61659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim							CURSEG_HOT_NODE]);
6177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
61859c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE,
61959c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim							type - CURSEG_HOT_NODE);
6207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		else
6217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_addr = GET_SUM_BLKADDR(sbi, segno);
6227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
6237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sum_blk = (struct f2fs_summary_block *)malloc(PAGE_SIZE);
6256591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	ret = dev_read_block(sum_blk, blk_addr);
6266591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	ASSERT(ret >= 0);
6276591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim
6286591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	if (IS_NODESEG(type) && !is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
6296591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		restore_node_summary(sbi, segno, sum_blk);
6307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg = CURSEG_I(sbi, type);
6327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(curseg->sum_blk, sum_blk, PAGE_CACHE_SIZE);
6333c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	reset_curseg(sbi, type);
6347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sum_blk);
6357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6376591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kimstatic void restore_curseg_summaries(struct f2fs_sb_info *sbi)
6387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int type = CURSEG_HOT_DATA;
6407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG)) {
6426591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		read_compacted_summaries(sbi);
6437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		type = CURSEG_HOT_NODE;
6447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
6457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6466591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	for (; type <= CURSEG_COLD_NODE; type++)
6476591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		read_normal_summaries(sbi, type);
6487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6506591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kimstatic void build_curseg(struct f2fs_sb_info *sbi)
6517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
65210d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
6537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *array;
65410d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim	unsigned short blk_off;
65510d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim	unsigned int segno;
6567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int i;
6577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
6596591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	ASSERT(array);
6607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	SM_I(sbi)->curseg_array = array;
6627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < NR_CURSEG_TYPE; i++) {
6647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
6656591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim		ASSERT(array[i].sum_blk);
66610d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		if (i <= CURSEG_COLD_DATA) {
66710d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim			blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]);
66810d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim			segno = le32_to_cpu(ckpt->cur_data_segno[i]);
66910d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		}
67010d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		if (i > CURSEG_COLD_DATA) {
67110d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim			blk_off = le16_to_cpu(ckpt->cur_node_blkoff[i -
67210d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim							CURSEG_HOT_NODE]);
67310d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim			segno = le32_to_cpu(ckpt->cur_node_segno[i -
67410d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim							CURSEG_HOT_NODE]);
67510d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		}
67610d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		array[i].segno = segno;
67710d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		array[i].zone = GET_ZONENO_FROM_SEGNO(sbi, segno);
67810d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		array[i].next_segno = NULL_SEGNO;
67910d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		array[i].next_blkoff = blk_off;
68010d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim		array[i].alloc_type = ckpt->alloc_type[i];
6817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
6826591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim	restore_curseg_summaries(sbi);
6837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeinline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
6867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int end_segno = SM_I(sbi)->segment_count - 1;
6887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(segno <= end_segno);
6897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
691893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kimstatic struct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi,
69259c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim						unsigned int segno)
6937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
6957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
6967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t blk_addr = sit_i->sit_base_addr + offset;
6977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sit_block *sit_blk = calloc(BLOCK_SZ, 1);
698893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	int ret;
6997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	check_seg_range(sbi, segno);
7017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* calculate sit block address */
7037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_test_bit(offset, sit_i->sit_bitmap))
7047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		blk_addr += sit_i->sit_blocks;
7057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
706893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ret = dev_read_block(sit_blk, blk_addr);
707893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ASSERT(ret >= 0);
7087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return sit_blk;
7107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
712893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kimvoid rewrite_current_sit_page(struct f2fs_sb_info *sbi,
713893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			unsigned int segno, struct f2fs_sit_block *sit_blk)
714893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim{
715893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct sit_info *sit_i = SIT_I(sbi);
716893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
717893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	block_t blk_addr = sit_i->sit_base_addr + offset;
718893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	int ret;
719893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
720893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	/* calculate sit block address */
721893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	if (f2fs_test_bit(offset, sit_i->sit_bitmap))
722893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		blk_addr += sit_i->sit_blocks;
723893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
724893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ret = dev_write_block(sit_blk, blk_addr);
725893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ASSERT(ret >= 0);
726893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim}
727893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
7287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid check_block_count(struct f2fs_sb_info *sbi,
7293c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall		unsigned int segno, struct f2fs_sit_entry *raw_sit)
7307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_info = SM_I(sbi);
7327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int end_segno = sm_info->segment_count - 1;
7337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int valid_blocks = 0;
7343c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	unsigned int i;
7357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* check segment usage */
737fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim	if (GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg)
738fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim		ASSERT_MSG("Invalid SIT vblocks: segno=0x%x, %u",
739fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim				segno, GET_SIT_VBLOCKS(raw_sit));
7407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* check boundary of a given segment number */
742fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim	if (segno > end_segno)
743fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim		ASSERT_MSG("Invalid SEGNO: 0x%x", segno);
7447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* check bitmap with valid block count */
746fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim	for (i = 0; i < SIT_VBLOCK_MAP_SIZE; i++)
747fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim		valid_blocks += get_bits_in_byte(raw_sit->valid_map[i]);
748fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim
749fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim	if (GET_SIT_VBLOCKS(raw_sit) != valid_blocks)
750fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim		ASSERT_MSG("Wrong SIT valid blocks: segno=0x%x, %u vs. %u",
751fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim				segno, GET_SIT_VBLOCKS(raw_sit), valid_blocks);
752893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
753893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	if (GET_SIT_TYPE(raw_sit) >= NO_CHECK_TYPE)
754893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		ASSERT_MSG("Wrong SIT type: segno=0x%x, %u",
755893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim				segno, GET_SIT_TYPE(raw_sit));
7567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid seg_info_from_raw_sit(struct seg_entry *se,
7597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct f2fs_sit_entry *raw_sit)
7607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->valid_blocks = GET_SIT_VBLOCKS(raw_sit);
7627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->ckpt_valid_blocks = GET_SIT_VBLOCKS(raw_sit);
7637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(se->cur_valid_map, raw_sit->valid_map, SIT_VBLOCK_MAP_SIZE);
7647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(se->ckpt_valid_map, raw_sit->valid_map, SIT_VBLOCK_MAP_SIZE);
7657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->type = GET_SIT_TYPE(raw_sit);
7667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->mtime = le64_to_cpu(raw_sit->mtime);
7677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leestruct seg_entry *get_seg_entry(struct f2fs_sb_info *sbi,
7707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		unsigned int segno)
7717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
7737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return &sit_i->sentries[segno];
7747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
77659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kimint get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno,
77759c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				struct f2fs_summary_block *sum_blk)
7787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
7807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg;
7817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int type, ret;
7827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u64 ssa_blk;
7837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ssa_blk = GET_SUM_BLKADDR(sbi, segno);
7857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (type = 0; type < NR_CURSEG_NODE_TYPE; type++) {
7867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (segno == ckpt->cur_node_segno[type]) {
787858c4039c85f7c00c57925902985701b1e083555Jaegeuk Kim			curseg = CURSEG_I(sbi, CURSEG_HOT_NODE + type);
7886591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim			if (!IS_SUM_NODE_SEG(curseg->sum_blk->footer)) {
7896591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim				ASSERT_MSG("segno [0x%x] indicates a data "
7906591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim						"segment, but should be node",
7916591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim						segno);
7926591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim				return -EINVAL;
7936591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim			}
7947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
79559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			return SEG_TYPE_CUR_NODE;
7967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
7977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
7987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (type = 0; type < NR_CURSEG_DATA_TYPE; type++) {
8007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (segno == ckpt->cur_data_segno[type]) {
8017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			curseg = CURSEG_I(sbi, type);
8026591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim			if (IS_SUM_NODE_SEG(curseg->sum_blk->footer)) {
8036591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim				ASSERT_MSG("segno [0x%x] indicates a node "
8046591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim						"segment, but should be data",
8056591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim						segno);
8066591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim				return -EINVAL;
8076591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim			}
80859c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			DBG(2, "segno [0x%x] is current data seg[0x%x]\n",
80959c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim								segno, type);
8106591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim			memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
81159c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			return SEG_TYPE_CUR_DATA;
8127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
8137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
8147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = dev_read_block(sum_blk, ssa_blk);
8167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(ret >= 0);
8177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (IS_SUM_NODE_SEG(sum_blk->footer))
8197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return SEG_TYPE_NODE;
8207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	else
8217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return SEG_TYPE_DATA;
8227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
82559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kimint get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr,
82659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				struct f2fs_summary *sum_entry)
8277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum_blk;
8297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 segno, offset;
8307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret;
8317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	segno = GET_SEGNO(sbi, blk_addr);
8337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	offset = OFFSET_IN_SEG(sbi, blk_addr);
8347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sum_blk = calloc(BLOCK_SZ, 1);
8367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = get_sum_block(sbi, segno, sum_blk);
83859c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	memcpy(sum_entry, &(sum_blk->entries[offset]),
83959c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				sizeof(struct f2fs_summary));
8407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sum_blk);
8417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return ret;
8427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
84402d04218720248f35ee2bcf4ca34c8b0e6e05140Jaegeuk Kimstatic void get_nat_entry(struct f2fs_sb_info *sbi, nid_t nid,
84502d04218720248f35ee2bcf4ca34c8b0e6e05140Jaegeuk Kim				struct f2fs_nat_entry *raw_nat)
8467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
8487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nat_block *nat_block;
8497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_off;
8507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_addr;
8517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int seg_off, entry_off;
8527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret;
8537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (lookup_nat_in_journal(sbi, nid, raw_nat) >= 0)
85502d04218720248f35ee2bcf4ca34c8b0e6e05140Jaegeuk Kim		return;
8567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
8587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_off = nid / NAT_ENTRY_PER_BLOCK;
8607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	entry_off = nid % NAT_ENTRY_PER_BLOCK;
8617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	seg_off = block_off >> sbi->log_blocks_per_seg;
8637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_addr = (pgoff_t)(nm_i->nat_blkaddr +
8647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			(seg_off << sbi->log_blocks_per_seg << 1) +
8657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
8667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
8687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		block_addr += sbi->blocks_per_seg;
8697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = dev_read_block(nat_block, block_addr);
8717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(ret >= 0);
8727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
87302d04218720248f35ee2bcf4ca34c8b0e6e05140Jaegeuk Kim	memcpy(raw_nat, &nat_block->entries[entry_off],
87402d04218720248f35ee2bcf4ca34c8b0e6e05140Jaegeuk Kim					sizeof(struct f2fs_nat_entry));
8757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(nat_block);
8767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
87802d04218720248f35ee2bcf4ca34c8b0e6e05140Jaegeuk Kimvoid get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
8797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nat_entry raw_nat;
88102d04218720248f35ee2bcf4ca34c8b0e6e05140Jaegeuk Kim	get_nat_entry(sbi, nid, &raw_nat);
8827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ni->nid = nid;
8837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	node_info_from_raw_nat(ni, &raw_nat);
8847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid build_sit_entries(struct f2fs_sb_info *sbi)
8877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
8897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
8907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum = curseg->sum_blk;
8917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int segno;
8927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
8947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct seg_entry *se = &sit_i->sentries[segno];
8957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct f2fs_sit_block *sit_blk;
8967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct f2fs_sit_entry sit;
8977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		int i;
8987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		for (i = 0; i < sits_in_cursum(sum); i++) {
9007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if (le32_to_cpu(segno_in_journal(sum, i)) == segno) {
9017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				sit = sit_in_journal(sum, i);
9027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				goto got_it;
9037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
9047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
9057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit_blk = get_current_sit_page(sbi, segno);
9067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, segno)];
9077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sit_blk);
9087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leegot_it:
9097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		check_block_count(sbi, segno, &sit);
9107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		seg_info_from_raw_sit(se, &sit);
9117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
9127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
9147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_segment_manager(struct f2fs_sb_info *sbi)
9167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
9177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
9187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
9197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_info;
9207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info = malloc(sizeof(struct f2fs_sm_info));
9227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sm_info)
9237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
9247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* init sm info */
9267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->sm_info = sm_info;
9277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->seg0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
9287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->main_blkaddr = le32_to_cpu(raw_super->main_blkaddr);
9297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->segment_count = le32_to_cpu(raw_super->segment_count);
9307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
9317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
9327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main);
9337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
9347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	build_sit_info(sbi);
9367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	build_curseg(sbi);
9387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	build_sit_entries(sbi);
9407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
9427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
9437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
944fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kimvoid build_sit_area_bitmap(struct f2fs_sb_info *sbi)
9457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
9467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
9477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_i = SM_I(sbi);
9483c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	unsigned int segno = 0;
9497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	char *ptr = NULL;
9507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 sum_vblocks = 0;
9517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 free_segs = 0;
9527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct seg_entry *se;
9537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->sit_area_bitmap_sz = sm_i->main_segments * SIT_VBLOCK_MAP_SIZE;
9557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->sit_area_bitmap = calloc(1, fsck->sit_area_bitmap_sz);
9567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ptr = fsck->sit_area_bitmap;
9577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(fsck->sit_area_bitmap_sz == fsck->main_area_bitmap_sz);
9597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
960fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim	for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
9617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		se = get_seg_entry(sbi, segno);
9627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		memcpy(ptr, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE);
9647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ptr += SIT_VBLOCK_MAP_SIZE;
9657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (se->valid_blocks == 0x0) {
9677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if (sbi->ckpt->cur_node_segno[0] == segno ||
9687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_data_segno[0] == segno ||
9697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_node_segno[1] == segno ||
9707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_data_segno[1] == segno ||
9717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_node_segno[2] == segno ||
9727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_data_segno[2] == segno) {
9737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				continue;
9747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			} else {
9757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				free_segs++;
9767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
9777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		} else {
9787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			sum_vblocks += se->valid_blocks;
9797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
9807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
9817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->chk.sit_valid_blocks = sum_vblocks;
9827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->chk.sit_free_segs = free_segs;
9837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
98459c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	DBG(1, "Blocks [0x%x : %d] Free Segs [0x%x : %d]\n\n",
98559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			sum_vblocks, sum_vblocks,
986223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee			free_segs, free_segs);
9877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
9887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
989893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kimvoid rewrite_sit_area_bitmap(struct f2fs_sb_info *sbi)
990893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim{
991893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
992893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
993893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct sit_info *sit_i = SIT_I(sbi);
994893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	unsigned int segno = 0;
995893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct f2fs_summary_block *sum = curseg->sum_blk;
996893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	char *ptr = NULL;
997893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
998893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	/* remove sit journal */
999893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	sum->n_sits = 0;
1000893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1001893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	fsck->chk.free_segs = 0;
1002893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1003893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ptr = fsck->main_area_bitmap;
1004893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1005893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
1006893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		struct f2fs_sit_block *sit_blk;
1007893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		struct f2fs_sit_entry *sit;
1008893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		struct seg_entry *se;
1009893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		u16 valid_blocks = 0;
1010893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		u16 type;
1011893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		int i;
1012893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1013893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		sit_blk = get_current_sit_page(sbi, segno);
1014893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		sit = &sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, segno)];
1015893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		memcpy(sit->valid_map, ptr, SIT_VBLOCK_MAP_SIZE);
1016893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1017893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		/* update valid block count */
1018893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		for (i = 0; i < SIT_VBLOCK_MAP_SIZE; i++)
1019893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			valid_blocks += get_bits_in_byte(sit->valid_map[i]);
1020893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1021893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		se = get_seg_entry(sbi, segno);
1022893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		type = se->type;
1023893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		if (type >= NO_CHECK_TYPE) {
1024893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			ASSERT(valid_blocks);
1025893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			type = 0;
1026893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		}
1027893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		sit->vblocks = cpu_to_le16((type << SIT_VBLOCKS_SHIFT) |
1028893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim								valid_blocks);
1029893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		rewrite_current_sit_page(sbi, segno, sit_blk);
1030893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		free(sit_blk);
1031893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1032893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		if (valid_blocks == 0 &&
1033893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim				sbi->ckpt->cur_node_segno[0] != segno &&
1034893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim				sbi->ckpt->cur_data_segno[0] != segno &&
1035893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim				sbi->ckpt->cur_node_segno[1] != segno &&
1036893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim				sbi->ckpt->cur_data_segno[1] != segno &&
1037893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim				sbi->ckpt->cur_node_segno[2] != segno &&
1038893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim				sbi->ckpt->cur_data_segno[2] != segno)
1039893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			fsck->chk.free_segs++;
1040893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1041893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		ptr += SIT_VBLOCK_MAP_SIZE;
1042893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	}
1043893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim}
1044893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
104559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kimint lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
104659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim					struct f2fs_nat_entry *raw_nat)
10477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
10487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
10497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum = curseg->sum_blk;
10507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int i = 0;
10517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < nats_in_cursum(sum); i++) {
10537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (le32_to_cpu(nid_in_journal(sum, i)) == nid) {
105459c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			memcpy(raw_nat, &nat_in_journal(sum, i),
105559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim						sizeof(struct f2fs_nat_entry));
10567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			DBG(3, "==> Found nid [0x%x] in nat cache\n", nid);
10577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return i;
10587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
10597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
10607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return -1;
10617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
10627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1063893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kimvoid nullify_nat_entry(struct f2fs_sb_info *sbi, u32 nid)
1064893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim{
1065893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
1066893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct f2fs_summary_block *sum = curseg->sum_blk;
1067893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct f2fs_nm_info *nm_i = NM_I(sbi);
1068893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	struct f2fs_nat_block *nat_block;
1069893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	pgoff_t block_off;
1070893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	pgoff_t block_addr;
1071893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	int seg_off, entry_off;
1072893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	int ret;
1073893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	int i = 0;
1074893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1075893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	/* check in journal */
1076893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	for (i = 0; i < nats_in_cursum(sum); i++) {
1077893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		if (le32_to_cpu(nid_in_journal(sum, i)) == nid) {
1078893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			memset(&nat_in_journal(sum, i), 0,
1079893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim					sizeof(struct f2fs_nat_entry));
1080893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			FIX_MSG("Remove nid [0x%x] in nat journal\n", nid);
1081893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			return;
1082893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		}
1083893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	}
1084893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
1085893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1086893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	block_off = nid / NAT_ENTRY_PER_BLOCK;
1087893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	entry_off = nid % NAT_ENTRY_PER_BLOCK;
1088893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1089893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	seg_off = block_off >> sbi->log_blocks_per_seg;
1090893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	block_addr = (pgoff_t)(nm_i->nat_blkaddr +
1091893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			(seg_off << sbi->log_blocks_per_seg << 1) +
1092893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim			(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
1093893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1094893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
1095893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim		block_addr += sbi->blocks_per_seg;
1096893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1097893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ret = dev_read_block(nat_block, block_addr);
1098893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ASSERT(ret >= 0);
1099893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1100893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	memset(&nat_block->entries[entry_off], 0,
1101893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim					sizeof(struct f2fs_nat_entry));
1102893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
1103893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ret = dev_write_block(nat_block, block_addr);
1104893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ASSERT(ret >= 0);
1105893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	free(nat_block);
1106893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim}
1107893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim
11087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid build_nat_area_bitmap(struct f2fs_sb_info *sbi)
11097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
11107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
11117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_sb = F2FS_RAW_SUPER(sbi);
11127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
11137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nat_block *nat_block;
11147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 nid, nr_nat_blks;
11157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_off;
11167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_addr;
11177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int seg_off;
11183c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	int ret;
11193c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	unsigned int i;
11207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
1122893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim	ASSERT(nat_block);
11237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Alloc & build nat entry bitmap */
112559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	nr_nat_blks = (le32_to_cpu(raw_sb->segment_count_nat) / 2) <<
112659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim						sbi->log_blocks_per_seg;
11277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->nr_nat_entries = nr_nat_blks * NAT_ENTRY_PER_BLOCK;
11297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->nat_area_bitmap_sz = (fsck->nr_nat_entries + 7) / 8;
11307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->nat_area_bitmap = calloc(fsck->nat_area_bitmap_sz, 1);
11317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(fsck->nat_area_bitmap != NULL);
11327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (block_off = 0; block_off < nr_nat_blks; block_off++) {
11347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		seg_off = block_off >> sbi->log_blocks_per_seg;
11367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		block_addr = (pgoff_t)(nm_i->nat_blkaddr +
113759c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			(seg_off << sbi->log_blocks_per_seg << 1) +
113859c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
11397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
11417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			block_addr += sbi->blocks_per_seg;
11427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ret = dev_read_block(nat_block, block_addr);
11447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ASSERT(ret >= 0);
11457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		nid = block_off * NAT_ENTRY_PER_BLOCK;
11477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		for (i = 0; i < NAT_ENTRY_PER_BLOCK; i++) {
11487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			struct f2fs_nat_entry raw_nat;
11497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			struct node_info ni;
11507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			ni.nid = nid + i;
11517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11523b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim			if ((nid + i) == F2FS_NODE_INO(sbi) ||
11533b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim					(nid + i) == F2FS_META_INO(sbi)) {
11547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				ASSERT(nat_block->entries[i].block_addr != 0x0);
11557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				continue;
11567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
11577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
115859c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			if (lookup_nat_in_journal(sbi, nid + i,
115959c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim							&raw_nat) >= 0) {
11607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				node_info_from_raw_nat(&ni, &raw_nat);
11617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				if (ni.blk_addr != 0x0) {
116259c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim					f2fs_set_bit(nid + i,
116359c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim							fsck->nat_area_bitmap);
11647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					fsck->chk.valid_nat_entry_cnt++;
116559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim					DBG(3, "nid[0x%x] in nat cache\n",
116659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim								nid + i);
11677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				}
11687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			} else {
116959c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				node_info_from_raw_nat(&ni,
117059c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim						&nat_block->entries[i]);
117159c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				if (ni.blk_addr == 0)
117259c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim					continue;
117359c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				ASSERT(nid + i != 0x0);
117459c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim
117559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				DBG(3, "nid[0x%8x] addr[0x%16x] ino[0x%8x]\n",
117659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim					nid + i, ni.blk_addr, ni.ino);
117759c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
117859c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim				fsck->chk.valid_nat_entry_cnt++;
11797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
11807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
11817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
11827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(nat_block);
11837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1184223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee	DBG(1, "valid nat entries (block_addr != 0x0) [0x%8x : %u]\n",
118559c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			fsck->chk.valid_nat_entry_cnt,
118659c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			fsck->chk.valid_nat_entry_cnt);
11877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
11887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint f2fs_do_mount(struct f2fs_sb_info *sbi)
11907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
11917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret;
1192de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim
11937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->active_logs = NR_CURSEG_TYPE;
11947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = validate_super_block(sbi, 0);
11957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (ret) {
11967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ret = validate_super_block(sbi, 1);
11977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (ret)
11987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return -1;
11997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
12007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	print_raw_sb_info(sbi);
12027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	init_sb_info(sbi);
12047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = get_valid_checkpoint(sbi);
12067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (ret) {
12077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("Can't find valid checkpoint\n");
12087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
12097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
12107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (sanity_check_ckpt(sbi)) {
12127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("Checkpoint is polluted\n");
12137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
12147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
12157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	print_ckpt_info(sbi);
12177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1218de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim	if (config.auto_fix) {
1219de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim		u32 flag = le32_to_cpu(sbi->ckpt->ckpt_flags);
1220de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim
1221de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim		if (flag & CP_FSCK_FLAG)
122273b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim			config.fix_on = 1;
1223de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim		else
1224de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim			return 1;
1225de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim	}
1226de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim
1227de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim	config.bug_on = 0;
1228de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim
12297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_valid_node_count = le32_to_cpu(sbi->ckpt->valid_node_count);
123059c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	sbi->total_valid_inode_count =
123159c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			le32_to_cpu(sbi->ckpt->valid_inode_count);
12327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count);
123359c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim	sbi->total_valid_block_count =
123459c0e13ed90a6395e5cdaaed1608358c799bb0e4Jaegeuk Kim			le64_to_cpu(sbi->ckpt->valid_block_count);
12357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->last_valid_block_count = sbi->total_valid_block_count;
12367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->alloc_valid_block_count = 0;
12377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (build_segment_manager(sbi)) {
12397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("build_segment_manager failed\n");
12407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
12417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
12427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (build_node_manager(sbi)) {
12447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("build_segment_manager failed\n");
12457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
12467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
12477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1248de6c1c7ce25841547813c71ca3b6d067300f0530Jaegeuk Kim	return 0;
12497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
12507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid f2fs_do_umount(struct f2fs_sb_info *sbi)
12527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
12537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
12547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_i = SM_I(sbi);
12557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
12563c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall	unsigned int i;
12577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* free nm_info */
12597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(nm_i->nat_bitmap);
12607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->nm_info);
12617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* free sit_info */
12637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < TOTAL_SEGS(sbi); i++) {
12647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sit_i->sentries[i].cur_valid_map);
12657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sit_i->sentries[i].ckpt_valid_map);
12667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
12677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sit_i->sit_bitmap);
12687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sm_i->sit_info);
12697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* free sm_info */
12717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < NR_CURSEG_TYPE; i++)
12727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sm_i->curseg_array[i].sum_blk);
12737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sm_i->curseg_array);
12757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->sm_info);
12767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
12777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->ckpt);
12787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->raw_super);
12797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
1280