checkpoint.c (31881d74b6dd1a6c530cff61248def4f2da38bee) | checkpoint.c (7e586fa0244578320fcced9cc08c6b124f727c35) |
---|---|
1/* 2 * fs/f2fs/checkpoint.c 3 * 4 * Copyright (c) 2012 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 --- 343 unchanged lines hidden (view full) --- 352 353static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, 354 block_t cp_addr, unsigned long long *version) 355{ 356 struct page *cp_page_1, *cp_page_2 = NULL; 357 unsigned long blk_size = sbi->blocksize; 358 struct f2fs_checkpoint *cp_block; 359 unsigned long long cur_version = 0, pre_version = 0; | 1/* 2 * fs/f2fs/checkpoint.c 3 * 4 * Copyright (c) 2012 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 --- 343 unchanged lines hidden (view full) --- 352 353static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, 354 block_t cp_addr, unsigned long long *version) 355{ 356 struct page *cp_page_1, *cp_page_2 = NULL; 357 unsigned long blk_size = sbi->blocksize; 358 struct f2fs_checkpoint *cp_block; 359 unsigned long long cur_version = 0, pre_version = 0; |
360 unsigned int crc = 0; | |
361 size_t crc_offset; | 360 size_t crc_offset; |
361 __u32 crc = 0; |
|
362 363 /* Read the 1st cp block in this CP pack */ 364 cp_page_1 = get_meta_page(sbi, cp_addr); 365 366 /* get the version number */ 367 cp_block = (struct f2fs_checkpoint *)page_address(cp_page_1); 368 crc_offset = le32_to_cpu(cp_block->checksum_offset); 369 if (crc_offset >= blk_size) 370 goto invalid_cp1; 371 | 362 363 /* Read the 1st cp block in this CP pack */ 364 cp_page_1 = get_meta_page(sbi, cp_addr); 365 366 /* get the version number */ 367 cp_block = (struct f2fs_checkpoint *)page_address(cp_page_1); 368 crc_offset = le32_to_cpu(cp_block->checksum_offset); 369 if (crc_offset >= blk_size) 370 goto invalid_cp1; 371 |
372 crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset); | 372 crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset))); |
373 if (!f2fs_crc_valid(crc, cp_block, crc_offset)) 374 goto invalid_cp1; 375 376 pre_version = le64_to_cpu(cp_block->checkpoint_ver); 377 378 /* Read the 2nd cp block in this CP pack */ 379 cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1; 380 cp_page_2 = get_meta_page(sbi, cp_addr); 381 382 cp_block = (struct f2fs_checkpoint *)page_address(cp_page_2); 383 crc_offset = le32_to_cpu(cp_block->checksum_offset); 384 if (crc_offset >= blk_size) 385 goto invalid_cp2; 386 | 373 if (!f2fs_crc_valid(crc, cp_block, crc_offset)) 374 goto invalid_cp1; 375 376 pre_version = le64_to_cpu(cp_block->checkpoint_ver); 377 378 /* Read the 2nd cp block in this CP pack */ 379 cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1; 380 cp_page_2 = get_meta_page(sbi, cp_addr); 381 382 cp_block = (struct f2fs_checkpoint *)page_address(cp_page_2); 383 crc_offset = le32_to_cpu(cp_block->checksum_offset); 384 if (crc_offset >= blk_size) 385 goto invalid_cp2; 386 |
387 crc = *(unsigned int *)((unsigned char *)cp_block + crc_offset); | 387 crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset))); |
388 if (!f2fs_crc_valid(crc, cp_block, crc_offset)) 389 goto invalid_cp2; 390 391 cur_version = le64_to_cpu(cp_block->checkpoint_ver); 392 393 if (cur_version == pre_version) { 394 *version = cur_version; 395 f2fs_put_page(cp_page_2, 1); --- 49 unchanged lines hidden (view full) --- 445 f2fs_put_page(cp2, 1); 446 return 0; 447 448fail_no_cp: 449 kfree(sbi->ckpt); 450 return -EINVAL; 451} 452 | 388 if (!f2fs_crc_valid(crc, cp_block, crc_offset)) 389 goto invalid_cp2; 390 391 cur_version = le64_to_cpu(cp_block->checkpoint_ver); 392 393 if (cur_version == pre_version) { 394 *version = cur_version; 395 f2fs_put_page(cp_page_2, 1); --- 49 unchanged lines hidden (view full) --- 445 f2fs_put_page(cp2, 1); 446 return 0; 447 448fail_no_cp: 449 kfree(sbi->ckpt); 450 return -EINVAL; 451} 452 |
453void set_dirty_dir_page(struct inode *inode, struct page *page) | 453static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new) |
454{ 455 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 456 struct list_head *head = &sbi->dir_inode_list; | 454{ 455 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 456 struct list_head *head = &sbi->dir_inode_list; |
457 struct dir_inode_entry *new; | |
458 struct list_head *this; 459 | 457 struct list_head *this; 458 |
459 list_for_each(this, head) { 460 struct dir_inode_entry *entry; 461 entry = list_entry(this, struct dir_inode_entry, list); 462 if (entry->inode == inode) 463 return -EEXIST; 464 } 465 list_add_tail(&new->list, head); 466#ifdef CONFIG_F2FS_STAT_FS 467 sbi->n_dirty_dirs++; 468#endif 469 return 0; 470} 471 472void set_dirty_dir_page(struct inode *inode, struct page *page) 473{ 474 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 475 struct dir_inode_entry *new; 476 |
|
460 if (!S_ISDIR(inode->i_mode)) 461 return; 462retry: 463 new = kmem_cache_alloc(inode_entry_slab, GFP_NOFS); 464 if (!new) { 465 cond_resched(); 466 goto retry; 467 } 468 new->inode = inode; 469 INIT_LIST_HEAD(&new->list); 470 471 spin_lock(&sbi->dir_inode_lock); | 477 if (!S_ISDIR(inode->i_mode)) 478 return; 479retry: 480 new = kmem_cache_alloc(inode_entry_slab, GFP_NOFS); 481 if (!new) { 482 cond_resched(); 483 goto retry; 484 } 485 new->inode = inode; 486 INIT_LIST_HEAD(&new->list); 487 488 spin_lock(&sbi->dir_inode_lock); |
472 list_for_each(this, head) { 473 struct dir_inode_entry *entry; 474 entry = list_entry(this, struct dir_inode_entry, list); 475 if (entry->inode == inode) { 476 kmem_cache_free(inode_entry_slab, new); 477 goto out; 478 } 479 } 480 list_add_tail(&new->list, head); 481 sbi->n_dirty_dirs++; | 489 if (__add_dirty_inode(inode, new)) 490 kmem_cache_free(inode_entry_slab, new); |
482 | 491 |
483 BUG_ON(!S_ISDIR(inode->i_mode)); 484out: | |
485 inc_page_count(sbi, F2FS_DIRTY_DENTS); 486 inode_inc_dirty_dents(inode); 487 SetPagePrivate(page); | 492 inc_page_count(sbi, F2FS_DIRTY_DENTS); 493 inode_inc_dirty_dents(inode); 494 SetPagePrivate(page); |
495 spin_unlock(&sbi->dir_inode_lock); 496} |
|
488 | 497 |
498void add_dirty_dir_inode(struct inode *inode) 499{ 500 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 501 struct dir_inode_entry *new; 502retry: 503 new = kmem_cache_alloc(inode_entry_slab, GFP_NOFS); 504 if (!new) { 505 cond_resched(); 506 goto retry; 507 } 508 new->inode = inode; 509 INIT_LIST_HEAD(&new->list); 510 511 spin_lock(&sbi->dir_inode_lock); 512 if (__add_dirty_inode(inode, new)) 513 kmem_cache_free(inode_entry_slab, new); |
|
489 spin_unlock(&sbi->dir_inode_lock); 490} 491 492void remove_dirty_dir_inode(struct inode *inode) 493{ 494 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 495 struct list_head *head = &sbi->dir_inode_list; 496 struct list_head *this; 497 498 if (!S_ISDIR(inode->i_mode)) 499 return; 500 501 spin_lock(&sbi->dir_inode_lock); | 514 spin_unlock(&sbi->dir_inode_lock); 515} 516 517void remove_dirty_dir_inode(struct inode *inode) 518{ 519 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 520 struct list_head *head = &sbi->dir_inode_list; 521 struct list_head *this; 522 523 if (!S_ISDIR(inode->i_mode)) 524 return; 525 526 spin_lock(&sbi->dir_inode_lock); |
502 if (atomic_read(&F2FS_I(inode)->dirty_dents)) 503 goto out; | 527 if (atomic_read(&F2FS_I(inode)->dirty_dents)) { 528 spin_unlock(&sbi->dir_inode_lock); 529 return; 530 } |
504 505 list_for_each(this, head) { 506 struct dir_inode_entry *entry; 507 entry = list_entry(this, struct dir_inode_entry, list); 508 if (entry->inode == inode) { 509 list_del(&entry->list); 510 kmem_cache_free(inode_entry_slab, entry); | 531 532 list_for_each(this, head) { 533 struct dir_inode_entry *entry; 534 entry = list_entry(this, struct dir_inode_entry, list); 535 if (entry->inode == inode) { 536 list_del(&entry->list); 537 kmem_cache_free(inode_entry_slab, entry); |
538#ifdef CONFIG_F2FS_STAT_FS |
|
511 sbi->n_dirty_dirs--; | 539 sbi->n_dirty_dirs--; |
540#endif |
|
512 break; 513 } 514 } | 541 break; 542 } 543 } |
515out: | |
516 spin_unlock(&sbi->dir_inode_lock); | 544 spin_unlock(&sbi->dir_inode_lock); |
545 546 /* Only from the recovery routine */ 547 if (is_inode_flag_set(F2FS_I(inode), FI_DELAY_IPUT)) { 548 clear_inode_flag(F2FS_I(inode), FI_DELAY_IPUT); 549 iput(inode); 550 } |
|
517} 518 | 551} 552 |
553struct inode *check_dirty_dir_inode(struct f2fs_sb_info *sbi, nid_t ino) 554{ 555 struct list_head *head = &sbi->dir_inode_list; 556 struct list_head *this; 557 struct inode *inode = NULL; 558 559 spin_lock(&sbi->dir_inode_lock); 560 list_for_each(this, head) { 561 struct dir_inode_entry *entry; 562 entry = list_entry(this, struct dir_inode_entry, list); 563 if (entry->inode->i_ino == ino) { 564 inode = entry->inode; 565 break; 566 } 567 } 568 spin_unlock(&sbi->dir_inode_lock); 569 return inode; 570} 571 |
|
519void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) 520{ 521 struct list_head *head = &sbi->dir_inode_list; 522 struct dir_inode_entry *entry; 523 struct inode *inode; 524retry: 525 spin_lock(&sbi->dir_inode_lock); 526 if (list_empty(head)) { --- 63 unchanged lines hidden (view full) --- 590 591static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) 592{ 593 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); 594 nid_t last_nid = 0; 595 block_t start_blk; 596 struct page *cp_page; 597 unsigned int data_sum_blocks, orphan_blocks; | 572void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) 573{ 574 struct list_head *head = &sbi->dir_inode_list; 575 struct dir_inode_entry *entry; 576 struct inode *inode; 577retry: 578 spin_lock(&sbi->dir_inode_lock); 579 if (list_empty(head)) { --- 63 unchanged lines hidden (view full) --- 643 644static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) 645{ 646 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); 647 nid_t last_nid = 0; 648 block_t start_blk; 649 struct page *cp_page; 650 unsigned int data_sum_blocks, orphan_blocks; |
598 unsigned int crc32 = 0; | 651 __u32 crc32 = 0; |
599 void *kaddr; 600 int i; 601 602 /* Flush all the NAT/SIT pages */ 603 while (get_pages(sbi, F2FS_DIRTY_META)) 604 sync_meta_pages(sbi, META, LONG_MAX); 605 606 next_free_nid(sbi, &last_nid); --- 52 unchanged lines hidden (view full) --- 659 else 660 clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); 661 662 /* update SIT/NAT bitmap */ 663 get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP)); 664 get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); 665 666 crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset)); | 652 void *kaddr; 653 int i; 654 655 /* Flush all the NAT/SIT pages */ 656 while (get_pages(sbi, F2FS_DIRTY_META)) 657 sync_meta_pages(sbi, META, LONG_MAX); 658 659 next_free_nid(sbi, &last_nid); --- 52 unchanged lines hidden (view full) --- 712 else 713 clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); 714 715 /* update SIT/NAT bitmap */ 716 get_sit_bitmap(sbi, __bitmap_ptr(sbi, SIT_BITMAP)); 717 get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); 718 719 crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset)); |
667 *(__le32 *)((unsigned char *)ckpt + 668 le32_to_cpu(ckpt->checksum_offset)) | 720 *((__le32 *)((unsigned char *)ckpt + 721 le32_to_cpu(ckpt->checksum_offset))) |
669 = cpu_to_le32(crc32); 670 671 start_blk = __start_cp_addr(sbi); 672 673 /* write out checkpoint buffer at block 0 */ 674 cp_page = grab_meta_page(sbi, start_blk++); 675 kaddr = page_address(cp_page); 676 memcpy(kaddr, ckpt, (1 << sbi->log_blocksize)); --- 109 unchanged lines hidden --- | 722 = cpu_to_le32(crc32); 723 724 start_blk = __start_cp_addr(sbi); 725 726 /* write out checkpoint buffer at block 0 */ 727 cp_page = grab_meta_page(sbi, start_blk++); 728 kaddr = page_address(cp_page); 729 memcpy(kaddr, ckpt, (1 << sbi->log_blocksize)); --- 109 unchanged lines hidden --- |