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