fsck.c revision 192d979c61719dd1a44eb845033e949dcabba3e7
1/** 2 * fsck.c 3 * 4 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 5 * http://www.samsung.com/ 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11#include "fsck.h" 12 13char *tree_mark; 14int tree_mark_size = 256; 15 16static int add_into_hard_link_list(struct f2fs_sb_info *sbi, u32 nid, u32 link_cnt) 17{ 18 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 19 struct hard_link_node *node = NULL, *tmp = NULL, *prev = NULL; 20 21 node = calloc(sizeof(struct hard_link_node), 1); 22 ASSERT(node != NULL); 23 24 node->nid = nid; 25 node->links = link_cnt; 26 node->next = NULL; 27 28 if (fsck->hard_link_list_head == NULL) { 29 fsck->hard_link_list_head = node; 30 goto out; 31 } 32 33 tmp = fsck->hard_link_list_head; 34 35 /* Find insertion position */ 36 while (tmp && (nid < tmp->nid)) { 37 ASSERT(tmp->nid != nid); 38 prev = tmp; 39 tmp = tmp->next; 40 } 41 42 if (tmp == fsck->hard_link_list_head) { 43 node->next = tmp; 44 fsck->hard_link_list_head = node; 45 } else { 46 prev->next = node; 47 node->next = tmp; 48 } 49 50out: 51 DBG(2, "ino[0x%x] has hard links [0x%x]\n", nid, link_cnt); 52 return 0; 53} 54 55static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid) 56{ 57 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 58 struct hard_link_node *node = NULL, *prev = NULL; 59 60 if (fsck->hard_link_list_head == NULL) { 61 ASSERT(0); 62 return -1; 63 } 64 65 node = fsck->hard_link_list_head; 66 67 while (node && (nid < node->nid)) { 68 prev = node; 69 node = node->next; 70 } 71 72 if (node == NULL || (nid != node->nid)) { 73 ASSERT(0); 74 return -1; 75 } 76 77 /* Decrease link count */ 78 node->links = node->links - 1; 79 80 /* if link count becomes one, remove the node */ 81 if (node->links == 1) { 82 if (fsck->hard_link_list_head == node) 83 fsck->hard_link_list_head = node->next; 84 else 85 prev->next = node->next; 86 free(node); 87 } 88 89 return 0; 90 91} 92 93static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid, u32 blk_addr) 94{ 95 int ret = 0; 96 struct f2fs_summary sum_entry; 97 98 ret = get_sum_entry(sbi, blk_addr, &sum_entry); 99 ASSERT(ret >= 0); 100 101 if (ret == SEG_TYPE_DATA || ret == SEG_TYPE_CUR_DATA) { 102 ASSERT_MSG(0, "Summary footer is not a node segment summary\n");; 103 } else if (ret == SEG_TYPE_NODE) { 104 if (le32_to_cpu(sum_entry.nid) != nid) { 105 DBG(0, "nid [0x%x]\n", nid); 106 DBG(0, "target blk_addr [0x%x]\n", blk_addr); 107 DBG(0, "summary blk_addr [0x%x]\n", 108 GET_SUM_BLKADDR(sbi, GET_SEGNO(sbi, blk_addr))); 109 DBG(0, "seg no / offset [0x%x / 0x%x]\n", 110 GET_SEGNO(sbi, blk_addr), OFFSET_IN_SEG(sbi, blk_addr)); 111 DBG(0, "summary_entry.nid [0x%x]\n", le32_to_cpu(sum_entry.nid)); 112 DBG(0, "--> node block's nid [0x%x]\n", nid); 113 ASSERT_MSG(0, "Invalid node seg summary\n"); 114 } 115 } else if (ret == SEG_TYPE_CUR_NODE) { 116 /* current node segment has no ssa */ 117 } else { 118 ASSERT_MSG(0, "Invalid return value of 'get_sum_entry'"); 119 } 120 121 return 1; 122} 123 124static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr, 125 u32 parent_nid, u16 idx_in_node, u8 version) 126{ 127 int ret = 0; 128 struct f2fs_summary sum_entry; 129 130 ret = get_sum_entry(sbi, blk_addr, &sum_entry); 131 ASSERT(ret == SEG_TYPE_DATA || ret == SEG_TYPE_CUR_DATA); 132 133 if (le32_to_cpu(sum_entry.nid) != parent_nid || 134 sum_entry.version != version || 135 le16_to_cpu(sum_entry.ofs_in_node) != idx_in_node) { 136 137 DBG(0, "summary_entry.nid [0x%x]\n", le32_to_cpu(sum_entry.nid)); 138 DBG(0, "summary_entry.version [0x%x]\n", sum_entry.version); 139 DBG(0, "summary_entry.ofs_in_node [0x%x]\n", le16_to_cpu(sum_entry.ofs_in_node)); 140 141 DBG(0, "parent nid [0x%x]\n", parent_nid); 142 DBG(0, "version from nat [0x%x]\n", version); 143 DBG(0, "idx in parent node [0x%x]\n", idx_in_node); 144 145 DBG(0, "Target data block addr [0x%x]\n", blk_addr); 146 ASSERT_MSG(0, "Invalid data seg summary\n"); 147 } 148 149 return 1; 150} 151 152int fsck_chk_node_blk(struct f2fs_sb_info *sbi, 153 struct f2fs_inode *inode, 154 u32 nid, 155 enum FILE_TYPE ftype, 156 enum NODE_TYPE ntype, 157 u32 *blk_cnt) 158{ 159 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 160 struct node_info ni; 161 struct f2fs_node *node_blk = NULL; 162 int ret = 0; 163 164 IS_VALID_NID(sbi, nid); 165 166 if (ftype != F2FS_FT_ORPHAN || 167 f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0x0) 168 f2fs_clear_bit(nid, fsck->nat_area_bitmap); 169 else 170 ASSERT_MSG(0, "nid duplicated [0x%x]\n", nid); 171 172 ret = get_node_info(sbi, nid, &ni); 173 ASSERT(ret >= 0); 174 175 /* Is it reserved block? 176 * if block addresss was 0xffff,ffff,ffff,ffff 177 * it means that block was already allocated, but not stored in disk 178 */ 179 if (ni.blk_addr == NEW_ADDR) { 180 fsck->chk.valid_blk_cnt++; 181 fsck->chk.valid_node_cnt++; 182 if (ntype == TYPE_INODE) 183 fsck->chk.valid_inode_cnt++; 184 return 0; 185 } 186 187 IS_VALID_BLK_ADDR(sbi, ni.blk_addr); 188 189 is_valid_ssa_node_blk(sbi, nid, ni.blk_addr); 190 191 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->sit_area_bitmap) == 0x0) { 192 DBG(0, "SIT bitmap is 0x0. blk_addr[0x%x]\n", ni.blk_addr); 193 ASSERT(0); 194 } 195 196 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap) == 0x0) { 197 fsck->chk.valid_blk_cnt++; 198 fsck->chk.valid_node_cnt++; 199 } 200 201 node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1); 202 ASSERT(node_blk != NULL); 203 204 ret = dev_read_block(node_blk, ni.blk_addr); 205 ASSERT(ret >= 0); 206 207 ASSERT_MSG(nid == le32_to_cpu(node_blk->footer.nid), 208 "nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]\n", 209 nid, ni.blk_addr, le32_to_cpu(node_blk->footer.nid)); 210 211 if (ntype == TYPE_INODE) { 212 ret = fsck_chk_inode_blk(sbi, 213 nid, 214 ftype, 215 node_blk, 216 blk_cnt, 217 &ni); 218 } else { 219 /* it's not inode */ 220 ASSERT(node_blk->footer.nid != node_blk->footer.ino); 221 222 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap) != 0) { 223 DBG(0, "Duplicated node block. ino[0x%x][0x%x]\n", nid, ni.blk_addr); 224 ASSERT(0); 225 } 226 f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap); 227 228 switch (ntype) { 229 case TYPE_DIRECT_NODE: 230 ret = fsck_chk_dnode_blk(sbi, 231 inode, 232 nid, 233 ftype, 234 node_blk, 235 blk_cnt, 236 &ni); 237 break; 238 case TYPE_INDIRECT_NODE: 239 ret = fsck_chk_idnode_blk(sbi, 240 inode, 241 nid, 242 ftype, 243 node_blk, 244 blk_cnt); 245 break; 246 case TYPE_DOUBLE_INDIRECT_NODE: 247 ret = fsck_chk_didnode_blk(sbi, 248 inode, 249 nid, 250 ftype, 251 node_blk, 252 blk_cnt); 253 break; 254 default: 255 ASSERT(0); 256 } 257 } 258 ASSERT(ret >= 0); 259 260 free(node_blk); 261 return 0; 262} 263 264int fsck_chk_inode_blk(struct f2fs_sb_info *sbi, 265 u32 nid, 266 enum FILE_TYPE ftype, 267 struct f2fs_node *node_blk, 268 u32 *blk_cnt, 269 struct node_info *ni) 270{ 271 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 272 u32 child_cnt = 0, child_files = 0; 273 enum NODE_TYPE ntype; 274 u32 i_links = le32_to_cpu(node_blk->i.i_links); 275 u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks); 276 int idx = 0; 277 int ret = 0; 278 279 ASSERT(node_blk->footer.nid == node_blk->footer.ino); 280 ASSERT(le32_to_cpu(node_blk->footer.nid) == nid); 281 282 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap) == 0x0) 283 fsck->chk.valid_inode_cnt++; 284 285 /* Orphan node. i_links should be 0 */ 286 if (ftype == F2FS_FT_ORPHAN) { 287 ASSERT(i_links == 0); 288 } else { 289 ASSERT(i_links > 0); 290 } 291 292 if (ftype == F2FS_FT_DIR) { 293 294 /* not included '.' & '..' */ 295 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap) != 0) { 296 DBG(0, "Duplicated inode blk. ino[0x%x][0x%x]\n", nid, ni->blk_addr); 297 ASSERT(0); 298 } 299 f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap); 300 301 } else { 302 303 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap) == 0x0) { 304 f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni->blk_addr), fsck->main_area_bitmap); 305 if (i_links > 1) { 306 /* First time. Create new hard link node */ 307 add_into_hard_link_list(sbi, nid, i_links); 308 fsck->chk.multi_hard_link_files++; 309 } 310 } else { 311 if (i_links <= 1) { 312 DBG(0, "Error. Node ID [0x%x]." 313 " There are one more hard links." 314 " But i_links is [0x%x]\n", 315 nid, i_links); 316 ASSERT(0); 317 } 318 319 DBG(3, "ino[0x%x] has hard links [0x%x]\n", nid, i_links); 320 ret = find_and_dec_hard_link_list(sbi, nid); 321 ASSERT(ret >= 0); 322 323 /* No need to go deep into the node */ 324 goto out; 325 } 326 } 327 328 fsck_chk_xattr_blk(sbi, nid, le32_to_cpu(node_blk->i.i_xattr_nid), blk_cnt); 329 330 if (ftype == F2FS_FT_CHRDEV || ftype == F2FS_FT_BLKDEV || 331 ftype == F2FS_FT_FIFO || ftype == F2FS_FT_SOCK) 332 goto check; 333 if((node_blk->i.i_inline & F2FS_INLINE_DATA)){ 334 DBG(3, "ino[0x%x] has inline data!\n", nid); 335 goto check; 336 } 337 338 /* check data blocks in inode */ 339 for (idx = 0; idx < ADDRS_PER_INODE(&node_blk->i); idx++) { 340 if (le32_to_cpu(node_blk->i.i_addr[idx]) != 0) { 341 *blk_cnt = *blk_cnt + 1; 342 ret = fsck_chk_data_blk(sbi, 343 &node_blk->i, 344 le32_to_cpu(node_blk->i.i_addr[idx]), 345 &child_cnt, 346 &child_files, 347 (i_blocks == *blk_cnt), 348 ftype, 349 nid, 350 idx, 351 ni->version); 352 ASSERT(ret >= 0); 353 } 354 } 355 356 /* check node blocks in inode */ 357 for (idx = 0; idx < 5; idx++) { 358 if (idx == 0 || idx == 1) 359 ntype = TYPE_DIRECT_NODE; 360 else if (idx == 2 || idx == 3) 361 ntype = TYPE_INDIRECT_NODE; 362 else if (idx == 4) 363 ntype = TYPE_DOUBLE_INDIRECT_NODE; 364 else 365 ASSERT(0); 366 367 if (le32_to_cpu(node_blk->i.i_nid[idx]) != 0) { 368 *blk_cnt = *blk_cnt + 1; 369 ret = fsck_chk_node_blk(sbi, 370 &node_blk->i, 371 le32_to_cpu(node_blk->i.i_nid[idx]), 372 ftype, 373 ntype, 374 blk_cnt); 375 ASSERT(ret >= 0); 376 } 377 } 378check: 379 if (ftype == F2FS_FT_DIR) 380 DBG(1, "Directory Inode: ino: %x name: %s depth: %d child files: %d\n\n", 381 le32_to_cpu(node_blk->footer.ino), node_blk->i.i_name, 382 le32_to_cpu(node_blk->i.i_current_depth), child_files); 383 if (ftype == F2FS_FT_ORPHAN) 384 DBG(1, "Orphan Inode: ino: %x name: %s i_blocks: %u\n\n", 385 le32_to_cpu(node_blk->footer.ino), node_blk->i.i_name, 386 (u32)i_blocks); 387 if ((ftype == F2FS_FT_DIR && i_links != child_cnt) || 388 (i_blocks != *blk_cnt)) { 389 print_node_info(node_blk); 390 DBG(1, "blk cnt [0x%x]\n", *blk_cnt); 391 DBG(1, "child cnt [0x%x]\n", child_cnt); 392 } 393 394 ASSERT(i_blocks == *blk_cnt); 395 if (ftype == F2FS_FT_DIR) 396 ASSERT(i_links == child_cnt); 397out: 398 return 0; 399} 400 401int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, 402 struct f2fs_inode *inode, 403 u32 nid, 404 enum FILE_TYPE ftype, 405 struct f2fs_node *node_blk, 406 u32 *blk_cnt, 407 struct node_info *ni) 408{ 409 int idx; 410 u32 child_cnt = 0, child_files = 0; 411 412 for (idx = 0; idx < ADDRS_PER_BLOCK; idx++) { 413 if (le32_to_cpu(node_blk->dn.addr[idx]) == 0x0) 414 continue; 415 *blk_cnt = *blk_cnt + 1; 416 fsck_chk_data_blk(sbi, 417 inode, 418 le32_to_cpu(node_blk->dn.addr[idx]), 419 &child_cnt, 420 &child_files, 421 le64_to_cpu(inode->i_blocks) == *blk_cnt, 422 ftype, 423 nid, 424 idx, 425 ni->version); 426 } 427 428 return 0; 429} 430 431int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, 432 struct f2fs_inode *inode, 433 u32 nid, 434 enum FILE_TYPE ftype, 435 struct f2fs_node *node_blk, 436 u32 *blk_cnt) 437{ 438 int i = 0; 439 440 for (i = 0 ; i < NIDS_PER_BLOCK; i++) { 441 if (le32_to_cpu(node_blk->in.nid[i]) == 0x0) 442 continue; 443 *blk_cnt = *blk_cnt + 1; 444 fsck_chk_node_blk(sbi, 445 inode, 446 le32_to_cpu(node_blk->in.nid[i]), 447 ftype, 448 TYPE_DIRECT_NODE, 449 blk_cnt); 450 } 451 452 return 0; 453} 454 455int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, 456 struct f2fs_inode *inode, 457 u32 nid, 458 enum FILE_TYPE ftype, 459 struct f2fs_node *node_blk, 460 u32 *blk_cnt) 461{ 462 int i = 0; 463 464 for (i = 0; i < NIDS_PER_BLOCK; i++) { 465 if (le32_to_cpu(node_blk->in.nid[i]) == 0x0) 466 continue; 467 *blk_cnt = *blk_cnt + 1; 468 fsck_chk_node_blk(sbi, 469 inode, 470 le32_to_cpu(node_blk->in.nid[i]), 471 ftype, 472 TYPE_INDIRECT_NODE, 473 blk_cnt); 474 } 475 476 return 0; 477} 478 479static void print_dentry(__u32 depth, __u8 *name, 480 struct f2fs_dentry_block *de_blk, int idx, int last_blk) 481{ 482 int last_de = 0; 483 int next_idx = 0; 484 int name_len; 485 int i; 486 int bit_offset; 487 488 if (config.dbg_lv != -1) 489 return; 490 491 name_len = le16_to_cpu(de_blk->dentry[idx].name_len); 492 next_idx = idx + (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; 493 494 bit_offset = find_next_bit((unsigned long *)de_blk->dentry_bitmap, 495 NR_DENTRY_IN_BLOCK, next_idx); 496 if (bit_offset >= NR_DENTRY_IN_BLOCK && last_blk) 497 last_de = 1; 498 499 if (tree_mark_size <= depth) { 500 tree_mark_size *= 2; 501 tree_mark = realloc(tree_mark, tree_mark_size); 502 } 503 504 if (last_de) 505 tree_mark[depth] = '`'; 506 else 507 tree_mark[depth] = '|'; 508 509 if (tree_mark[depth - 1] == '`') 510 tree_mark[depth - 1] = ' '; 511 512 513 for (i = 1; i < depth; i++) 514 printf("%c ", tree_mark[i]); 515 printf("%c-- %s\n", last_de ? '`' : '|', name); 516} 517 518int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, 519 struct f2fs_inode *inode, 520 u32 blk_addr, 521 u32 *child_cnt, 522 u32 *child_files, 523 int last_blk) 524{ 525 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 526 int i; 527 int ret = 0; 528 int dentries = 0; 529 u8 *name; 530 u32 hash_code; 531 u32 blk_cnt; 532 u16 name_len;; 533 534 enum FILE_TYPE ftype; 535 struct f2fs_dentry_block *de_blk; 536 537 de_blk = (struct f2fs_dentry_block *)calloc(BLOCK_SZ, 1); 538 ASSERT(de_blk != NULL); 539 540 ret = dev_read_block(de_blk, blk_addr); 541 ASSERT(ret >= 0); 542 543 fsck->dentry_depth++; 544 545 for (i = 0; i < NR_DENTRY_IN_BLOCK;) { 546 if (test_bit(i, (unsigned long *)de_blk->dentry_bitmap) == 0x0) { 547 i++; 548 continue; 549 } 550 551 name_len = le32_to_cpu(de_blk->dentry[i].name_len); 552 name = calloc(name_len + 1, 1); 553 memcpy(name, de_blk->filename[i], name_len); 554 555 hash_code = f2fs_dentry_hash((const char *)name, name_len); 556 ASSERT(le32_to_cpu(de_blk->dentry[i].hash_code) == hash_code); 557 558 ftype = de_blk->dentry[i].file_type; 559 560 /* Becareful. 'dentry.file_type' is not imode. */ 561 if (ftype == F2FS_FT_DIR) { 562 *child_cnt = *child_cnt + 1; 563 if ((name[0] == '.' && name[1] == '.' && name_len == 2) || 564 (name[0] == '.' && name_len == 1)) { 565 i++; 566 free(name); 567 continue; 568 } 569 } 570 571 DBG(2, "[%3u] - no[0x%x] name[%s] len[0x%x] ino[0x%x] type[0x%x]\n", 572 fsck->dentry_depth, i, name, name_len, 573 le32_to_cpu(de_blk->dentry[i].ino), 574 de_blk->dentry[i].file_type); 575 576 print_dentry(fsck->dentry_depth, name, de_blk, i, last_blk); 577 578 blk_cnt = 1; 579 ret = fsck_chk_node_blk(sbi, 580 NULL, 581 le32_to_cpu(de_blk->dentry[i].ino), 582 ftype, 583 TYPE_INODE, 584 &blk_cnt); 585 586 ASSERT(ret >= 0); 587 588 i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN; 589 dentries++; 590 *child_files = *child_files + 1; 591 free(name); 592 } 593 594 DBG(1, "[%3d] Dentry Block [0x%x] Done : dentries:%d in %d slots (len:%d)\n\n", 595 fsck->dentry_depth, blk_addr, dentries, NR_DENTRY_IN_BLOCK, F2FS_NAME_LEN); 596 fsck->dentry_depth--; 597 598 free(de_blk); 599 return 0; 600} 601 602int fsck_chk_data_blk(struct f2fs_sb_info *sbi, 603 struct f2fs_inode *inode, 604 u32 blk_addr, 605 u32 *child_cnt, 606 u32 *child_files, 607 int last_blk, 608 enum FILE_TYPE ftype, 609 u32 parent_nid, 610 u16 idx_in_node, 611 u8 ver) 612{ 613 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 614 615 /* Is it reserved block? */ 616 if (blk_addr == NEW_ADDR) { 617 fsck->chk.valid_blk_cnt++; 618 return 0; 619 } 620 621 IS_VALID_BLK_ADDR(sbi, blk_addr); 622 623 is_valid_ssa_data_blk(sbi, blk_addr, parent_nid, idx_in_node, ver); 624 625 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk_addr), fsck->sit_area_bitmap) == 0x0) { 626 ASSERT_MSG(0, "SIT bitmap is 0x0. blk_addr[0x%x]\n", blk_addr); 627 } 628 629 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, blk_addr), fsck->main_area_bitmap) != 0) { 630 ASSERT_MSG(0, "Duplicated data block. pnid[0x%x] idx[0x%x] blk_addr[0x%x]\n", 631 parent_nid, idx_in_node, blk_addr); 632 } 633 f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, blk_addr), fsck->main_area_bitmap); 634 635 fsck->chk.valid_blk_cnt++; 636 637 if (ftype == F2FS_FT_DIR) { 638 fsck_chk_dentry_blk(sbi, 639 inode, 640 blk_addr, 641 child_cnt, 642 child_files, 643 last_blk); 644 } 645 646 return 0; 647} 648 649int fsck_chk_orphan_node(struct f2fs_sb_info *sbi) 650{ 651 int ret = 0; 652 u32 blk_cnt = 0; 653 654 block_t start_blk, orphan_blkaddr, i, j; 655 struct f2fs_orphan_block *orphan_blk; 656 657 if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG)) 658 return 0; 659 660 start_blk = __start_cp_addr(sbi) + 1; 661 orphan_blkaddr = __start_sum_addr(sbi) - 1; 662 663 orphan_blk = calloc(BLOCK_SZ, 1); 664 665 for (i = 0; i < orphan_blkaddr; i++) { 666 dev_read_block(orphan_blk, start_blk + i); 667 668 for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) { 669 nid_t ino = le32_to_cpu(orphan_blk->ino[j]); 670 DBG(1, "[%3d] ino [0x%x]\n", i, ino); 671 blk_cnt = 1; 672 ret = fsck_chk_node_blk(sbi, 673 NULL, 674 ino, 675 F2FS_FT_ORPHAN, 676 TYPE_INODE, 677 &blk_cnt); 678 ASSERT(ret >= 0); 679 } 680 memset(orphan_blk, 0, BLOCK_SZ); 681 } 682 free(orphan_blk); 683 684 685 return 0; 686} 687 688int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino, u32 x_nid, u32 *blk_cnt) 689{ 690 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 691 struct node_info ni; 692 693 if (x_nid == 0x0) 694 return 0; 695 696 if (f2fs_test_bit(x_nid, fsck->nat_area_bitmap) != 0x0) { 697 f2fs_clear_bit(x_nid, fsck->nat_area_bitmap); 698 } else { 699 ASSERT_MSG(0, "xattr_nid duplicated [0x%x]\n", x_nid); 700 } 701 702 *blk_cnt = *blk_cnt + 1; 703 fsck->chk.valid_blk_cnt++; 704 fsck->chk.valid_node_cnt++; 705 706 ASSERT(get_node_info(sbi, x_nid, &ni) >= 0); 707 708 if (f2fs_test_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap) != 0) { 709 ASSERT_MSG(0, "Duplicated node block for x_attr. " 710 "x_nid[0x%x] block addr[0x%x]\n", 711 x_nid, ni.blk_addr); 712 } 713 f2fs_set_bit(BLKOFF_FROM_MAIN(sbi, ni.blk_addr), fsck->main_area_bitmap); 714 715 DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid); 716 return 0; 717} 718 719int fsck_init(struct f2fs_sb_info *sbi) 720{ 721 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 722 struct f2fs_sm_info *sm_i = SM_I(sbi); 723 724 /* 725 * We build three bitmap for main/sit/nat so that may check consistency of filesystem. 726 * 1. main_area_bitmap will be used to check whether all blocks of main area is used or not. 727 * 2. nat_area_bitmap has bitmap information of used nid in NAT. 728 * 3. sit_area_bitmap has bitmap information of used main block. 729 * At Last sequence, we compare main_area_bitmap with sit_area_bitmap. 730 */ 731 fsck->nr_main_blks = sm_i->main_segments << sbi->log_blocks_per_seg; 732 fsck->main_area_bitmap_sz = (fsck->nr_main_blks + 7) / 8; 733 fsck->main_area_bitmap = calloc(fsck->main_area_bitmap_sz, 1); 734 ASSERT(fsck->main_area_bitmap != NULL); 735 736 build_nat_area_bitmap(sbi); 737 738 build_sit_area_bitmap(sbi); 739 740 tree_mark = calloc(tree_mark_size, 1); 741 return 0; 742} 743 744int fsck_verify(struct f2fs_sb_info *sbi) 745{ 746 int i = 0; 747 int ret = 0; 748 u32 nr_unref_nid = 0; 749 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 750 struct hard_link_node *node = NULL; 751 752 printf("\n"); 753 754 for (i = 0; i < fsck->nr_nat_entries; i++) { 755 if (f2fs_test_bit(i, fsck->nat_area_bitmap) != 0) { 756 printf("NID[0x%x] is unreachable\n", i); 757 nr_unref_nid++; 758 } 759 } 760 761 if (fsck->hard_link_list_head != NULL) { 762 node = fsck->hard_link_list_head; 763 while (node) { 764 printf("NID[0x%x] has [0x%x] more unreachable links\n", 765 node->nid, node->links); 766 node = node->next; 767 } 768 } 769 770 printf("[FSCK] Unreachable nat entries "); 771 if (nr_unref_nid == 0x0) { 772 printf(" [Ok..] [0x%x]\n", nr_unref_nid); 773 } else { 774 printf(" [Fail] [0x%x]\n", nr_unref_nid); 775 ret = EXIT_ERR_CODE; 776 } 777 778 printf("[FSCK] SIT valid block bitmap checking "); 779 if (memcmp(fsck->sit_area_bitmap, fsck->main_area_bitmap, fsck->sit_area_bitmap_sz) == 0x0) { 780 printf("[Ok..]\n"); 781 } else { 782 printf("[Fail]\n"); 783 ret = EXIT_ERR_CODE; 784 } 785 786 printf("[FSCK] Hard link checking for regular file "); 787 if (fsck->hard_link_list_head == NULL) { 788 printf(" [Ok..] [0x%x]\n", fsck->chk.multi_hard_link_files); 789 } else { 790 printf(" [Fail] [0x%x]\n", fsck->chk.multi_hard_link_files); 791 ret = EXIT_ERR_CODE; 792 } 793 794 printf("[FSCK] valid_block_count matching with CP "); 795 if (sbi->total_valid_block_count == fsck->chk.valid_blk_cnt) { 796 printf(" [Ok..] [0x%x]\n", (u32)fsck->chk.valid_blk_cnt); 797 } else { 798 printf(" [Fail] [0x%x]\n", (u32)fsck->chk.valid_blk_cnt); 799 ret = EXIT_ERR_CODE; 800 } 801 802 printf("[FSCK] valid_node_count matcing with CP (de lookup) "); 803 if (sbi->total_valid_node_count == fsck->chk.valid_node_cnt) { 804 printf(" [Ok..] [0x%x]\n", fsck->chk.valid_node_cnt); 805 } else { 806 printf(" [Fail] [0x%x]\n", fsck->chk.valid_node_cnt); 807 ret = EXIT_ERR_CODE; 808 } 809 810 printf("[FSCK] valid_node_count matcing with CP (nat lookup) "); 811 if (sbi->total_valid_node_count == fsck->chk.valid_nat_entry_cnt) { 812 printf(" [Ok..] [0x%x]\n", fsck->chk.valid_nat_entry_cnt); 813 } else { 814 printf(" [Fail] [0x%x]\n", fsck->chk.valid_nat_entry_cnt); 815 ret = EXIT_ERR_CODE; 816 } 817 818 printf("[FSCK] valid_inode_count matched with CP "); 819 if (sbi->total_valid_inode_count == fsck->chk.valid_inode_cnt) { 820 printf(" [Ok..] [0x%x]\n", fsck->chk.valid_inode_cnt); 821 } else { 822 printf(" [Fail] [0x%x]\n", fsck->chk.valid_inode_cnt); 823 ret = EXIT_ERR_CODE; 824 } 825 826 return ret; 827} 828 829void fsck_free(struct f2fs_sb_info *sbi) 830{ 831 struct f2fs_fsck *fsck = F2FS_FSCK(sbi); 832 if (fsck->main_area_bitmap) 833 free(fsck->main_area_bitmap); 834 835 if (fsck->nat_area_bitmap) 836 free(fsck->nat_area_bitmap); 837 838 if (fsck->sit_area_bitmap) 839 free(fsck->sit_area_bitmap); 840 841 if (tree_mark) 842 free(tree_mark); 843} 844