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