mount.c revision 223fdf3e00a56cb32fb8c69dc4523ee53ff7731a
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{
157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	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);
367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_pino);
377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (namelen) {
397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		DISP_u32(inode, i_namelen);
407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		inode->i_name[namelen] = '\0';
417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		DISP_utf(inode, i_name);
427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("i_ext: fofs:%x blkaddr:%x len:%x\n",
457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			inode->i_ext.fofs,
467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			inode->i_ext.blk_addr,
477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			inode->i_ext.len);
487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[0]);	/* Pointers to data blocks */
507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[1]);	/* Pointers to data blocks */
517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[2]);	/* Pointers to data blocks */
527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_addr[3]);	/* Pointers to data blocks */
537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 4; i < ADDRS_PER_INODE; i++) {
557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (inode->i_addr[i] != 0x0) {
567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			printf("i_addr[0x%x] points data block\r\t\t\t\t[0x%4x]\n",
577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					i, inode->i_addr[i]);
587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			break;
597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[0]);	/* direct */
637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[1]);	/* direct */
647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[2]);	/* indirect */
657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[3]);	/* indirect */
667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(inode, i_nid[4]);	/* double indirect */
677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid print_node_info(struct f2fs_node *node_block)
727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nid_t ino = le32_to_cpu(node_block->footer.ino);
747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nid_t nid = le32_to_cpu(node_block->footer.nid);
757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Is this inode? */
767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (ino == nid) {
777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		DBG(0, "Node ID [0x%x:%u] is inode\n", nid, nid);
787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		print_inode_info(&node_block->i);
797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else {
808843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee		int i;
818843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee		u32 *dump_blk = (u32 *)node_block;
827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		DBG(0, "Node ID [0x%x:%u] is direct node or indirect node.\n", nid, nid);
838843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee		for (i = 0; i <= 10; i++)
848843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee			MSG(0, "[%d]\t\t\t[0x%8x : %d]\n", i, dump_blk[i], dump_blk[i]);
857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid print_raw_sb_info(struct f2fs_sb_info *sbi)
897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
91223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee
92223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee	if (!config.dbg_lv)
93223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee		return;
94223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee
957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("| Super block                                            |\n");
987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, magic);
1017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, major_ver);
1027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, minor_ver);
1037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_sectorsize);
1047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_sectors_per_block);
1057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_blocksize);
1077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, log_blocks_per_seg);
1087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segs_per_sec);
1097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, secs_per_zone);
1107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, checksum_offset);
1117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(sb, block_count);
1127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, section_count);
1147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count);
1157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_ckpt);
1167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_sit);
1177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_nat);
1187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_ssa);
1207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment_count_main);
1217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, segment0_blkaddr);
1227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, cp_blkaddr);
1247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, sit_blkaddr);
1257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, nat_blkaddr);
1267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, ssa_blkaddr);
1277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, main_blkaddr);
1287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, root_ino);
1307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, node_ino);
1317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(sb, meta_ino);
1327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
1337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
1347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid print_ckpt_info(struct f2fs_sb_info *sbi)
1367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
1377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
1387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
139223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee	if (!config.dbg_lv)
140223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee		return;
141223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee
1427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n");
1437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
1447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("| Checkpoint                                             |\n");
1457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("+--------------------------------------------------------+\n");
1467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, checkpoint_ver);
1487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, user_block_count);
1497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, valid_block_count);
1507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, rsvd_segment_count);
1517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, overprov_segment_count);
1527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, free_segment_count);
1537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_HOT_NODE]);
1557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_WARM_NODE]);
1567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_COLD_NODE]);
1577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_segno[0]);
1587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_segno[1]);
1597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_segno[2]);
1607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_blkoff[0]);
1627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_blkoff[1]);
1637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_node_blkoff[2]);
1647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_HOT_DATA]);
1677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_WARM_DATA]);
1687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, alloc_type[CURSEG_COLD_DATA]);
1697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_segno[0]);
1707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_segno[1]);
1717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_segno[2]);
1727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_blkoff[0]);
1747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_blkoff[1]);
1757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cur_data_blkoff[2]);
1767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, ckpt_flags);
1787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cp_pack_total_block_count);
1797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, cp_pack_start_sum);
1807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, valid_node_count);
1817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, valid_inode_count);
1827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, next_free_nid);
1837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, sit_ver_bitmap_bytesize);
1847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, nat_ver_bitmap_bytesize);
1857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, checksum_offset);
1867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u64(cp, elapsed_time);
1877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	DISP_u32(cp, sit_nat_version_bitmap[0]);
1897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	printf("\n\n");
1907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
1917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint sanity_check_raw_super(struct f2fs_super_block *raw_super)
1937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
1947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int blocksize;
1957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) {
1977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
1987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
1997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) {
2017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	blocksize = 1 << le32_to_cpu(raw_super->log_blocksize);
2057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_BLKSIZE != blocksize) {
2067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_LOG_SECTOR_SIZE != le32_to_cpu(raw_super->log_sectorsize)) {
2107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (F2FS_LOG_SECTORS_PER_BLOCK != le32_to_cpu(raw_super->log_sectors_per_block)) {
2147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
2167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
2187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
2197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint validate_super_block(struct f2fs_sb_info *sbi, int block)
2217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
2227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u64 offset = (block + 1) * F2FS_SUPER_OFFSET;
2237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->raw_super = malloc(sizeof(struct f2fs_super_block));
2247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (dev_read(sbi->raw_super, offset, sizeof(struct f2fs_super_block)))
2267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
2277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sanity_check_raw_super(sbi->raw_super))
2297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return 0;
2307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->raw_super);
2327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	MSG(0, "\tCan't find a valid F2FS filesystem in %d superblock\n", block);
2337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return -EINVAL;
2357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
2367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint init_sb_info(struct f2fs_sb_info *sbi)
2387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
2397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_super = sbi->raw_super;
2407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->log_sectors_per_block =
2427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		le32_to_cpu(raw_super->log_sectors_per_block);
2437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->log_blocksize = le32_to_cpu(raw_super->log_blocksize);
2447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->blocksize = 1 << sbi->log_blocksize;
2457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
2467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->blocks_per_seg = 1 << sbi->log_blocks_per_seg;
2477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
2487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
2497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_sections = le32_to_cpu(raw_super->section_count);
2507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_node_count =
2517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		(le32_to_cpu(raw_super->segment_count_nat) / 2)
2527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		* sbi->blocks_per_seg * NAT_ENTRY_PER_BLOCK;
2537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->root_ino_num = le32_to_cpu(raw_super->root_ino);
2547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->node_ino_num = le32_to_cpu(raw_super->node_ino);
2557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->meta_ino_num = le32_to_cpu(raw_super->meta_ino);
2567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->cur_victim_sec = NULL_SEGNO;
2577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
2587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
2597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr, unsigned long long *version)
2617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
2627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	void *cp_page_1, *cp_page_2;
2637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *cp_block;
2647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long blk_size = sbi->blocksize;
2657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long long cur_version = 0, pre_version = 0;
2667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int crc = 0;
2677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	size_t crc_offset;
2687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Read the 1st cp block in this CP pack */
2707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_page_1 = malloc(PAGE_SIZE);
2717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (dev_read_block(cp_page_1, cp_addr) < 0)
2727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return NULL;
2737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_block = (struct f2fs_checkpoint *)cp_page_1;
2757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc_offset = le32_to_cpu(cp_block->checksum_offset);
2767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (crc_offset >= blk_size)
2777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp1;
2787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
2807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_crc_valid(crc, cp_block, crc_offset))
2817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp1;
2827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pre_version = le64_to_cpu(cp_block->checkpoint_ver);
2847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Read the 2nd cp block in this CP pack */
2867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_page_2 = malloc(PAGE_SIZE);
2877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
2887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (dev_read_block(cp_page_2, cp_addr) < 0)
2897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp2;
2907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_block = (struct f2fs_checkpoint *)cp_page_2;
2927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc_offset = le32_to_cpu(cp_block->checksum_offset);
2937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (crc_offset >= blk_size)
2947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp2;
2957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
2967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset);
2977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_crc_valid(crc, cp_block, crc_offset))
2987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto invalid_cp1;
2997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cur_version = le64_to_cpu(cp_block->checkpoint_ver);
3017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (cur_version == pre_version) {
3037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		*version = cur_version;
3047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(cp_page_2);
3057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return cp_page_1;
3067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
3077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeinvalid_cp2:
3097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp_page_2);
3107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeinvalid_cp1:
3117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp_page_1);
3127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return NULL;
3137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
3147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint get_valid_checkpoint(struct f2fs_sb_info *sbi)
3167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
3177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_sb = sbi->raw_super;
3187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	void *cp1, *cp2, *cur_page;
3197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long blk_size = sbi->blocksize;
3207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long long cp1_version = 0, cp2_version = 0;
3217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned long long cp_start_blk_no;
3227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->ckpt = malloc(blk_size);
3247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sbi->ckpt)
3257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
3267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/*
3277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	 * Finding out valid cp block involves read both
3287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	 * sets( cp pack1 and cp pack 2)
3297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	 */
3307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_start_blk_no = le32_to_cpu(raw_sb->cp_blkaddr);
3317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp1 = validate_checkpoint(sbi, cp_start_blk_no, &cp1_version);
3327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* The second checkpoint pack should start at the next segment */
3347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp_start_blk_no += 1 << le32_to_cpu(raw_sb->log_blocks_per_seg);
3357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	cp2 = validate_checkpoint(sbi, cp_start_blk_no, &cp2_version);
3367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (cp1 && cp2) {
3387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (ver_after(cp2_version, cp1_version))
3397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			cur_page = cp2;
3407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		else
3417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			cur_page = cp1;
3427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else if (cp1) {
3437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		cur_page = cp1;
3447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else if (cp2) {
3457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		cur_page = cp2;
3467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else {
3477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(cp1);
3487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(cp2);
3497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		goto fail_no_cp;
3507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
3517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(sbi->ckpt, cur_page, blk_size);
3537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp1);
3557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(cp2);
3567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
3577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leefail_no_cp:
3597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->ckpt);
3607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return -EINVAL;
3617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
3627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint sanity_check_ckpt(struct f2fs_sb_info *sbi)
3647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
3657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int total, fsmeta;
3667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
3677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
3687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	total = le32_to_cpu(raw_super->segment_count);
3707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
3717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(raw_super->segment_count_sit);
3727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(raw_super->segment_count_nat);
3737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(ckpt->rsvd_segment_count);
3747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsmeta += le32_to_cpu(raw_super->segment_count_ssa);
3757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (fsmeta >= total)
3777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return 1;
3787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
3807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
3817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint init_node_manager(struct f2fs_sb_info *sbi)
3837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
3847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *sb_raw = F2FS_RAW_SUPER(sbi);
3857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
3867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned char *version_bitmap;
3877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int nat_segs, nat_blocks;
3887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->nat_blkaddr = le32_to_cpu(sb_raw->nat_blkaddr);
3907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
3917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* segment_count_nat includes pair segment so divide to 2. */
3927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_segs = le32_to_cpu(sb_raw->segment_count_nat) >> 1;
3937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_blocks = nat_segs << le32_to_cpu(sb_raw->log_blocks_per_seg);
3947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->max_nid = NAT_ENTRY_PER_BLOCK * nat_blocks;
3957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->fcnt = 0;
3967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->nat_cnt = 0;
3977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->init_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid);
3987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid);
3997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP);
4017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nm_i->nat_bitmap = malloc(nm_i->bitmap_size);
4037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!nm_i->nat_bitmap)
4047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
4057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	version_bitmap = __bitmap_ptr(sbi, NAT_BITMAP);
4067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!version_bitmap)
4077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -EFAULT;
4087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* copy version bitmap */
4107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(nm_i->nat_bitmap, version_bitmap, nm_i->bitmap_size);
4117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
4127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
4137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_node_manager(struct f2fs_sb_info *sbi)
4157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int err;
4177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->nm_info = malloc(sizeof(struct f2fs_nm_info));
4187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sbi->nm_info)
4197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
4207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	err = init_node_manager(sbi);
4227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (err)
4237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return err;
4247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
4267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
4277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_sit_info(struct f2fs_sb_info *sbi)
4297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_sb = F2FS_RAW_SUPER(sbi);
4317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
4327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i;
4337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int sit_segs, start;
4347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	char *src_bitmap, *dst_bitmap;
4357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int bitmap_size;
4367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i = malloc(sizeof(struct sit_info));
4387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sit_i)
4397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
4407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	SM_I(sbi)->sit_info = sit_i;
4427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sentries = calloc(TOTAL_SEGS(sbi) * sizeof(struct seg_entry), 1);
4447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (start = 0; start < TOTAL_SEGS(sbi); start++) {
4467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit_i->sentries[start].cur_valid_map
4477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			= calloc(SIT_VBLOCK_MAP_SIZE, 1);
4487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit_i->sentries[start].ckpt_valid_map
4497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			= calloc(SIT_VBLOCK_MAP_SIZE, 1);
4507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (!sit_i->sentries[start].cur_valid_map
4517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				|| !sit_i->sentries[start].ckpt_valid_map)
4527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return -ENOMEM;
4537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
4547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_segs = le32_to_cpu(raw_sb->segment_count_sit) >> 1;
4567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	bitmap_size = __bitmap_size(sbi, SIT_BITMAP);
4577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	src_bitmap = __bitmap_ptr(sbi, SIT_BITMAP);
4587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	dst_bitmap = malloc(bitmap_size);
4607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(dst_bitmap, src_bitmap, bitmap_size);
4617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sit_base_addr = le32_to_cpu(raw_sb->sit_blkaddr);
4637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sit_blocks = sit_segs << sbi->log_blocks_per_seg;
4647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->written_valid_blocks = le64_to_cpu(ckpt->valid_block_count);
4657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sit_bitmap = dst_bitmap;
4667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->bitmap_size = bitmap_size;
4677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->dirty_sentries = 0;
4687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->sents_per_block = SIT_ENTRY_PER_BLOCK;
4697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sit_i->elapsed_time = le64_to_cpu(ckpt->elapsed_time);
4707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
4717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
4727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
4747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg = CURSEG_I(sbi, type);
4767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg->segno = curseg->next_segno;
4787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg->zone = GET_ZONENO_FROM_SEGNO(sbi, curseg->segno);
4797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg->next_blkoff = 0;
4807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg->next_segno = NULL_SEGNO;
4817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
4837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint read_compacted_summaries(struct f2fs_sb_info *sbi)
4857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
4867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
4877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg;
4887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t start;
4897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	char *kaddr;
4907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int i, j, offset;
4917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	start = start_sum_block(sbi);
4937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	kaddr = (char *)malloc(PAGE_SIZE);
4957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	dev_read_block(kaddr, start++);
4967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
4977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
4987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(&curseg->sum_blk->n_nats, kaddr, SUM_JOURNAL_SIZE);
4997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
5017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(&curseg->sum_blk->n_sits, kaddr + SUM_JOURNAL_SIZE, SUM_JOURNAL_SIZE);
5027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	offset = 2 * SUM_JOURNAL_SIZE;
5047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
5057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		unsigned short blk_off;
5067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		unsigned int segno;
5077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		curseg = CURSEG_I(sbi, i);
5097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		segno = le32_to_cpu(ckpt->cur_data_segno[i]);
5107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		blk_off = le16_to_cpu(ckpt->cur_data_blkoff[i]);
5117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		curseg->next_segno = segno;
5127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		reset_curseg(sbi, i, 0);
5137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		curseg->alloc_type = ckpt->alloc_type[i];
5147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		curseg->next_blkoff = blk_off;
5157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (curseg->alloc_type == SSR)
5177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_off = sbi->blocks_per_seg;
5187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		for (j = 0; j < blk_off; j++) {
5207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			struct f2fs_summary *s;
5217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			s = (struct f2fs_summary *)(kaddr + offset);
5227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			curseg->sum_blk->entries[j] = *s;
5237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			offset += SUMMARY_SIZE;
5247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if (offset + SUMMARY_SIZE <= PAGE_CACHE_SIZE - SUM_FOOTER_SIZE)
5257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				continue;
5267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			memset(kaddr, 0, PAGE_SIZE);
5277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			dev_read_block(kaddr, start++);
5287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			offset = 0;
5297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
5307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
5317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(kaddr);
5337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
5347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
5357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint restore_node_summary(struct f2fs_sb_info *sbi,
5377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		unsigned int segno, struct f2fs_summary_block *sum_blk)
5387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
5397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_node *node_blk;
5407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary *sum_entry;
5417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	void *page;
5427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t addr;
5437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int i;
5447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	page = malloc(PAGE_SIZE);
5467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!page)
5477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
5487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* scan the node segment */
5507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	addr = START_BLOCK(sbi, segno);
5517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sum_entry = &sum_blk->entries[0];
5527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < sbi->blocks_per_seg; i++, sum_entry++) {
5547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (dev_read_block(page, addr))
5557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			goto out;
5567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		node_blk = (struct f2fs_node *)page;
5587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sum_entry->nid = node_blk->footer.nid;
5597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		/* do not change original value */
5607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee#if 0
5617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sum_entry->version = 0;
5627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sum_entry->ofs_in_node = 0;
5637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee#endif
5647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		addr++;
5657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
5677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeout:
5687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(page);
5697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
5707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
5717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint read_normal_summaries(struct f2fs_sb_info *sbi, int type)
5737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
5747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
5757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum_blk;
5767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg;
5777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned short blk_off;
5787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int segno = 0;
5797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t blk_addr = 0;
5807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (IS_DATASEG(type)) {
5827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		segno = le32_to_cpu(ckpt->cur_data_segno[type]);
5837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - CURSEG_HOT_DATA]);
5847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
5867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
5877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		else
5887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
5897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	} else {
5907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		segno = le32_to_cpu(ckpt->cur_node_segno[type - CURSEG_HOT_NODE]);
5917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		blk_off = le16_to_cpu(ckpt->cur_node_blkoff[type - CURSEG_HOT_NODE]);
5927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG))
5947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_addr = sum_blk_addr(sbi, NR_CURSEG_NODE_TYPE, type - CURSEG_HOT_NODE);
5957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		else
5967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			blk_addr = GET_SUM_BLKADDR(sbi, segno);
5977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
5987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
5997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sum_blk = (struct f2fs_summary_block *)malloc(PAGE_SIZE);
6007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	dev_read_block(sum_blk, blk_addr);
6017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (IS_NODESEG(type)) {
6037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (is_set_ckpt_flags(ckpt, CP_UMOUNT_FLAG)) {
6047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			struct f2fs_summary *sum_entry = &sum_blk->entries[0];
6057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			int i;
6067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			for (i = 0; i < sbi->blocks_per_seg; i++, sum_entry++) {
6077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				/* do not change original value */
6087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee#if 0
6097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				sum_entry->version = 0;
6107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				sum_entry->ofs_in_node = 0;
6117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee#endif
6127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
6137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		} else {
6147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if (restore_node_summary(sbi, segno, sum_blk)) {
6157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				free(sum_blk);
6167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				return -EINVAL;
6177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
6187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
6197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
6207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg = CURSEG_I(sbi, type);
6227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(curseg->sum_blk, sum_blk, PAGE_CACHE_SIZE);
6237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg->next_segno = segno;
6247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	reset_curseg(sbi, type, 0);
6257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg->alloc_type = ckpt->alloc_type[type];
6267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	curseg->next_blkoff = blk_off;
6277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sum_blk);
6287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
6307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint restore_curseg_summaries(struct f2fs_sb_info *sbi)
6337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int type = CURSEG_HOT_DATA;
6357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (is_set_ckpt_flags(F2FS_CKPT(sbi), CP_COMPACT_SUM_FLAG)) {
6377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (read_compacted_summaries(sbi))
6387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return -EINVAL;
6397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		type = CURSEG_HOT_NODE;
6407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
6417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (; type <= CURSEG_COLD_NODE; type++) {
6437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (read_normal_summaries(sbi, type))
6447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return -EINVAL;
6457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
6467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
6477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_curseg(struct f2fs_sb_info *sbi)
6507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *array;
6527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int i;
6537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	array = malloc(sizeof(*array) * NR_CURSEG_TYPE);
6557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	SM_I(sbi)->curseg_array = array;
6577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < NR_CURSEG_TYPE; i++) {
6597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		array[i].sum_blk = malloc(PAGE_CACHE_SIZE);
6607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (!array[i].sum_blk)
6617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return -ENOMEM;
6627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		array[i].segno = NULL_SEGNO;
6637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		array[i].next_blkoff = 0;
6647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
6657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return restore_curseg_summaries(sbi);
6667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeinline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
6697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int end_segno = SM_I(sbi)->segment_count - 1;
6717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(segno <= end_segno);
6727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leestruct f2fs_sit_block *get_current_sit_page(struct f2fs_sb_info *sbi, unsigned int segno)
6757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
6777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int offset = SIT_BLOCK_OFFSET(sit_i, segno);
6787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_t blk_addr = sit_i->sit_base_addr + offset;
6797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sit_block *sit_blk = calloc(BLOCK_SZ, 1);
6807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	check_seg_range(sbi, segno);
6827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* calculate sit block address */
6847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_test_bit(offset, sit_i->sit_bitmap))
6857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		blk_addr += sit_i->sit_blocks;
6867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	dev_read_block(sit_blk, blk_addr);
6887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return sit_blk;
6907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
6917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
6927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid check_block_count(struct f2fs_sb_info *sbi,
6937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		int segno, struct f2fs_sit_entry *raw_sit)
6947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
6957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_info = SM_I(sbi);
6967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int end_segno = sm_info->segment_count - 1;
6977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int valid_blocks = 0;
6987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int i;
6997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* check segment usage */
7017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(GET_SIT_VBLOCKS(raw_sit) <= sbi->blocks_per_seg);
7027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* check boundary of a given segment number */
7047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(segno <= end_segno);
7057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* check bitmap with valid block count */
7077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < sbi->blocks_per_seg; i++)
7087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (f2fs_test_bit(i, (char *)raw_sit->valid_map))
7097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			valid_blocks++;
7107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(GET_SIT_VBLOCKS(raw_sit) == valid_blocks);
7117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid seg_info_from_raw_sit(struct seg_entry *se,
7147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct f2fs_sit_entry *raw_sit)
7157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->valid_blocks = GET_SIT_VBLOCKS(raw_sit);
7177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->ckpt_valid_blocks = GET_SIT_VBLOCKS(raw_sit);
7187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(se->cur_valid_map, raw_sit->valid_map, SIT_VBLOCK_MAP_SIZE);
7197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(se->ckpt_valid_map, raw_sit->valid_map, SIT_VBLOCK_MAP_SIZE);
7207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->type = GET_SIT_TYPE(raw_sit);
7217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	se->mtime = le64_to_cpu(raw_sit->mtime);
7227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leestruct seg_entry *get_seg_entry(struct f2fs_sb_info *sbi,
7257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		unsigned int segno)
7267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
7287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return &sit_i->sentries[segno];
7297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint get_sum_block(struct f2fs_sb_info *sbi, unsigned int segno, struct f2fs_summary_block *sum_blk)
7327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
7347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg;
7357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int type, ret;
7367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u64 ssa_blk;
7377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ssa_blk = GET_SUM_BLKADDR(sbi, segno);
7397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (type = 0; type < NR_CURSEG_NODE_TYPE; type++) {
7407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (segno == ckpt->cur_node_segno[type]) {
7417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			curseg = CURSEG_I(sbi, type);
7427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
7437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return SEG_TYPE_CUR_NODE; /* current node seg was not stored */
7447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
7457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
7467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (type = 0; type < NR_CURSEG_DATA_TYPE; type++) {
7487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (segno == ckpt->cur_data_segno[type]) {
7497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			curseg = CURSEG_I(sbi, type);
7507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			memcpy(sum_blk, curseg->sum_blk, BLOCK_SZ);
7517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			ASSERT(!IS_SUM_NODE_SEG(sum_blk->footer));
7527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			DBG(2, "segno [0x%x] is current data seg[0x%x]\n", segno, type);
7537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return SEG_TYPE_CUR_DATA; /* current data seg was not stored */
7547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
7557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
7567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = dev_read_block(sum_blk, ssa_blk);
7587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(ret >= 0);
7597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (IS_SUM_NODE_SEG(sum_blk->footer))
7617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return SEG_TYPE_NODE;
7627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	else
7637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return SEG_TYPE_DATA;
7647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint get_sum_entry(struct f2fs_sb_info *sbi, u32 blk_addr, struct f2fs_summary *sum_entry)
7687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum_blk;
7707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 segno, offset;
7717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret;
7727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	segno = GET_SEGNO(sbi, blk_addr);
7747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	offset = OFFSET_IN_SEG(sbi, blk_addr);
7757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sum_blk = calloc(BLOCK_SZ, 1);
7777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = get_sum_block(sbi, segno, sum_blk);
7797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(sum_entry, &(sum_blk->entries[offset]), sizeof(struct f2fs_summary));
7817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sum_blk);
7837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return ret;
7847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
7857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint get_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, struct f2fs_nat_entry *raw_nat)
7877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
7887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
7897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
7907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nat_block *nat_block;
7917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_off;
7927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_addr;
7937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int seg_off, entry_off;
7947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret;
7957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
7968843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee	if ((nid / NAT_ENTRY_PER_BLOCK) > fsck->nr_nat_entries) {
7978843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee		DBG(0, "nid is over max nid\n");
7987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -EINVAL;
7997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
8007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (lookup_nat_in_journal(sbi, nid, raw_nat) >= 0)
8027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return 0;
8037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
8057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_off = nid / NAT_ENTRY_PER_BLOCK;
8077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	entry_off = nid % NAT_ENTRY_PER_BLOCK;
8087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	seg_off = block_off >> sbi->log_blocks_per_seg;
8107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	block_addr = (pgoff_t)(nm_i->nat_blkaddr +
8117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			(seg_off << sbi->log_blocks_per_seg << 1) +
8127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
8137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
8157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		block_addr += sbi->blocks_per_seg;
8167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = dev_read_block(nat_block, block_addr);
8187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(ret >= 0);
8197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	memcpy(raw_nat, &nat_block->entries[entry_off], sizeof(struct f2fs_nat_entry));
8217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(nat_block);
8227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
8247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint get_node_info(struct f2fs_sb_info *sbi, nid_t nid, struct node_info *ni)
8277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nat_entry raw_nat;
8297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret;
8307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = get_nat_entry(sbi, nid, &raw_nat);
8327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ni->nid = nid;
8337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	node_info_from_raw_nat(ni, &raw_nat);
8347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return ret;
8357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid build_sit_entries(struct f2fs_sb_info *sbi)
8387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
8407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
8417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum = curseg->sum_blk;
8427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	unsigned int segno;
8437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (segno = 0; segno < TOTAL_SEGS(sbi); segno++) {
8457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct seg_entry *se = &sit_i->sentries[segno];
8467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct f2fs_sit_block *sit_blk;
8477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		struct f2fs_sit_entry sit;
8487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		int i;
8497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		for (i = 0; i < sits_in_cursum(sum); i++) {
8517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if (le32_to_cpu(segno_in_journal(sum, i)) == segno) {
8527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				sit = sit_in_journal(sum, i);
8537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				goto got_it;
8547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
8557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
8567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit_blk = get_current_sit_page(sbi, segno);
8577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, segno)];
8587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sit_blk);
8597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leegot_it:
8607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		check_block_count(sbi, segno, &sit);
8617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		seg_info_from_raw_sit(se, &sit);
8627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
8637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_segment_manager(struct f2fs_sb_info *sbi)
8677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
8697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
8707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_info;
8717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info = malloc(sizeof(struct f2fs_sm_info));
8737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (!sm_info)
8747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -ENOMEM;
8757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* init sm info */
8777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->sm_info = sm_info;
8787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->seg0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
8797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->main_blkaddr = le32_to_cpu(raw_super->main_blkaddr);
8807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->segment_count = le32_to_cpu(raw_super->segment_count);
8817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
8827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
8837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->main_segments = le32_to_cpu(raw_super->segment_count_main);
8847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
8857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	build_sit_info(sbi);
8877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	build_curseg(sbi);
8897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	build_sit_entries(sbi);
8917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
8937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
8947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
8957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint build_sit_area_bitmap(struct f2fs_sb_info *sbi)
8967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
8977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
8987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_i = SM_I(sbi);
8997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int segno = 0, j = 0;
9007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	char *ptr = NULL;
9017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 sum_vblocks = 0;
9037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 free_segs = 0;
9047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 vblocks = 0;
9057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct seg_entry *se;
9077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->sit_area_bitmap_sz = sm_i->main_segments * SIT_VBLOCK_MAP_SIZE;
9097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->sit_area_bitmap = calloc(1, fsck->sit_area_bitmap_sz);
9107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ptr = fsck->sit_area_bitmap;
9117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(fsck->sit_area_bitmap_sz == fsck->main_area_bitmap_sz);
9137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (segno = 0; segno < sm_i->main_segments; segno++) {
9157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		se = get_seg_entry(sbi, segno);
9167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		memcpy(ptr, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE);
9187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ptr += SIT_VBLOCK_MAP_SIZE;
9197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		vblocks = 0;
9217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		for (j = 0; j < SIT_VBLOCK_MAP_SIZE; j++) {
9227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			vblocks += get_bits_in_byte(se->cur_valid_map[j]);
9237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
9247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ASSERT(vblocks == se->valid_blocks);
9257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (se->valid_blocks == 0x0) {
9277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if (sbi->ckpt->cur_node_segno[0] == segno ||
9297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_data_segno[0] == segno ||
9307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_node_segno[1] == segno ||
9317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_data_segno[1] == segno ||
9327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_node_segno[2] == segno ||
9337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					sbi->ckpt->cur_data_segno[2] == segno) {
9347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				continue;
9357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			} else {
9367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				free_segs++;
9377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
9387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		} else {
9407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			ASSERT(se->valid_blocks <= 512);
9417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			sum_vblocks += se->valid_blocks;
9427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
9437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
9447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->chk.sit_valid_blocks = sum_vblocks;
9467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->chk.sit_free_segs = free_segs;
9477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
948223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee	DBG(1, "Blocks [0x%x : %d] Free Segs [0x%x : %d]\n\n", sum_vblocks, sum_vblocks,
949223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee			free_segs, free_segs);
9507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return 0;
9517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
9527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid, struct f2fs_nat_entry *raw_nat)
9547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
9557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
9567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_summary_block *sum = curseg->sum_blk;
9577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int i = 0;
9587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < nats_in_cursum(sum); i++) {
9607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (le32_to_cpu(nid_in_journal(sum, i)) == nid) {
9617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			memcpy(raw_nat, &nat_in_journal(sum, i), sizeof(struct f2fs_nat_entry));
9627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			DBG(3, "==> Found nid [0x%x] in nat cache\n", nid);
9637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return i;
9647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
9657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
9667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return -1;
9677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
9687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid build_nat_area_bitmap(struct f2fs_sb_info *sbi)
9707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
9717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
9727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_super_block *raw_sb = F2FS_RAW_SUPER(sbi);
9737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
9747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nat_block *nat_block;
9757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	u32 nid, nr_nat_blks;
9767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_off;
9787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	pgoff_t block_addr;
9797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int seg_off;
9807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret, i;
9817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nat_block = (struct f2fs_nat_block *)calloc(BLOCK_SZ, 1);
9847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* Alloc & build nat entry bitmap */
9867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	nr_nat_blks = (le32_to_cpu(raw_sb->segment_count_nat) / 2) << sbi->log_blocks_per_seg;
9877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->nr_nat_entries = nr_nat_blks * NAT_ENTRY_PER_BLOCK;
9897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->nat_area_bitmap_sz = (fsck->nr_nat_entries + 7) / 8;
9907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	fsck->nat_area_bitmap = calloc(fsck->nat_area_bitmap_sz, 1);
9917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ASSERT(fsck->nat_area_bitmap != NULL);
9927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (block_off = 0; block_off < nr_nat_blks; block_off++) {
9947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
9957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		seg_off = block_off >> sbi->log_blocks_per_seg;
9967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		block_addr = (pgoff_t)(nm_i->nat_blkaddr +
9977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				(seg_off << sbi->log_blocks_per_seg << 1) +
9987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				(block_off & ((1 << sbi->log_blocks_per_seg) - 1)));
9997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (f2fs_test_bit(block_off, nm_i->nat_bitmap))
10017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			block_addr += sbi->blocks_per_seg;
10027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ret = dev_read_block(nat_block, block_addr);
10047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ASSERT(ret >= 0);
10057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		nid = block_off * NAT_ENTRY_PER_BLOCK;
10077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		for (i = 0; i < NAT_ENTRY_PER_BLOCK; i++) {
10087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			struct f2fs_nat_entry raw_nat;
10097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			struct node_info ni;
10107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			ni.nid = nid + i;
10117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if ((nid + i) == F2FS_NODE_INO(sbi) || (nid + i) == F2FS_META_INO(sbi)) {
10137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				ASSERT(nat_block->entries[i].block_addr != 0x0);
10147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				continue;
10157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
10167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			if (lookup_nat_in_journal(sbi, nid + i, &raw_nat) >= 0) {
10187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				node_info_from_raw_nat(&ni, &raw_nat);
10197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				if (ni.blk_addr != 0x0) {
10207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
10217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					fsck->chk.valid_nat_entry_cnt++;
10227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					DBG(3, "nid[0x%x] in nat cache\n", nid + i);
10237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				}
10247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			} else {
10257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				node_info_from_raw_nat(&ni, &nat_block->entries[i]);
10267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				if (ni.blk_addr != 0) {
10277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					ASSERT(nid + i != 0x0);
10287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					DBG(3, "nid[0x%8x] in nat entry [0x%16x] [0x%8x]\n",
10307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee							nid + i,
10317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee							ni.blk_addr,
10327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee							ni.ino);
10337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					f2fs_set_bit(nid + i, fsck->nat_area_bitmap);
10357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee					fsck->chk.valid_nat_entry_cnt++;
10367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee				}
10377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			}
10387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		}
10397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
10407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(nat_block);
10417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
1042223fdf3e00a56cb32fb8c69dc4523ee53ff7731aChangman Lee	DBG(1, "valid nat entries (block_addr != 0x0) [0x%8x : %u]\n",
10437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			fsck->chk.valid_nat_entry_cnt, fsck->chk.valid_nat_entry_cnt);
10447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
10467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint f2fs_do_mount(struct f2fs_sb_info *sbi)
10487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
10497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int ret;
10507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->active_logs = NR_CURSEG_TYPE;
10517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = validate_super_block(sbi, 0);
10527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (ret) {
10537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ret = validate_super_block(sbi, 1);
10547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		if (ret)
10557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee			return -1;
10567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
10577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	print_raw_sb_info(sbi);
10597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	init_sb_info(sbi);
10617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	ret = get_valid_checkpoint(sbi);
10637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (ret) {
10647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("Can't find valid checkpoint\n");
10657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
10667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
10677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (sanity_check_ckpt(sbi)) {
10697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("Checkpoint is polluted\n");
10707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
10717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
10727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	print_ckpt_info(sbi);
10747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_valid_node_count = le32_to_cpu(sbi->ckpt->valid_node_count);
10767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_valid_inode_count = le32_to_cpu(sbi->ckpt->valid_inode_count);
10777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->user_block_count = le64_to_cpu(sbi->ckpt->user_block_count);
10787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->total_valid_block_count = le64_to_cpu(sbi->ckpt->valid_block_count);
10797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->last_valid_block_count = sbi->total_valid_block_count;
10807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	sbi->alloc_valid_block_count = 0;
10817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (build_segment_manager(sbi)) {
10837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("build_segment_manager failed\n");
10847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
10857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
10867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	if (build_node_manager(sbi)) {
10887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		ERR_MSG("build_segment_manager failed\n");
10897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		return -1;
10907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
10917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	return ret;
10937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
10947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
10957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid f2fs_do_umount(struct f2fs_sb_info *sbi)
10967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{
10977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct sit_info *sit_i = SIT_I(sbi);
10987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_sm_info *sm_i = SM_I(sbi);
10997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	struct f2fs_nm_info *nm_i = NM_I(sbi);
11007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	int i;
11017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* free nm_info */
11037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(nm_i->nat_bitmap);
11047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->nm_info);
11057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* free sit_info */
11077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < TOTAL_SEGS(sbi); i++) {
11087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sit_i->sentries[i].cur_valid_map);
11097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sit_i->sentries[i].ckpt_valid_map);
11107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	}
11117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sit_i->sit_bitmap);
11127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sm_i->sit_info);
11137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	/* free sm_info */
11157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	for (i = 0; i < NR_CURSEG_TYPE; i++)
11167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee		free(sm_i->curseg_array[i].sum_blk);
11177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sm_i->curseg_array);
11197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->sm_info);
11207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee
11217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->ckpt);
11227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee	free(sbi->raw_super);
11237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee}
1124