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