aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/checkpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r--fs/f2fs/checkpoint.c99
1 files changed, 76 insertions, 23 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index b1de01da1a40..66a6b85a51d8 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -357,8 +357,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
357 unsigned long blk_size = sbi->blocksize; 357 unsigned long blk_size = sbi->blocksize;
358 struct f2fs_checkpoint *cp_block; 358 struct f2fs_checkpoint *cp_block;
359 unsigned long long cur_version = 0, pre_version = 0; 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 362
363 /* Read the 1st cp block in this CP pack */ 363 /* Read the 1st cp block in this CP pack */
364 cp_page_1 = get_meta_page(sbi, cp_addr); 364 cp_page_1 = get_meta_page(sbi, cp_addr);
@@ -369,7 +369,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
369 if (crc_offset >= blk_size) 369 if (crc_offset >= blk_size)
370 goto invalid_cp1; 370 goto invalid_cp1;
371 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)) 373 if (!f2fs_crc_valid(crc, cp_block, crc_offset))
374 goto invalid_cp1; 374 goto invalid_cp1;
375 375
@@ -384,7 +384,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi,
384 if (crc_offset >= blk_size) 384 if (crc_offset >= blk_size)
385 goto invalid_cp2; 385 goto invalid_cp2;
386 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)) 388 if (!f2fs_crc_valid(crc, cp_block, crc_offset))
389 goto invalid_cp2; 389 goto invalid_cp2;
390 390
@@ -450,13 +450,30 @@ fail_no_cp:
450 return -EINVAL; 450 return -EINVAL;
451} 451}
452 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{ 454{
455 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); 455 struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
456 struct list_head *head = &sbi->dir_inode_list; 456 struct list_head *head = &sbi->dir_inode_list;
457 struct dir_inode_entry *new;
458 struct list_head *this; 457 struct list_head *this;
459 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)) 477 if (!S_ISDIR(inode->i_mode))
461 return; 478 return;
462retry: 479retry:
@@ -469,23 +486,31 @@ retry:
469 INIT_LIST_HEAD(&new->list); 486 INIT_LIST_HEAD(&new->list);
470 487
471 spin_lock(&sbi->dir_inode_lock); 488 spin_lock(&sbi->dir_inode_lock);
472 list_for_each(this, head) { 489 if (__add_dirty_inode(inode, new))
473 struct dir_inode_entry *entry; 490 kmem_cache_free(inode_entry_slab, new);
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++;
482 491
483 BUG_ON(!S_ISDIR(inode->i_mode));
484out:
485 inc_page_count(sbi, F2FS_DIRTY_DENTS); 492 inc_page_count(sbi, F2FS_DIRTY_DENTS);
486 inode_inc_dirty_dents(inode); 493 inode_inc_dirty_dents(inode);
487 SetPagePrivate(page); 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); 514 spin_unlock(&sbi->dir_inode_lock);
490} 515}
491 516
@@ -499,8 +524,10 @@ void remove_dirty_dir_inode(struct inode *inode)
499 return; 524 return;
500 525
501 spin_lock(&sbi->dir_inode_lock); 526 spin_lock(&sbi->dir_inode_lock);
502 if (atomic_read(&F2FS_I(inode)->dirty_dents)) 527 if (atomic_read(&F2FS_I(inode)->dirty_dents)) {
503 goto out; 528 spin_unlock(&sbi->dir_inode_lock);
529 return;
530 }
504 531
505 list_for_each(this, head) { 532 list_for_each(this, head) {
506 struct dir_inode_entry *entry; 533 struct dir_inode_entry *entry;
@@ -508,12 +535,38 @@ void remove_dirty_dir_inode(struct inode *inode)
508 if (entry->inode == inode) { 535 if (entry->inode == inode) {
509 list_del(&entry->list); 536 list_del(&entry->list);
510 kmem_cache_free(inode_entry_slab, entry); 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
541 break;
542 }
543 }
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 }
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;
512 break; 565 break;
513 } 566 }
514 } 567 }
515out:
516 spin_unlock(&sbi->dir_inode_lock); 568 spin_unlock(&sbi->dir_inode_lock);
569 return inode;
517} 570}
518 571
519void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) 572void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi)
@@ -595,7 +648,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
595 block_t start_blk; 648 block_t start_blk;
596 struct page *cp_page; 649 struct page *cp_page;
597 unsigned int data_sum_blocks, orphan_blocks; 650 unsigned int data_sum_blocks, orphan_blocks;
598 unsigned int crc32 = 0; 651 __u32 crc32 = 0;
599 void *kaddr; 652 void *kaddr;
600 int i; 653 int i;
601 654
@@ -664,8 +717,8 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
664 get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP)); 717 get_nat_bitmap(sbi, __bitmap_ptr(sbi, NAT_BITMAP));
665 718
666 crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset)); 719 crc32 = f2fs_crc32(ckpt, le32_to_cpu(ckpt->checksum_offset));
667 *(__le32 *)((unsigned char *)ckpt + 720 *((__le32 *)((unsigned char *)ckpt +
668 le32_to_cpu(ckpt->checksum_offset)) 721 le32_to_cpu(ckpt->checksum_offset)))
669 = cpu_to_le32(crc32); 722 = cpu_to_le32(crc32);
670 723
671 start_blk = __start_cp_addr(sbi); 724 start_blk = __start_cp_addr(sbi);