17f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee/** 27f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * fsck.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 1357baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Leechar *tree_mark; 143c85e737308ef95629b232745d6a8d141d87cc9aJP Abgralluint32_t tree_mark_size = 256; 1557baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 16f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kimstatic inline int f2fs_set_main_bitmap(struct f2fs_sb_info *sbi, u32 blk, 17f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim int type) 18b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim{ 19b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 20f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim struct seg_entry *se; 21f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim 22f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim se = get_seg_entry(sbi, GET_SEGNO(sbi, blk)); 23f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim if (se->type != type) { 24f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim if (type == CURSEG_WARM_DATA) { 25f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim if (se->type != CURSEG_COLD_DATA) { 267b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim DBG(1, "Wrong segment type [0x%x] %x -> %x", 27f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim GET_SEGNO(sbi, blk), se->type, 28f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim CURSEG_WARM_DATA); 29f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim se->type = CURSEG_WARM_DATA; 30f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim } 31f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim } else { 327b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim DBG(1, "Wrong segment type [0x%x] %x -> %x", 33f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim GET_SEGNO(sbi, blk), se->type, type); 34f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim se->type = type; 35f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim } 36f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim } 37b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim return f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, blk), fsck->main_area_bitmap); 38b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim} 39b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim 40b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimstatic inline int f2fs_test_main_bitmap(struct f2fs_sb_info *sbi, u32 blk) 41b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim{ 42b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 43b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim 44b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim return f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk), 45b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim fsck->main_area_bitmap); 46b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim} 47b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim 48b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimstatic inline int f2fs_test_sit_bitmap(struct f2fs_sb_info *sbi, u32 blk) 49b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim{ 50b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 51b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim 52b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim return f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk), fsck->sit_area_bitmap); 53b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim} 54b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim 55b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimstatic int add_into_hard_link_list(struct f2fs_sb_info *sbi, 56b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim u32 nid, u32 link_cnt) 577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct hard_link_node *node = NULL, *tmp = NULL, *prev = NULL; 607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node = calloc(sizeof(struct hard_link_node), 1); 627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ASSERT(node != NULL); 637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node->nid = nid; 657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node->links = link_cnt; 667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node->next = NULL; 677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (fsck->hard_link_list_head == NULL) { 697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->hard_link_list_head = node; 707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee goto out; 717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee tmp = fsck->hard_link_list_head; 747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* Find insertion position */ 767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee while (tmp && (nid < tmp->nid)) { 777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ASSERT(tmp->nid != nid); 787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee prev = tmp; 797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee tmp = tmp->next; 807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (tmp == fsck->hard_link_list_head) { 837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node->next = tmp; 847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->hard_link_list_head = node; 857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee prev->next = node; 877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node->next = tmp; 887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeout: 917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee DBG(2, "ino[0x%x] has hard links [0x%x]\n", nid, link_cnt); 927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leestatic int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid) 967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct hard_link_node *node = NULL, *prev = NULL; 997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1003b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (fsck->hard_link_list_head == NULL) 1013b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 1027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node = fsck->hard_link_list_head; 1047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee while (node && (nid < node->nid)) { 1067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee prev = node; 1077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node = node->next; 1087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 1097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1103b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (node == NULL || (nid != node->nid)) 1113b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 1127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* Decrease link count */ 1147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node->links = node->links - 1; 1157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* if link count becomes one, remove the node */ 1177f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (node->links == 1) { 1187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (fsck->hard_link_list_head == node) 1197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->hard_link_list_head = node->next; 1207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee else 1217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee prev->next = node->next; 1227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(node); 1237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 1247f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 1257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 1267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 127b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimstatic int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid, 128b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim u32 blk_addr) 1297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 1307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee int ret = 0; 1317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_summary sum_entry; 1327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = get_sum_entry(sbi, blk_addr, &sum_entry); 1347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1356591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim if (ret != SEG_TYPE_NODE && ret != SEG_TYPE_CUR_NODE) { 1366591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim ASSERT_MSG("Summary footer is not for node segment"); 1376591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return -EINVAL; 1386591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim } 1396591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim 1406591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim if (le32_to_cpu(sum_entry.nid) != nid) { 1416591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim DBG(0, "nid [0x%x]\n", nid); 1426591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim DBG(0, "target blk_addr [0x%x]\n", blk_addr); 1436591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim DBG(0, "summary blk_addr [0x%x]\n", 144b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim GET_SUM_BLKADDR(sbi, 1456591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim GET_SEGNO(sbi, blk_addr))); 1466591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim DBG(0, "seg no / offset [0x%x / 0x%x]\n", 147b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim GET_SEGNO(sbi, blk_addr), 1486591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim OFFSET_IN_SEG(sbi, blk_addr)); 1496591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim DBG(0, "summary_entry.nid [0x%x]\n", 150b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le32_to_cpu(sum_entry.nid)); 1516591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim DBG(0, "--> node block's nid [0x%x]\n", nid); 1526591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim ASSERT_MSG("Invalid node seg summary\n"); 1536591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return -EINVAL; 1547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 1556591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return 0; 1567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 1577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leestatic int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr, 1597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u32 parent_nid, u16 idx_in_node, u8 version) 1607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 1617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee int ret = 0; 1627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_summary sum_entry; 1637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = get_sum_entry(sbi, blk_addr, &sum_entry); 1656591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim 1666591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim if (ret != SEG_TYPE_DATA && ret != SEG_TYPE_CUR_DATA) { 1676591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim ASSERT_MSG("Summary footer is not for data segment"); 1686591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return -EINVAL; 1696591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim } 1707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (le32_to_cpu(sum_entry.nid) != parent_nid || 1727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee sum_entry.version != version || 1737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee le16_to_cpu(sum_entry.ofs_in_node) != idx_in_node) { 1747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 175b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim DBG(0, "summary_entry.nid [0x%x]\n", 176b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le32_to_cpu(sum_entry.nid)); 177b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim DBG(0, "summary_entry.version [0x%x]\n", 178b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim sum_entry.version); 179b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim DBG(0, "summary_entry.ofs_in_node [0x%x]\n", 180b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le16_to_cpu(sum_entry.ofs_in_node)); 1817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee DBG(0, "parent nid [0x%x]\n", parent_nid); 1827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee DBG(0, "version from nat [0x%x]\n", version); 1837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee DBG(0, "idx in parent node [0x%x]\n", idx_in_node); 1847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee DBG(0, "Target data block addr [0x%x]\n", blk_addr); 186b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ASSERT_MSG("Invalid data seg summary\n"); 1876591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return -EINVAL; 1887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 1896591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return 0; 1907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 1917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 1923b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kimstatic int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, 1933b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim struct f2fs_node *node_blk, 1943b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim enum FILE_TYPE ftype, enum NODE_TYPE ntype, 1953b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim struct node_info *ni) 1967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 1977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 1983b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim int ret; 1997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 200e9cd4deec85930bed5862c7cd136d2dcc0e02907Jaegeuk Kim if (!IS_VALID_NID(sbi, nid)) { 201b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ASSERT_MSG("nid is not valid. [0x%x]", nid); 2023b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 203e9cd4deec85930bed5862c7cd136d2dcc0e02907Jaegeuk Kim } 2047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 2053b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim get_node_info(sbi, nid, ni); 2063b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (ni->blk_addr == NEW_ADDR) { 2073b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("nid is NEW_ADDR. [0x%x]", nid); 2083b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2093b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 2107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 2113b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (!IS_VALID_BLK_ADDR(sbi, ni->blk_addr)) { 2123b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("blkaddres is not valid. [0x%x]", ni->blk_addr); 2133b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2143b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 2157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 2163b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (is_valid_ssa_node_blk(sbi, nid, ni->blk_addr)) { 2173b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("summary node block is not valid. [0x%x]", nid); 2183b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 2207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 2213b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ret = dev_read_block(node_blk, ni->blk_addr); 2223b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT(ret >= 0); 2233b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 2243b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (ntype == TYPE_INODE && 2253b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim node_blk->footer.nid != node_blk->footer.ino) { 2263b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("nid[0x%x] footer.nid[0x%x] footer.ino[0x%x]", 2273b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim nid, le32_to_cpu(node_blk->footer.nid), 2283b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim le32_to_cpu(node_blk->footer.ino)); 2293b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2303b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 2313b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (ntype != TYPE_INODE && 2323b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim node_blk->footer.nid == node_blk->footer.ino) { 2333b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("nid[0x%x] footer.nid[0x%x] footer.ino[0x%x]", 2343b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim nid, le32_to_cpu(node_blk->footer.nid), 2353b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim le32_to_cpu(node_blk->footer.ino)); 2363b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2373b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 2383b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 2393b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (le32_to_cpu(node_blk->footer.nid) != nid) { 2403b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]", 2413b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim nid, ni->blk_addr, 2423b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim le32_to_cpu(node_blk->footer.nid)); 2433b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2443b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 2453b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 2463b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (ntype == TYPE_XATTR) { 2473b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim u32 flag = le32_to_cpu(node_blk->footer.flag); 2483b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 2493b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if ((flag >> OFFSET_BIT_SHIFT) != XATTR_NODE_OFFSET) { 2503b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("xnid[0x%x] has wrong ofs:[0x%x]", 2513b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim nid, flag); 2523b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2533b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 2543b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 2553b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 2563b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if ((ntype == TYPE_INODE && ftype == F2FS_FT_DIR) || 2573b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim (ntype == TYPE_XATTR && ftype == F2FS_FT_XATTR)) { 2583b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim /* not included '.' & '..' */ 2593b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (f2fs_test_main_bitmap(sbi, ni->blk_addr) != 0) { 2603b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("Duplicated node blk. nid[0x%x][0x%x]\n", 2613b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim nid, ni->blk_addr); 2623b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 2633b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim } 264e9cd4deec85930bed5862c7cd136d2dcc0e02907Jaegeuk Kim } 2657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 2663b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim /* workaround to fix later */ 2673b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (ftype != F2FS_FT_ORPHAN || 2683b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0) 2693b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim f2fs_clear_bit(nid, fsck->nat_area_bitmap); 2703b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim else 2713b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("orphan or xattr nid is duplicated [0x%x]\n", 2723b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim nid); 2737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 2743b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (f2fs_test_sit_bitmap(sbi, ni->blk_addr) == 0) 2753b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]", 2763b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ni->blk_addr); 2777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 2783b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) { 2797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->chk.valid_blk_cnt++; 2807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->chk.valid_node_cnt++; 2817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 2823b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return 0; 2833b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim} 2843b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 2851118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kimstatic int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, 2861118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim u32 x_nid, u32 *blk_cnt) 2871118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim{ 2881118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim struct f2fs_node *node_blk = NULL; 2891118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim struct node_info ni; 2901118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim int ret = 0; 2911118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim 2921118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim if (x_nid == 0x0) 2931118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim return 0; 2941118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim 2951118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1); 2961118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim ASSERT(node_blk != NULL); 2971118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim 2981118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim /* Sanity check */ 2991118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim if (sanity_check_nid(sbi, x_nid, node_blk, 3001118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim F2FS_FT_XATTR, TYPE_XATTR, &ni)) { 3011118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim ret = -EINVAL; 3021118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim goto out; 3031118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim } 3041118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim 3051118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim *blk_cnt = *blk_cnt + 1; 306f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, ni.blk_addr, CURSEG_COLD_NODE); 3071118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid); 3081118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kimout: 3091118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim free(node_blk); 3101118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim return ret; 3111118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim} 3121118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim 3133b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kimint fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, 3143b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim u32 nid, enum FILE_TYPE ftype, enum NODE_TYPE ntype, 3153b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim u32 *blk_cnt) 3163b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim{ 3173b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim struct node_info ni; 3183b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim struct f2fs_node *node_blk = NULL; 3197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 3207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1); 3217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ASSERT(node_blk != NULL); 3227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 3233b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (sanity_check_nid(sbi, nid, node_blk, ftype, ntype, &ni)) 3243b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim goto err; 3257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 3267f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (ntype == TYPE_INODE) { 3273b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim fsck_chk_inode_blk(sbi, nid, ftype, node_blk, blk_cnt, &ni); 3287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 3297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee switch (ntype) { 3307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee case TYPE_DIRECT_NODE: 331f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, ni.blk_addr, 332f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim CURSEG_WARM_NODE); 3333b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim fsck_chk_dnode_blk(sbi, inode, nid, ftype, node_blk, 3343b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim blk_cnt, &ni); 3357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee break; 3367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee case TYPE_INDIRECT_NODE: 337f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, ni.blk_addr, 338f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim CURSEG_COLD_NODE); 3393b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim fsck_chk_idnode_blk(sbi, inode, ftype, node_blk, 3407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee blk_cnt); 3417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee break; 3427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee case TYPE_DOUBLE_INDIRECT_NODE: 343f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, ni.blk_addr, 344f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim CURSEG_COLD_NODE); 3453b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim fsck_chk_didnode_blk(sbi, inode, ftype, node_blk, 3467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee blk_cnt); 3477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee break; 3487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee default: 3497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ASSERT(0); 3507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 3517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 3527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(node_blk); 3537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 3543b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kimerr: 3553b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim free(node_blk); 3563b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return -EINVAL; 3577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 3587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 3593b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim/* start with valid nid and blkaddr */ 3603b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kimvoid fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid, 3613b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim enum FILE_TYPE ftype, struct f2fs_node *node_blk, 3623b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim u32 *blk_cnt, struct node_info *ni) 3637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 3647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 3657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u32 child_cnt = 0, child_files = 0; 3667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee enum NODE_TYPE ntype; 3677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u32 i_links = le32_to_cpu(node_blk->i.i_links); 36857baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks); 3693c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall unsigned int idx = 0; 370dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim int need_fix = 0; 3713b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim int ret; 3727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 373b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) 3747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->chk.valid_inode_cnt++; 3757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 37676a069430a295a27bf478d4a5d2fd71112a11a54Jaegeuk Kim if (ftype == F2FS_FT_DIR) { 377f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, ni->blk_addr, CURSEG_HOT_NODE); 37876a069430a295a27bf478d4a5d2fd71112a11a54Jaegeuk Kim } else { 379b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) { 380f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, ni->blk_addr, 381f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim CURSEG_WARM_NODE); 3827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (i_links > 1) { 3837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* First time. Create new hard link node */ 3847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee add_into_hard_link_list(sbi, nid, i_links); 3857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->chk.multi_hard_link_files++; 3867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 3877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 3883b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim DBG(3, "[0x%x] has hard links [0x%x]\n", nid, i_links); 3893b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (find_and_dec_hard_link_list(sbi, nid)) { 3903b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("[0x%x] needs more i_links=0x%x", 3917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee nid, i_links); 39273b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim if (config.fix_on) { 393dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim node_blk->i.i_links = 394dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim cpu_to_le32(i_links + 1); 395dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim need_fix = 1; 396269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim FIX_MSG("File: 0x%x " 397269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim "i_links= 0x%x -> 0x%x", 398269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim nid, i_links, i_links + 1); 399dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 400df2501e140764a8b67fc22388985359836760a0bJaegeuk Kim goto check; 4017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 4027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* No need to go deep into the node */ 4033b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return; 4047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 4057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 4067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 4071118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim if (fsck_chk_xattr_blk(sbi, nid, 4081118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt) && 40973b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim config.fix_on) { 4101118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim node_blk->i.i_xattr_nid = 0; 4111118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim need_fix = 1; 4121118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim FIX_MSG("Remove xattr block: 0x%x, x_nid = 0x%x", 4131118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim nid, le32_to_cpu(node_blk->i.i_xattr_nid)); 4141118af29cae53275851c3b1f7ef266e67cc7e2a7Jaegeuk Kim } 4157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 41676a069430a295a27bf478d4a5d2fd71112a11a54Jaegeuk Kim if (ftype == F2FS_FT_CHRDEV || ftype == F2FS_FT_BLKDEV || 41776a069430a295a27bf478d4a5d2fd71112a11a54Jaegeuk Kim ftype == F2FS_FT_FIFO || ftype == F2FS_FT_SOCK) 41878b795e05d411e28f2480f78ad9225bd21e199feJaegeuk Kim goto check; 419e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim 420e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim if((node_blk->i.i_inline & F2FS_INLINE_DATA)) { 421e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim if (le32_to_cpu(node_blk->i.i_addr[0]) != 0) { 422e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim /* should fix this bug all the time */ 423e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim FIX_MSG("inline_data has wrong 0'th block = %x", 424e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim le32_to_cpu(node_blk->i.i_addr[0])); 425e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim node_blk->i.i_addr[0] = 0; 426e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim node_blk->i.i_blocks = cpu_to_le64(*blk_cnt); 427e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim need_fix = 1; 428e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim } 4299464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim if (!(node_blk->i.i_inline & F2FS_DATA_EXIST)) { 4309464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim char buf[MAX_INLINE_DATA]; 4319464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim memset(buf, 0, MAX_INLINE_DATA); 4329464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim 4339464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim if (memcmp(buf, &node_blk->i.i_addr[1], 4349464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim MAX_INLINE_DATA)) { 4359464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim FIX_MSG("inline_data has DATA_EXIST"); 4369464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim node_blk->i.i_inline |= F2FS_DATA_EXIST; 4379464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim need_fix = 1; 4389464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim } 4399464be283ebdbb17c8940bea6c8a4f7acb75299aJaegeuk Kim } 440061ee67915ba3e8c86bde89a2efb1b8a9aadfb37Huajun Li DBG(3, "ino[0x%x] has inline data!\n", nid); 441061ee67915ba3e8c86bde89a2efb1b8a9aadfb37Huajun Li goto check; 442061ee67915ba3e8c86bde89a2efb1b8a9aadfb37Huajun Li } 443e90e81703d3245e14d90fcb1bdb5a6c6cdd6393eJaegeuk Kim if((node_blk->i.i_inline & F2FS_INLINE_DENTRY)) { 4443a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim DBG(3, "ino[0x%x] has inline dentry!\n", nid); 4453a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim ret = fsck_chk_inline_dentries(sbi, node_blk, 4463a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim &child_cnt, &child_files); 447866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim if (ret < 0) { 448866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim /* should fix this bug all the time */ 449866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim need_fix = 1; 450866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim } 4513a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim goto check; 4523a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim } 45378b795e05d411e28f2480f78ad9225bd21e199feJaegeuk Kim 4548bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim /* readahead node blocks */ 4558bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim for (idx = 0; idx < 5; idx++) { 4568bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim u32 nid = le32_to_cpu(node_blk->i.i_nid[idx]); 4578bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim 4588bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim if (nid != 0) { 4598bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim struct node_info ni; 4608bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim 4618bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim get_node_info(sbi, nid, &ni); 4628bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) 4638bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim dev_reada_block(ni.blk_addr); 4648bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim } 4658bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim } 4668bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim 4677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* check data blocks in inode */ 468cd1e4704d0cbf1cbb49b3f33c576566b4b1e296eJaegeuk Kim for (idx = 0; idx < ADDRS_PER_INODE(&node_blk->i); idx++) { 4697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (le32_to_cpu(node_blk->i.i_addr[idx]) != 0) { 4707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = fsck_chk_data_blk(sbi, 4717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee le32_to_cpu(node_blk->i.i_addr[idx]), 472b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim &child_cnt, &child_files, 4737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee (i_blocks == *blk_cnt), 474b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ftype, nid, idx, ni->version); 475dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim if (!ret) { 4763b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim *blk_cnt = *blk_cnt + 1; 47773b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim } else if (config.fix_on) { 478dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim node_blk->i.i_addr[idx] = 0; 479dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim need_fix = 1; 480269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim FIX_MSG("[0x%x] i_addr[%d] = 0", nid, idx); 481dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 4827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 4837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 4847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 4857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* check node blocks in inode */ 4867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee for (idx = 0; idx < 5; idx++) { 4877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (idx == 0 || idx == 1) 4887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ntype = TYPE_DIRECT_NODE; 4897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee else if (idx == 2 || idx == 3) 4907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ntype = TYPE_INDIRECT_NODE; 4917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee else if (idx == 4) 4927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ntype = TYPE_DOUBLE_INDIRECT_NODE; 4937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee else 4947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ASSERT(0); 4957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 4967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (le32_to_cpu(node_blk->i.i_nid[idx]) != 0) { 497b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ret = fsck_chk_node_blk(sbi, &node_blk->i, 4987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee le32_to_cpu(node_blk->i.i_nid[idx]), 499b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ftype, ntype, blk_cnt); 500dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim if (!ret) { 5013b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim *blk_cnt = *blk_cnt + 1; 50273b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim } else if (config.fix_on) { 503dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim node_blk->i.i_nid[idx] = 0; 504dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim need_fix = 1; 505269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim FIX_MSG("[0x%x] i_nid[%d] = 0", nid, idx); 506dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 5077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 5087f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 50978b795e05d411e28f2480f78ad9225bd21e199feJaegeuk Kimcheck: 51076a069430a295a27bf478d4a5d2fd71112a11a54Jaegeuk Kim if (ftype == F2FS_FT_DIR) 511b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim DBG(1, "Directory Inode: 0x%x [%s] depth: %d has %d files\n\n", 512b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le32_to_cpu(node_blk->footer.ino), 513b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim node_blk->i.i_name, 514b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le32_to_cpu(node_blk->i.i_current_depth), 515b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim child_files); 5168e678b2edfba95f3edbb1730c69da365d659e95dJaegeuk Kim if (ftype == F2FS_FT_ORPHAN) 517b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim DBG(1, "Orphan Inode: 0x%x [%s] i_blocks: %u\n\n", 518b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le32_to_cpu(node_blk->footer.ino), 519b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim node_blk->i.i_name, 520192d979c61719dd1a44eb845033e949dcabba3e7Jaegeuk Kim (u32)i_blocks); 521dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim 522dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim if (i_blocks != *blk_cnt) { 523bc6a70006baab16bf51e9cc7a7b042f734d4ccd2Jaegeuk Kim ASSERT_MSG("ino: 0x%x has i_blocks: %08"PRIx64", " 524bc6a70006baab16bf51e9cc7a7b042f734d4ccd2Jaegeuk Kim "but has %u blocks", 525dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim nid, i_blocks, *blk_cnt); 52673b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim if (config.fix_on) { 527dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim node_blk->i.i_blocks = cpu_to_le64(*blk_cnt); 528dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim need_fix = 1; 529bc6a70006baab16bf51e9cc7a7b042f734d4ccd2Jaegeuk Kim FIX_MSG("[0x%x] i_blocks=0x%08"PRIx64" -> 0x%x", 530269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim nid, i_blocks, *blk_cnt); 531dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 532dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 533dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim if (ftype == F2FS_FT_DIR && i_links != child_cnt) { 5343b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("ino: 0x%x has i_links: %u but real links: %u", 535dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim nid, i_links, child_cnt); 53673b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim if (config.fix_on) { 537dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim node_blk->i.i_links = cpu_to_le32(child_cnt); 538dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim need_fix = 1; 539269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim FIX_MSG("Dir: 0x%x i_links= 0x%x -> 0x%x", 540269eac2e0346e92fa1428bbfbc3fa50233f8c4efJaegeuk Kim nid, i_links, child_cnt); 541dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 542dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 543dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim 5443b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (ftype == F2FS_FT_ORPHAN && i_links) 5453b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT_MSG("ino: 0x%x is orphan inode, but has i_links: %u", 546dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim nid, i_links); 547dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim if (need_fix) { 548dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim ret = dev_write_block(node_blk, ni->blk_addr); 549dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim ASSERT(ret >= 0); 550dc530859c5e422b10ab70bc3b9d4b7ff0d004d57Jaegeuk Kim } 5517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 5527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 553b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimint fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, 554b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim u32 nid, enum FILE_TYPE ftype, struct f2fs_node *node_blk, 555b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim u32 *blk_cnt, struct node_info *ni) 5567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 5573b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim int idx, ret; 5587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u32 child_cnt = 0, child_files = 0; 5593e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim int need_fix = 0; 5607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 5617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee for (idx = 0; idx < ADDRS_PER_BLOCK; idx++) { 5627f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (le32_to_cpu(node_blk->dn.addr[idx]) == 0x0) 5637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee continue; 5643b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ret = fsck_chk_data_blk(sbi, 565b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le32_to_cpu(node_blk->dn.addr[idx]), 566b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim &child_cnt, &child_files, 567b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype, 568b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim nid, idx, ni->version); 5693e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim if (!ret) { 5703b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim *blk_cnt = *blk_cnt + 1; 5713e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim } else if (config.fix_on) { 5723e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim node_blk->dn.addr[idx] = 0; 5733e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim need_fix = 1; 5743e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim FIX_MSG("[0x%x] dn.addr[%d] = 0", nid, idx); 5753e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim } 5763e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim } 5773e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim if (need_fix) { 5783e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim ret = dev_write_block(node_blk, ni->blk_addr); 5793e2c7b7ed31829c836958b87656b286d9ddfa10cJaegeuk Kim ASSERT(ret >= 0); 5807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 5817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 5827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 5837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 584b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimint fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, 585b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt) 5867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 5873b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim int ret; 5887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee int i = 0; 5897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 5907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee for (i = 0 ; i < NIDS_PER_BLOCK; i++) { 5917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (le32_to_cpu(node_blk->in.nid[i]) == 0x0) 5927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee continue; 5933b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ret = fsck_chk_node_blk(sbi, inode, 5943b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim le32_to_cpu(node_blk->in.nid[i]), 595b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ftype, TYPE_DIRECT_NODE, blk_cnt); 5963b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (!ret) 5973b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim *blk_cnt = *blk_cnt + 1; 5983b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim else if (ret == -EINVAL) 5993b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim printf("delete in.nid[i] = 0;\n"); 6007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 6017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 6027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 6037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 604b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimint fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, 605b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt) 6067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 6077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee int i = 0; 6083b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim int ret = 0; 6097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 6107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee for (i = 0; i < NIDS_PER_BLOCK; i++) { 6117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (le32_to_cpu(node_blk->in.nid[i]) == 0x0) 6127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee continue; 6133b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ret = fsck_chk_node_blk(sbi, inode, 6147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee le32_to_cpu(node_blk->in.nid[i]), 615b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ftype, TYPE_INDIRECT_NODE, blk_cnt); 6163b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim if (!ret) 6173b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim *blk_cnt = *blk_cnt + 1; 6183b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim else if (ret == -EINVAL) 6193b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim printf("delete in.nid[i] = 0;\n"); 6207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 6217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 6227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 6237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 62457baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Leestatic void print_dentry(__u32 depth, __u8 *name, 6253a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim unsigned long *bitmap, 6263a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim struct f2fs_dir_entry *dentry, 6273a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim int max, int idx, int last_blk) 62857baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee{ 62957baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee int last_de = 0; 63057baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee int next_idx = 0; 63157baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee int name_len; 6323c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall unsigned int i; 63357baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee int bit_offset; 63457baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 63557baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee if (config.dbg_lv != -1) 63657baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee return; 63757baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 6383a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim name_len = le16_to_cpu(dentry[idx].name_len); 63957baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee next_idx = idx + (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; 64057baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 6413a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim bit_offset = find_next_bit(bitmap, max, next_idx); 6423a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim if (bit_offset >= max && last_blk) 64357baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee last_de = 1; 64457baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 64557baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee if (tree_mark_size <= depth) { 64657baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee tree_mark_size *= 2; 64757baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee tree_mark = realloc(tree_mark, tree_mark_size); 64857baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee } 64957baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 65057baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee if (last_de) 65157baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee tree_mark[depth] = '`'; 65257baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee else 65357baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee tree_mark[depth] = '|'; 65457baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 65557baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee if (tree_mark[depth - 1] == '`') 65657baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee tree_mark[depth - 1] = ' '; 65757baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 65857baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 65957baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee for (i = 1; i < depth; i++) 66057baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee printf("%c ", tree_mark[i]); 661ab258b431b634f4980f279db22cbee83271f6f16Jaegeuk Kim printf("%c-- %s 0x%x\n", last_de ? '`' : '|', 6623a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim name, le32_to_cpu(dentry[idx].ino)); 66357baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee} 66457baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 6653a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kimstatic int __chk_dentries(struct f2fs_sb_info *sbi, u32 *child_cnt, 6663a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim u32* child_files, 6673a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim unsigned long *bitmap, 6683a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim struct f2fs_dir_entry *dentry, 6693a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim __u8 (*filenames)[F2FS_SLOT_LEN], 6703a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim int max, int last_blk) 6717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 6727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 6733a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim enum FILE_TYPE ftype; 6747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee int dentries = 0; 6753a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim u32 blk_cnt; 6767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u8 *name; 6778bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim u32 hash_code, ino; 6787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u16 name_len;; 6793a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim int ret = 0; 680866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim int fixed = 0; 6813a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim int i; 6827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 6838bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim /* readahead inode blocks */ 6848bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim for (i = 0; i < max;) { 6858bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim if (test_bit(i, bitmap) == 0) { 6868bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim i++; 6878bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim continue; 6888bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim } 6898bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim ino = le32_to_cpu(dentry[i].ino); 6908bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim 6918bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim if (IS_VALID_NID(sbi, ino)) { 6928bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim struct node_info ni; 6938bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim 6948bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim get_node_info(sbi, ino, &ni); 6958bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim if (IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) 6968bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim dev_reada_block(ni.blk_addr); 6978bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim } 6988bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim name_len = le16_to_cpu(dentry[i].name_len); 6998bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; 7008bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim } 7018bcdc5fdb206196241dc6fc535e6d285d4985201Jaegeuk Kim 7023a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim for (i = 0; i < max;) { 7033a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim if (test_bit(i, bitmap) == 0) { 7047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee i++; 7057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee continue; 7067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 7072c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall if (!IS_VALID_NID(sbi, le32_to_cpu(dentry[i].ino))) { 7082c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall DBG(1, "Bad dentry 0x%x with invalid NID/ino 0x%x", 7092c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall i, le32_to_cpu(dentry[i].ino)); 7102c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall if (config.fix_on) { 7112c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall FIX_MSG("Clear bad dentry 0x%x with bad ino 0x%x", 7122c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall i, le32_to_cpu(dentry[i].ino)); 7132c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall clear_bit(i, bitmap); 7142c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall i++; 715100ea9f321b92fa1e15889ec0ef72b6b8929459dJP Abgrall fixed = 1; 7162c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall continue; 7172c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall } 7182c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall } 7192c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall ftype = dentry[i].file_type; 7202c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall if ((ftype <= F2FS_FT_UNKNOWN || ftype > F2FS_FT_LAST_FILE_TYPE) && config.fix_on) { 7212c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall DBG(1, "Bad dentry 0x%x with unexpected ftype 0x%x", 7222c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall i, ftype); 7232c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall if (config.fix_on) { 7242c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall FIX_MSG("Clear bad dentry 0x%x with bad ftype 0x%x", 7252c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall i, ftype); 7262c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall clear_bit(i, bitmap); 7272c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall i++; 728100ea9f321b92fa1e15889ec0ef72b6b8929459dJP Abgrall fixed = 1; 7292c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall continue; 7302c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall } 7312c82eafaa38922a370545dc56d6210bf94b929e9JP Abgrall } 7323a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim name_len = le16_to_cpu(dentry[i].name_len); 7337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee name = calloc(name_len + 1, 1); 7343a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim memcpy(name, filenames[i], name_len); 735347fe81d8e860d29a254ac066d87c5efe87d717bJaegeuk Kim hash_code = f2fs_dentry_hash((const unsigned char *)name, 736347fe81d8e860d29a254ac066d87c5efe87d717bJaegeuk Kim name_len); 7377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 738866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim /* fix hash_code made by old buggy code */ 739866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim if (le32_to_cpu(dentry[i].hash_code) != hash_code) { 740866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim dentry[i].hash_code = hash_code; 741866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim fixed = 1; 742866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim FIX_MSG("hash_code[%d] of %s", i, name); 743866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim } 7447f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 7457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* Becareful. 'dentry.file_type' is not imode. */ 74676a069430a295a27bf478d4a5d2fd71112a11a54Jaegeuk Kim if (ftype == F2FS_FT_DIR) { 7477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee *child_cnt = *child_cnt + 1; 748b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim if ((name[0] == '.' && name_len == 1) || 749b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim (name[0] == '.' && name[1] == '.' && 750b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim name_len == 2)) { 7517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee i++; 7527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(name); 7537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee continue; 7547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 7557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 7567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 757b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim DBG(1, "[%3u]-[0x%x] name[%s] len[0x%x] ino[0x%x] type[0x%x]\n", 7587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->dentry_depth, i, name, name_len, 7593a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim le32_to_cpu(dentry[i].ino), 7603a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim dentry[i].file_type); 7617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 7623a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim print_dentry(fsck->dentry_depth, name, bitmap, 7630ca82d1b7231fdda4d1062b4a852d2aa53fa8316Jaegeuk Kim dentry, max, i, last_blk); 76457baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 7657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee blk_cnt = 1; 7667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = fsck_chk_node_blk(sbi, 7673a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim NULL, le32_to_cpu(dentry[i].ino), 7683a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim ftype, TYPE_INODE, &blk_cnt); 7697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 77073b6e3eb4e944338edd80b4f27c29b7aa31c76f2Jaegeuk Kim if (ret && config.fix_on) { 7716b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim int j; 7726b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim int slots = (name_len + F2FS_SLOT_LEN - 1) / 7736b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim F2FS_SLOT_LEN; 7746b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim for (j = 0; j < slots; j++) 7753a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim clear_bit(i + j, bitmap); 7766b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim FIX_MSG("Unlink [0x%x] - %s len[0x%x], type[0x%x]", 7773a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim le32_to_cpu(dentry[i].ino), 7786b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim name, name_len, 7793a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim dentry[i].file_type); 7806b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim i += slots; 7816b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim free(name); 78297e299da3a91d8f558f551d452b4149cb6781750JP Abgrall fixed = 1; 7836b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim continue; 7846b20b0d6788b4e7241c3acad1560d8eaad80b319Jaegeuk Kim } 7857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 7860307b93ce2e44e80a1efb279894601ae64ffaf47Jaegeuk Kim i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; 7877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee dentries++; 7887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee *child_files = *child_files + 1; 7897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(name); 7907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 791866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim return fixed ? -1 : dentries; 7923a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim} 7933a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim 7943a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kimint fsck_chk_inline_dentries(struct f2fs_sb_info *sbi, 7953a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim struct f2fs_node *node_blk, u32 *child_cnt, u32 *child_files) 7963a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim{ 7973a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 7983a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim struct f2fs_inline_dentry *de_blk; 7993a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim int dentries; 8003a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim 8013a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim de_blk = inline_data_addr(node_blk); 8023a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim ASSERT(de_blk != NULL); 8033a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim 8043a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim fsck->dentry_depth++; 8053a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim dentries = __chk_dentries(sbi, child_cnt, child_files, 8063a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim (unsigned long *)de_blk->dentry_bitmap, 8073a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim de_blk->dentry, de_blk->filename, 8083a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim NR_INLINE_DENTRY, 1); 809866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim if (dentries < 0) { 810866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim DBG(1, "[%3d] Inline Dentry Block Fixed hash_codes\n\n", 811866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim fsck->dentry_depth); 812866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim } else { 813866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim DBG(1, "[%3d] Inline Dentry Block Done : " 8143a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim "dentries:%d in %d slots (len:%d)\n\n", 8153a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim fsck->dentry_depth, dentries, 8163a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim (int)NR_INLINE_DENTRY, F2FS_NAME_LEN); 817866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim } 8183a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim fsck->dentry_depth--; 819866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim return dentries; 8203a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim} 8213a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim 8223a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kimint fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, u32 blk_addr, 8233a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim u32 *child_cnt, u32 *child_files, int last_blk) 8243a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim{ 8253a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 8263a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim struct f2fs_dentry_block *de_blk; 8273a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim int dentries, ret; 8283a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim 8293a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim de_blk = (struct f2fs_dentry_block *)calloc(BLOCK_SZ, 1); 8303a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim ASSERT(de_blk != NULL); 8313a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim 8323a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim ret = dev_read_block(de_blk, blk_addr); 8333a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim ASSERT(ret >= 0); 8343a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim 8353a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim fsck->dentry_depth++; 8363a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim dentries = __chk_dentries(sbi, child_cnt, child_files, 8373a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim (unsigned long *)de_blk->dentry_bitmap, 8383a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim de_blk->dentry, de_blk->filename, 8393a8c9a69525f75a6c59bee0eb3d882ddc341b3f1Jaegeuk Kim NR_DENTRY_IN_BLOCK, last_blk); 8407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 841866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim if (dentries < 0) { 842866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim ret = dev_write_block(de_blk, blk_addr); 843866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim ASSERT(ret >= 0); 844866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim DBG(1, "[%3d] Dentry Block [0x%x] Fixed hash_codes\n\n", 845866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim fsck->dentry_depth, blk_addr); 846866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim } else { 847866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim DBG(1, "[%3d] Dentry Block [0x%x] Done : " 848b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim "dentries:%d in %d slots (len:%d)\n\n", 849b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim fsck->dentry_depth, blk_addr, dentries, 850b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim NR_DENTRY_IN_BLOCK, F2FS_NAME_LEN); 851866c86a6376598c1e72141de2805ba0f43e6daaaJaegeuk Kim } 8527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->dentry_depth--; 8537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(de_blk); 8547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 8557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 8567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 857b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kimint fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr, 858b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim u32 *child_cnt, u32 *child_files, int last_blk, 859b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim enum FILE_TYPE ftype, u32 parent_nid, u16 idx_in_node, u8 ver) 8607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 8617f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 86278b795e05d411e28f2480f78ad9225bd21e199feJaegeuk Kim 8637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* Is it reserved block? */ 8647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (blk_addr == NEW_ADDR) { 8657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->chk.valid_blk_cnt++; 8667f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 8677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 8687f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 869e9cd4deec85930bed5862c7cd136d2dcc0e02907Jaegeuk Kim if (!IS_VALID_BLK_ADDR(sbi, blk_addr)) { 870e9cd4deec85930bed5862c7cd136d2dcc0e02907Jaegeuk Kim ASSERT_MSG("blkaddres is not valid. [0x%x]", blk_addr); 8716591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return -EINVAL; 872e9cd4deec85930bed5862c7cd136d2dcc0e02907Jaegeuk Kim } 8737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 8746591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim if (is_valid_ssa_data_blk(sbi, blk_addr, parent_nid, 8756591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim idx_in_node, ver)) { 8766591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim ASSERT_MSG("summary data block is not valid. [0x%x]", 8776591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim parent_nid); 8786591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim return -EINVAL; 8796591dadcb05b7787dfa4c703728f773069dece04Jaegeuk Kim } 8807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 881b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim if (f2fs_test_sit_bitmap(sbi, blk_addr) == 0) 882fffeed796a79fa6621d01b0e4c5fa18d9d89cdd7Jaegeuk Kim ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]", blk_addr); 8837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 884b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim if (f2fs_test_main_bitmap(sbi, blk_addr) != 0) 885b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim ASSERT_MSG("Duplicated data [0x%x]. pnid[0x%x] idx[0x%x]", 886b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim blk_addr, parent_nid, idx_in_node); 887b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim 8887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 8897f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->chk.valid_blk_cnt++; 8907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 891f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim if (ftype == F2FS_FT_DIR) { 892f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, blk_addr, CURSEG_HOT_DATA); 8933b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return fsck_chk_dentry_blk(sbi, blk_addr, child_cnt, 894b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim child_files, last_blk); 895f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim } else { 896f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim f2fs_set_main_bitmap(sbi, blk_addr, CURSEG_WARM_DATA); 897f54dd91d065c15b84686a3fde7a096786e368201Jaegeuk Kim } 8987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return 0; 8997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 9007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 9013b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kimvoid fsck_chk_orphan_node(struct f2fs_sb_info *sbi) 9027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 9037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u32 blk_cnt = 0; 9047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee block_t start_blk, orphan_blkaddr, i, j; 9057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_orphan_block *orphan_blk; 906fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); 9077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 908fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee if (!is_set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG)) 9093b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim return; 9103b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 911fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee start_blk = __start_cp_addr(sbi) + 1 + 912fd9816f31e5cd668962f00511d7a91d055d76048Changman Lee le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); 9137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee orphan_blkaddr = __start_sum_addr(sbi) - 1; 9147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee orphan_blk = calloc(BLOCK_SZ, 1); 9157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 9167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee for (i = 0; i < orphan_blkaddr; i++) { 9173b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim int ret = dev_read_block(orphan_blk, start_blk + i); 9183b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim 9193b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT(ret >= 0); 9207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 9217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) { 9227f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee nid_t ino = le32_to_cpu(orphan_blk->ino[j]); 923858c4039c85f7c00c57925902985701b1e083555Jaegeuk Kim DBG(1, "[%3d] ino [0x%x]\n", i, ino); 924a21f461a0f945b081e64d4d47356bca918940af7Jaegeuk Kim if (config.fix_on) { 925fbfd8e3ae04a2f91ce28d0cb26e4e677b3a0076cJaegeuk Kim FIX_MSG("Discard orphan inodes: ino [0x%x]", 926a21f461a0f945b081e64d4d47356bca918940af7Jaegeuk Kim ino); 927a21f461a0f945b081e64d4d47356bca918940af7Jaegeuk Kim continue; 928a21f461a0f945b081e64d4d47356bca918940af7Jaegeuk Kim } 9297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee blk_cnt = 1; 93083e54446710466a0c4493236079184131f0004ceJaegeuk Kim fsck_chk_node_blk(sbi, NULL, ino, 931b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt); 9327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 9337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee memset(orphan_blk, 0, BLOCK_SZ); 9347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 9357f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(orphan_blk); 9367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 9377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 9383b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kimvoid fsck_init(struct f2fs_sb_info *sbi) 9397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 9407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 9417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_sm_info *sm_i = SM_I(sbi); 9427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 9437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee /* 944b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim * We build three bitmap for main/sit/nat so that may check consistency 945b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim * of filesystem. 946b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim * 1. main_area_bitmap will be used to check whether all blocks of main 947b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim * area is used or not. 9487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * 2. nat_area_bitmap has bitmap information of used nid in NAT. 9497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * 3. sit_area_bitmap has bitmap information of used main block. 9507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee * At Last sequence, we compare main_area_bitmap with sit_area_bitmap. 9517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee */ 9527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->nr_main_blks = sm_i->main_segments << sbi->log_blocks_per_seg; 9537f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->main_area_bitmap_sz = (fsck->nr_main_blks + 7) / 8; 9547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee fsck->main_area_bitmap = calloc(fsck->main_area_bitmap_sz, 1); 9557f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ASSERT(fsck->main_area_bitmap != NULL); 9567f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 9577f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee build_nat_area_bitmap(sbi); 9587f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 9597f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee build_sit_area_bitmap(sbi); 9607f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 96157baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee tree_mark = calloc(tree_mark_size, 1); 9623b4b82634489b2f9d367b1f897d51a341208d163Jaegeuk Kim ASSERT(tree_mark != NULL); 9637f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 9647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 965893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kimstatic void fix_nat_entries(struct f2fs_sb_info *sbi) 966893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim{ 967893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 968bc6a70006baab16bf51e9cc7a7b042f734d4ccd2Jaegeuk Kim u32 i; 969893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 970893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim for (i = 0; i < fsck->nr_nat_entries; i++) 971893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim if (f2fs_test_bit(i, fsck->nat_area_bitmap) != 0) 972893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim nullify_nat_entry(sbi, i); 973893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim} 974893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 975893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kimstatic void fix_checkpoint(struct f2fs_sb_info *sbi) 976893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim{ 977893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 978893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim struct f2fs_super_block *raw_sb = sbi->raw_super; 979893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim struct f2fs_checkpoint *ckp = F2FS_CKPT(sbi); 980893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim unsigned long long cp_blk_no; 981bc6a70006baab16bf51e9cc7a7b042f734d4ccd2Jaegeuk Kim u32 i; 982bc6a70006baab16bf51e9cc7a7b042f734d4ccd2Jaegeuk Kim int ret; 983893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim u_int32_t crc = 0; 984893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 985893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ckp->ckpt_flags = cpu_to_le32(CP_UMOUNT_FLAG); 986893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ckp->cp_pack_total_block_count = 987893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim cpu_to_le32(8 + le32_to_cpu(raw_sb->cp_payload)); 988893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ckp->cp_pack_start_sum = cpu_to_le32(1 + 989893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim le32_to_cpu(raw_sb->cp_payload)); 990893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 991893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ckp->free_segment_count = cpu_to_le32(fsck->chk.free_segs); 992893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ckp->valid_block_count = cpu_to_le32(fsck->chk.valid_blk_cnt); 993893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ckp->valid_node_count = cpu_to_le32(fsck->chk.valid_node_cnt); 994893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ckp->valid_inode_count = cpu_to_le32(fsck->chk.valid_inode_cnt); 995893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 996893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, ckp, CHECKSUM_OFFSET); 997893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim *((__le32 *)((unsigned char *)ckp + CHECKSUM_OFFSET)) = 998893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim cpu_to_le32(crc); 999893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1000893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim cp_blk_no = le32_to_cpu(raw_sb->cp_blkaddr); 1001893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim if (sbi->cur_cp == 2) 1002893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim cp_blk_no += 1 << le32_to_cpu(raw_sb->log_blocks_per_seg); 1003893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1004893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ret = dev_write_block(ckp, cp_blk_no++); 1005893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ASSERT(ret >= 0); 1006893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1007893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim for (i = 0; i < le32_to_cpu(raw_sb->cp_payload); i++) { 1008893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ret = dev_write_block(((unsigned char *)ckp) + i * F2FS_BLKSIZE, 1009893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim cp_blk_no++); 1010893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ASSERT(ret >= 0); 1011893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim } 1012893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1013893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim for (i = 0; i < NO_CHECK_TYPE; i++) { 1014893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim struct curseg_info *curseg = CURSEG_I(sbi, i); 1015893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1016893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ret = dev_write_block(curseg->sum_blk, cp_blk_no++); 1017893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ASSERT(ret >= 0); 1018893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim } 1019893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1020893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ret = dev_write_block(ckp, cp_blk_no++); 1021893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ASSERT(ret >= 0); 1022893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim} 1023893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 102410d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kimint check_curseg_offset(struct f2fs_sb_info *sbi) 102510d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim{ 102610d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim int i; 102710d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim 102810d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim for (i = 0; i < NO_CHECK_TYPE; i++) { 102910d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim struct curseg_info *curseg = CURSEG_I(sbi, i); 103010d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim struct seg_entry *se; 103110d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim 103210d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim se = get_seg_entry(sbi, curseg->segno); 103310d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim if (f2fs_test_bit(curseg->next_blkoff, 103410d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim (const char *)se->cur_valid_map) == 1) { 103510d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim ASSERT_MSG("Next block offset is not free, type:%d", i); 103610d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim return -EINVAL; 103710d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim } 103810d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim } 103910d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim return 0; 104010d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim} 104110d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim 10427b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kimint check_sit_types(struct f2fs_sb_info *sbi) 10437b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim{ 10447b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim unsigned int i; 10457b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim int err = 0; 10467b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim 10477b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim for (i = 0; i < TOTAL_SEGS(sbi); i++) { 10487b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim struct seg_entry *se; 10497b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim 10507b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim se = get_seg_entry(sbi, i); 10517b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim if (se->orig_type != se->type) { 10521e69ed2c8a4164968f853a28a8ae54afefaaae4cJaegeuk Kim if (se->orig_type == CURSEG_COLD_DATA) { 10531e69ed2c8a4164968f853a28a8ae54afefaaae4cJaegeuk Kim se->type = se->orig_type; 10541e69ed2c8a4164968f853a28a8ae54afefaaae4cJaegeuk Kim } else { 10551e69ed2c8a4164968f853a28a8ae54afefaaae4cJaegeuk Kim FIX_MSG("Wrong segment type [0x%x] %x -> %x", 10561e69ed2c8a4164968f853a28a8ae54afefaaae4cJaegeuk Kim i, se->orig_type, se->type); 10571e69ed2c8a4164968f853a28a8ae54afefaaae4cJaegeuk Kim err = -EINVAL; 10581e69ed2c8a4164968f853a28a8ae54afefaaae4cJaegeuk Kim } 10597b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim } 10607b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim } 10617b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim return err; 10627b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim} 10637b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim 10647f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leeint fsck_verify(struct f2fs_sb_info *sbi) 10657f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 10663c85e737308ef95629b232745d6a8d141d87cc9aJP Abgrall unsigned int i = 0; 10677f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee int ret = 0; 1068f3b55c8ff22bfd7bfb5588637d08804aca9ac148Jaegeuk Kim int force = 0; 10697f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee u32 nr_unref_nid = 0; 10707f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 10717f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct hard_link_node *node = NULL; 10727f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 10737f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("\n"); 10747f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 10757f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee for (i = 0; i < fsck->nr_nat_entries; i++) { 10767f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (f2fs_test_bit(i, fsck->nat_area_bitmap) != 0) { 10777f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("NID[0x%x] is unreachable\n", i); 10787f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee nr_unref_nid++; 10797f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 10807f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 10817f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 10827f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (fsck->hard_link_list_head != NULL) { 10837f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node = fsck->hard_link_list_head; 10847f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee while (node) { 10857f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("NID[0x%x] has [0x%x] more unreachable links\n", 10867f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node->nid, node->links); 10877f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee node = node->next; 10887f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 1089f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 10907f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 10917f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 10927f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[FSCK] Unreachable nat entries "); 10937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (nr_unref_nid == 0x0) { 10947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Ok..] [0x%x]\n", nr_unref_nid); 10957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 10967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Fail] [0x%x]\n", nr_unref_nid); 10977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = EXIT_ERR_CODE; 1098f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 10997f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 11007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 11017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[FSCK] SIT valid block bitmap checking "); 1102b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim if (memcmp(fsck->sit_area_bitmap, fsck->main_area_bitmap, 1103b3a4f9457718eb1aecb85d082f9e6f737ce3af86Jaegeuk Kim fsck->sit_area_bitmap_sz) == 0x0) { 11047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[Ok..]\n"); 11057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 11067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[Fail]\n"); 11077f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = EXIT_ERR_CODE; 1108f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 11097f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 11107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 11117f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[FSCK] Hard link checking for regular file "); 11127f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (fsck->hard_link_list_head == NULL) { 11137f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Ok..] [0x%x]\n", fsck->chk.multi_hard_link_files); 11147f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 11157f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Fail] [0x%x]\n", fsck->chk.multi_hard_link_files); 11167f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = EXIT_ERR_CODE; 1117f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 11187f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 11197f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 11207f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[FSCK] valid_block_count matching with CP "); 11217f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (sbi->total_valid_block_count == fsck->chk.valid_blk_cnt) { 1122192d979c61719dd1a44eb845033e949dcabba3e7Jaegeuk Kim printf(" [Ok..] [0x%x]\n", (u32)fsck->chk.valid_blk_cnt); 11237f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 1124192d979c61719dd1a44eb845033e949dcabba3e7Jaegeuk Kim printf(" [Fail] [0x%x]\n", (u32)fsck->chk.valid_blk_cnt); 11257f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = EXIT_ERR_CODE; 1126f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 11277f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 11287f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 11297f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[FSCK] valid_node_count matcing with CP (de lookup) "); 11307f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (sbi->total_valid_node_count == fsck->chk.valid_node_cnt) { 11317f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Ok..] [0x%x]\n", fsck->chk.valid_node_cnt); 11327f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 11337f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Fail] [0x%x]\n", fsck->chk.valid_node_cnt); 11347f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = EXIT_ERR_CODE; 1135f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 11367f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 11377f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 11387f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[FSCK] valid_node_count matcing with CP (nat lookup) "); 11397f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (sbi->total_valid_node_count == fsck->chk.valid_nat_entry_cnt) { 11407f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Ok..] [0x%x]\n", fsck->chk.valid_nat_entry_cnt); 11417f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 11427f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Fail] [0x%x]\n", fsck->chk.valid_nat_entry_cnt); 11437f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = EXIT_ERR_CODE; 1144f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 11457f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 11467f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 11477f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf("[FSCK] valid_inode_count matched with CP "); 11487f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (sbi->total_valid_inode_count == fsck->chk.valid_inode_cnt) { 11497f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Ok..] [0x%x]\n", fsck->chk.valid_inode_cnt); 11507f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } else { 11517f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee printf(" [Fail] [0x%x]\n", fsck->chk.valid_inode_cnt); 11527f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee ret = EXIT_ERR_CODE; 1153f4ef4a14e978e7328037b43a8a6ec9d2a2d4bb5aJaegeuk Kim config.bug_on = 1; 11547f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee } 1155893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1156893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim printf("[FSCK] free segment_count matched with CP "); 1157893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim if (le32_to_cpu(F2FS_CKPT(sbi)->free_segment_count) == 1158893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim fsck->chk.sit_free_segs) { 1159893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim printf(" [Ok..] [0x%x]\n", fsck->chk.sit_free_segs); 1160893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim } else { 1161893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim printf(" [Fail] [0x%x]\n", fsck->chk.sit_free_segs); 1162893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ret = EXIT_ERR_CODE; 1163893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim config.bug_on = 1; 1164893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim } 1165893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 116610d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim printf("[FSCK] next block offset is free "); 116710d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim if (check_curseg_offset(sbi) == 0) { 116810d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim printf(" [Ok..]\n"); 116910d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim } else { 117010d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim printf(" [Fail]\n"); 117110d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim ret = EXIT_ERR_CODE; 117210d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim config.bug_on = 1; 117310d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim } 117410d97dd1b386abcceec1b1bf590a3711d93e8c1cJaegeuk Kim 1175f3b55c8ff22bfd7bfb5588637d08804aca9ac148Jaegeuk Kim printf("[FSCK] fixing SIT types\n"); 1176f3b55c8ff22bfd7bfb5588637d08804aca9ac148Jaegeuk Kim if (check_sit_types(sbi) != 0) 1177f3b55c8ff22bfd7bfb5588637d08804aca9ac148Jaegeuk Kim force = 1; 11787b5d1181a4663c9a55658791de6c04c30e52602aJaegeuk Kim 1179893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim printf("[FSCK] other corrupted bugs "); 1180893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim if (config.bug_on == 0) { 1181893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim printf(" [Ok..]\n"); 1182893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim } else { 1183893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim printf(" [Fail]\n"); 1184893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim ret = EXIT_ERR_CODE; 1185893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim } 1186893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim 1187893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim /* fix global metadata */ 1188f3b55c8ff22bfd7bfb5588637d08804aca9ac148Jaegeuk Kim if (force || (config.bug_on && config.fix_on)) { 1189893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim fix_nat_entries(sbi); 1190893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim rewrite_sit_area_bitmap(sbi); 1191893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim fix_checkpoint(sbi); 1192893312ced238b9ee93c5427aa6e6c1f29fe39899Jaegeuk Kim } 11937f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee return ret; 11947f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 11957f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 11967f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Leevoid fsck_free(struct f2fs_sb_info *sbi) 11977f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee{ 11987f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 11998843554c8c43e713e2ce4e36ac3c06f9eca94b09Changman Lee if (fsck->main_area_bitmap) 12007f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(fsck->main_area_bitmap); 12017f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 12027f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (fsck->nat_area_bitmap) 12037f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(fsck->nat_area_bitmap); 12047f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee 12057f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee if (fsck->sit_area_bitmap) 12067f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee free(fsck->sit_area_bitmap); 120757baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee 120857baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee if (tree_mark) 120957baa23a3279a4b9e9df0ab92ee20a2c79b839d8Changman Lee free(tree_mark); 12107f35b548d4b0e3c8577ad7a09433e589a0ab3f2aChangman Lee} 1211