diff options
Diffstat (limited to 'fs/f2fs/checkpoint.c')
| -rw-r--r-- | fs/f2fs/checkpoint.c | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index e6c271fefaca..7f794b72b3b7 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
| @@ -20,10 +20,11 @@ | |||
| 20 | #include "f2fs.h" | 20 | #include "f2fs.h" |
| 21 | #include "node.h" | 21 | #include "node.h" |
| 22 | #include "segment.h" | 22 | #include "segment.h" |
| 23 | #include "trace.h" | ||
| 23 | #include <trace/events/f2fs.h> | 24 | #include <trace/events/f2fs.h> |
| 24 | 25 | ||
| 25 | static struct kmem_cache *ino_entry_slab; | 26 | static struct kmem_cache *ino_entry_slab; |
| 26 | static struct kmem_cache *inode_entry_slab; | 27 | struct kmem_cache *inode_entry_slab; |
| 27 | 28 | ||
| 28 | /* | 29 | /* |
| 29 | * We guarantee no failure on the returned page. | 30 | * We guarantee no failure on the returned page. |
| @@ -50,6 +51,11 @@ struct page *get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index) | |||
| 50 | { | 51 | { |
| 51 | struct address_space *mapping = META_MAPPING(sbi); | 52 | struct address_space *mapping = META_MAPPING(sbi); |
| 52 | struct page *page; | 53 | struct page *page; |
| 54 | struct f2fs_io_info fio = { | ||
| 55 | .type = META, | ||
| 56 | .rw = READ_SYNC | REQ_META | REQ_PRIO, | ||
| 57 | .blk_addr = index, | ||
| 58 | }; | ||
| 53 | repeat: | 59 | repeat: |
| 54 | page = grab_cache_page(mapping, index); | 60 | page = grab_cache_page(mapping, index); |
| 55 | if (!page) { | 61 | if (!page) { |
| @@ -59,8 +65,7 @@ repeat: | |||
| 59 | if (PageUptodate(page)) | 65 | if (PageUptodate(page)) |
| 60 | goto out; | 66 | goto out; |
| 61 | 67 | ||
| 62 | if (f2fs_submit_page_bio(sbi, page, index, | 68 | if (f2fs_submit_page_bio(sbi, page, &fio)) |
| 63 | READ_SYNC | REQ_META | REQ_PRIO)) | ||
| 64 | goto repeat; | 69 | goto repeat; |
| 65 | 70 | ||
| 66 | lock_page(page); | 71 | lock_page(page); |
| @@ -112,14 +117,12 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type | |||
| 112 | block_t prev_blk_addr = 0; | 117 | block_t prev_blk_addr = 0; |
| 113 | struct page *page; | 118 | struct page *page; |
| 114 | block_t blkno = start; | 119 | block_t blkno = start; |
| 115 | |||
| 116 | struct f2fs_io_info fio = { | 120 | struct f2fs_io_info fio = { |
| 117 | .type = META, | 121 | .type = META, |
| 118 | .rw = READ_SYNC | REQ_META | REQ_PRIO | 122 | .rw = READ_SYNC | REQ_META | REQ_PRIO |
| 119 | }; | 123 | }; |
| 120 | 124 | ||
| 121 | for (; nrpages-- > 0; blkno++) { | 125 | for (; nrpages-- > 0; blkno++) { |
| 122 | block_t blk_addr; | ||
| 123 | 126 | ||
| 124 | if (!is_valid_blkaddr(sbi, blkno, type)) | 127 | if (!is_valid_blkaddr(sbi, blkno, type)) |
| 125 | goto out; | 128 | goto out; |
| @@ -130,27 +133,27 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type | |||
| 130 | NAT_BLOCK_OFFSET(NM_I(sbi)->max_nid))) | 133 | NAT_BLOCK_OFFSET(NM_I(sbi)->max_nid))) |
| 131 | blkno = 0; | 134 | blkno = 0; |
| 132 | /* get nat block addr */ | 135 | /* get nat block addr */ |
| 133 | blk_addr = current_nat_addr(sbi, | 136 | fio.blk_addr = current_nat_addr(sbi, |
| 134 | blkno * NAT_ENTRY_PER_BLOCK); | 137 | blkno * NAT_ENTRY_PER_BLOCK); |
| 135 | break; | 138 | break; |
| 136 | case META_SIT: | 139 | case META_SIT: |
| 137 | /* get sit block addr */ | 140 | /* get sit block addr */ |
| 138 | blk_addr = current_sit_addr(sbi, | 141 | fio.blk_addr = current_sit_addr(sbi, |
| 139 | blkno * SIT_ENTRY_PER_BLOCK); | 142 | blkno * SIT_ENTRY_PER_BLOCK); |
| 140 | if (blkno != start && prev_blk_addr + 1 != blk_addr) | 143 | if (blkno != start && prev_blk_addr + 1 != fio.blk_addr) |
| 141 | goto out; | 144 | goto out; |
| 142 | prev_blk_addr = blk_addr; | 145 | prev_blk_addr = fio.blk_addr; |
| 143 | break; | 146 | break; |
| 144 | case META_SSA: | 147 | case META_SSA: |
| 145 | case META_CP: | 148 | case META_CP: |
| 146 | case META_POR: | 149 | case META_POR: |
| 147 | blk_addr = blkno; | 150 | fio.blk_addr = blkno; |
| 148 | break; | 151 | break; |
| 149 | default: | 152 | default: |
| 150 | BUG(); | 153 | BUG(); |
| 151 | } | 154 | } |
| 152 | 155 | ||
| 153 | page = grab_cache_page(META_MAPPING(sbi), blk_addr); | 156 | page = grab_cache_page(META_MAPPING(sbi), fio.blk_addr); |
| 154 | if (!page) | 157 | if (!page) |
| 155 | continue; | 158 | continue; |
| 156 | if (PageUptodate(page)) { | 159 | if (PageUptodate(page)) { |
| @@ -158,7 +161,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type | |||
| 158 | continue; | 161 | continue; |
| 159 | } | 162 | } |
| 160 | 163 | ||
| 161 | f2fs_submit_page_mbio(sbi, page, blk_addr, &fio); | 164 | f2fs_submit_page_mbio(sbi, page, &fio); |
| 162 | f2fs_put_page(page, 0); | 165 | f2fs_put_page(page, 0); |
| 163 | } | 166 | } |
| 164 | out: | 167 | out: |
| @@ -187,7 +190,7 @@ static int f2fs_write_meta_page(struct page *page, | |||
| 187 | 190 | ||
| 188 | trace_f2fs_writepage(page, META); | 191 | trace_f2fs_writepage(page, META); |
| 189 | 192 | ||
| 190 | if (unlikely(sbi->por_doing)) | 193 | if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) |
| 191 | goto redirty_out; | 194 | goto redirty_out; |
| 192 | if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0)) | 195 | if (wbc->for_reclaim && page->index < GET_SUM_BLOCK(sbi, 0)) |
| 193 | goto redirty_out; | 196 | goto redirty_out; |
| @@ -299,6 +302,8 @@ static int f2fs_set_meta_page_dirty(struct page *page) | |||
| 299 | if (!PageDirty(page)) { | 302 | if (!PageDirty(page)) { |
| 300 | __set_page_dirty_nobuffers(page); | 303 | __set_page_dirty_nobuffers(page); |
| 301 | inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META); | 304 | inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META); |
| 305 | SetPagePrivate(page); | ||
| 306 | f2fs_trace_pid(page); | ||
| 302 | return 1; | 307 | return 1; |
| 303 | } | 308 | } |
| 304 | return 0; | 309 | return 0; |
| @@ -308,6 +313,8 @@ const struct address_space_operations f2fs_meta_aops = { | |||
| 308 | .writepage = f2fs_write_meta_page, | 313 | .writepage = f2fs_write_meta_page, |
| 309 | .writepages = f2fs_write_meta_pages, | 314 | .writepages = f2fs_write_meta_pages, |
| 310 | .set_page_dirty = f2fs_set_meta_page_dirty, | 315 | .set_page_dirty = f2fs_set_meta_page_dirty, |
| 316 | .invalidatepage = f2fs_invalidate_page, | ||
| 317 | .releasepage = f2fs_release_page, | ||
| 311 | }; | 318 | }; |
| 312 | 319 | ||
| 313 | static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) | 320 | static void __add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type) |
| @@ -462,7 +469,7 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi) | |||
| 462 | if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG)) | 469 | if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG)) |
| 463 | return; | 470 | return; |
| 464 | 471 | ||
| 465 | sbi->por_doing = true; | 472 | set_sbi_flag(sbi, SBI_POR_DOING); |
| 466 | 473 | ||
| 467 | start_blk = __start_cp_addr(sbi) + 1 + | 474 | start_blk = __start_cp_addr(sbi) + 1 + |
| 468 | le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); | 475 | le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload); |
| @@ -483,7 +490,7 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi) | |||
| 483 | } | 490 | } |
| 484 | /* clear Orphan Flag */ | 491 | /* clear Orphan Flag */ |
| 485 | clear_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG); | 492 | clear_ckpt_flags(F2FS_CKPT(sbi), CP_ORPHAN_PRESENT_FLAG); |
| 486 | sbi->por_doing = false; | 493 | clear_sbi_flag(sbi, SBI_POR_DOING); |
| 487 | return; | 494 | return; |
| 488 | } | 495 | } |
| 489 | 496 | ||
| @@ -567,7 +574,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, | |||
| 567 | if (crc_offset >= blk_size) | 574 | if (crc_offset >= blk_size) |
| 568 | goto invalid_cp1; | 575 | goto invalid_cp1; |
| 569 | 576 | ||
| 570 | crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset))); | 577 | crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset))); |
| 571 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) | 578 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) |
| 572 | goto invalid_cp1; | 579 | goto invalid_cp1; |
| 573 | 580 | ||
| @@ -582,7 +589,7 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, | |||
| 582 | if (crc_offset >= blk_size) | 589 | if (crc_offset >= blk_size) |
| 583 | goto invalid_cp2; | 590 | goto invalid_cp2; |
| 584 | 591 | ||
| 585 | crc = le32_to_cpu(*((__u32 *)((unsigned char *)cp_block + crc_offset))); | 592 | crc = le32_to_cpu(*((__le32 *)((unsigned char *)cp_block + crc_offset))); |
| 586 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) | 593 | if (!f2fs_crc_valid(crc, cp_block, crc_offset)) |
| 587 | goto invalid_cp2; | 594 | goto invalid_cp2; |
| 588 | 595 | ||
| @@ -669,7 +676,7 @@ fail_no_cp: | |||
| 669 | return -EINVAL; | 676 | return -EINVAL; |
| 670 | } | 677 | } |
| 671 | 678 | ||
| 672 | static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new) | 679 | static int __add_dirty_inode(struct inode *inode, struct inode_entry *new) |
| 673 | { | 680 | { |
| 674 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 681 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
| 675 | 682 | ||
| @@ -686,7 +693,7 @@ static int __add_dirty_inode(struct inode *inode, struct dir_inode_entry *new) | |||
| 686 | void update_dirty_page(struct inode *inode, struct page *page) | 693 | void update_dirty_page(struct inode *inode, struct page *page) |
| 687 | { | 694 | { |
| 688 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 695 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
| 689 | struct dir_inode_entry *new; | 696 | struct inode_entry *new; |
| 690 | int ret = 0; | 697 | int ret = 0; |
| 691 | 698 | ||
| 692 | if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode)) | 699 | if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode)) |
| @@ -710,12 +717,13 @@ void update_dirty_page(struct inode *inode, struct page *page) | |||
| 710 | kmem_cache_free(inode_entry_slab, new); | 717 | kmem_cache_free(inode_entry_slab, new); |
| 711 | out: | 718 | out: |
| 712 | SetPagePrivate(page); | 719 | SetPagePrivate(page); |
| 720 | f2fs_trace_pid(page); | ||
| 713 | } | 721 | } |
| 714 | 722 | ||
| 715 | void add_dirty_dir_inode(struct inode *inode) | 723 | void add_dirty_dir_inode(struct inode *inode) |
| 716 | { | 724 | { |
| 717 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 725 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
| 718 | struct dir_inode_entry *new = | 726 | struct inode_entry *new = |
| 719 | f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); | 727 | f2fs_kmem_cache_alloc(inode_entry_slab, GFP_NOFS); |
| 720 | int ret = 0; | 728 | int ret = 0; |
| 721 | 729 | ||
| @@ -733,7 +741,7 @@ void add_dirty_dir_inode(struct inode *inode) | |||
| 733 | void remove_dirty_dir_inode(struct inode *inode) | 741 | void remove_dirty_dir_inode(struct inode *inode) |
| 734 | { | 742 | { |
| 735 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); | 743 | struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
| 736 | struct dir_inode_entry *entry; | 744 | struct inode_entry *entry; |
| 737 | 745 | ||
| 738 | if (!S_ISDIR(inode->i_mode)) | 746 | if (!S_ISDIR(inode->i_mode)) |
| 739 | return; | 747 | return; |
| @@ -763,7 +771,7 @@ void remove_dirty_dir_inode(struct inode *inode) | |||
| 763 | void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) | 771 | void sync_dirty_dir_inodes(struct f2fs_sb_info *sbi) |
| 764 | { | 772 | { |
| 765 | struct list_head *head; | 773 | struct list_head *head; |
| 766 | struct dir_inode_entry *entry; | 774 | struct inode_entry *entry; |
| 767 | struct inode *inode; | 775 | struct inode *inode; |
| 768 | retry: | 776 | retry: |
| 769 | if (unlikely(f2fs_cp_error(sbi))) | 777 | if (unlikely(f2fs_cp_error(sbi))) |
| @@ -776,7 +784,7 @@ retry: | |||
| 776 | spin_unlock(&sbi->dir_inode_lock); | 784 | spin_unlock(&sbi->dir_inode_lock); |
| 777 | return; | 785 | return; |
| 778 | } | 786 | } |
| 779 | entry = list_entry(head->next, struct dir_inode_entry, list); | 787 | entry = list_entry(head->next, struct inode_entry, list); |
| 780 | inode = igrab(entry->inode); | 788 | inode = igrab(entry->inode); |
| 781 | spin_unlock(&sbi->dir_inode_lock); | 789 | spin_unlock(&sbi->dir_inode_lock); |
| 782 | if (inode) { | 790 | if (inode) { |
| @@ -922,7 +930,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 922 | ckpt->next_free_nid = cpu_to_le32(last_nid); | 930 | ckpt->next_free_nid = cpu_to_le32(last_nid); |
| 923 | 931 | ||
| 924 | /* 2 cp + n data seg summary + orphan inode blocks */ | 932 | /* 2 cp + n data seg summary + orphan inode blocks */ |
| 925 | data_sum_blocks = npages_for_summary_flush(sbi); | 933 | data_sum_blocks = npages_for_summary_flush(sbi, false); |
| 926 | if (data_sum_blocks < NR_CURSEG_DATA_TYPE) | 934 | if (data_sum_blocks < NR_CURSEG_DATA_TYPE) |
| 927 | set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); | 935 | set_ckpt_flags(ckpt, CP_COMPACT_SUM_FLAG); |
| 928 | else | 936 | else |
| @@ -932,24 +940,31 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 932 | ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + | 940 | ckpt->cp_pack_start_sum = cpu_to_le32(1 + cp_payload_blks + |
| 933 | orphan_blocks); | 941 | orphan_blocks); |
| 934 | 942 | ||
| 935 | if (cpc->reason == CP_UMOUNT) { | 943 | if (__remain_node_summaries(cpc->reason)) |
| 936 | set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
| 937 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+ | 944 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS+ |
| 938 | cp_payload_blks + data_sum_blocks + | 945 | cp_payload_blks + data_sum_blocks + |
| 939 | orphan_blocks + NR_CURSEG_NODE_TYPE); | 946 | orphan_blocks + NR_CURSEG_NODE_TYPE); |
| 940 | } else { | 947 | else |
| 941 | clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
| 942 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS + | 948 | ckpt->cp_pack_total_block_count = cpu_to_le32(F2FS_CP_PACKS + |
| 943 | cp_payload_blks + data_sum_blocks + | 949 | cp_payload_blks + data_sum_blocks + |
| 944 | orphan_blocks); | 950 | orphan_blocks); |
| 945 | } | 951 | |
| 952 | if (cpc->reason == CP_UMOUNT) | ||
| 953 | set_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
| 954 | else | ||
| 955 | clear_ckpt_flags(ckpt, CP_UMOUNT_FLAG); | ||
| 956 | |||
| 957 | if (cpc->reason == CP_FASTBOOT) | ||
| 958 | set_ckpt_flags(ckpt, CP_FASTBOOT_FLAG); | ||
| 959 | else | ||
| 960 | clear_ckpt_flags(ckpt, CP_FASTBOOT_FLAG); | ||
| 946 | 961 | ||
| 947 | if (orphan_num) | 962 | if (orphan_num) |
| 948 | set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); | 963 | set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); |
| 949 | else | 964 | else |
| 950 | clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); | 965 | clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); |
| 951 | 966 | ||
| 952 | if (sbi->need_fsck) | 967 | if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) |
| 953 | set_ckpt_flags(ckpt, CP_FSCK_FLAG); | 968 | set_ckpt_flags(ckpt, CP_FSCK_FLAG); |
| 954 | 969 | ||
| 955 | /* update SIT/NAT bitmap */ | 970 | /* update SIT/NAT bitmap */ |
| @@ -966,15 +981,14 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 966 | /* write out checkpoint buffer at block 0 */ | 981 | /* write out checkpoint buffer at block 0 */ |
| 967 | cp_page = grab_meta_page(sbi, start_blk++); | 982 | cp_page = grab_meta_page(sbi, start_blk++); |
| 968 | kaddr = page_address(cp_page); | 983 | kaddr = page_address(cp_page); |
| 969 | memcpy(kaddr, ckpt, (1 << sbi->log_blocksize)); | 984 | memcpy(kaddr, ckpt, F2FS_BLKSIZE); |
| 970 | set_page_dirty(cp_page); | 985 | set_page_dirty(cp_page); |
| 971 | f2fs_put_page(cp_page, 1); | 986 | f2fs_put_page(cp_page, 1); |
| 972 | 987 | ||
| 973 | for (i = 1; i < 1 + cp_payload_blks; i++) { | 988 | for (i = 1; i < 1 + cp_payload_blks; i++) { |
| 974 | cp_page = grab_meta_page(sbi, start_blk++); | 989 | cp_page = grab_meta_page(sbi, start_blk++); |
| 975 | kaddr = page_address(cp_page); | 990 | kaddr = page_address(cp_page); |
| 976 | memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, | 991 | memcpy(kaddr, (char *)ckpt + i * F2FS_BLKSIZE, F2FS_BLKSIZE); |
| 977 | (1 << sbi->log_blocksize)); | ||
| 978 | set_page_dirty(cp_page); | 992 | set_page_dirty(cp_page); |
| 979 | f2fs_put_page(cp_page, 1); | 993 | f2fs_put_page(cp_page, 1); |
| 980 | } | 994 | } |
| @@ -986,7 +1000,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 986 | 1000 | ||
| 987 | write_data_summaries(sbi, start_blk); | 1001 | write_data_summaries(sbi, start_blk); |
| 988 | start_blk += data_sum_blocks; | 1002 | start_blk += data_sum_blocks; |
| 989 | if (cpc->reason == CP_UMOUNT) { | 1003 | if (__remain_node_summaries(cpc->reason)) { |
| 990 | write_node_summaries(sbi, start_blk); | 1004 | write_node_summaries(sbi, start_blk); |
| 991 | start_blk += NR_CURSEG_NODE_TYPE; | 1005 | start_blk += NR_CURSEG_NODE_TYPE; |
| 992 | } | 1006 | } |
| @@ -994,7 +1008,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 994 | /* writeout checkpoint block */ | 1008 | /* writeout checkpoint block */ |
| 995 | cp_page = grab_meta_page(sbi, start_blk); | 1009 | cp_page = grab_meta_page(sbi, start_blk); |
| 996 | kaddr = page_address(cp_page); | 1010 | kaddr = page_address(cp_page); |
| 997 | memcpy(kaddr, ckpt, (1 << sbi->log_blocksize)); | 1011 | memcpy(kaddr, ckpt, F2FS_BLKSIZE); |
| 998 | set_page_dirty(cp_page); | 1012 | set_page_dirty(cp_page); |
| 999 | f2fs_put_page(cp_page, 1); | 1013 | f2fs_put_page(cp_page, 1); |
| 1000 | 1014 | ||
| @@ -1023,7 +1037,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 1023 | return; | 1037 | return; |
| 1024 | 1038 | ||
| 1025 | clear_prefree_segments(sbi); | 1039 | clear_prefree_segments(sbi); |
| 1026 | F2FS_RESET_SB_DIRT(sbi); | 1040 | clear_sbi_flag(sbi, SBI_IS_DIRTY); |
| 1027 | } | 1041 | } |
| 1028 | 1042 | ||
| 1029 | /* | 1043 | /* |
| @@ -1038,10 +1052,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
| 1038 | 1052 | ||
| 1039 | mutex_lock(&sbi->cp_mutex); | 1053 | mutex_lock(&sbi->cp_mutex); |
| 1040 | 1054 | ||
| 1041 | if (!sbi->s_dirty && cpc->reason != CP_DISCARD) | 1055 | if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) && |
| 1056 | cpc->reason != CP_DISCARD && cpc->reason != CP_UMOUNT) | ||
| 1042 | goto out; | 1057 | goto out; |
| 1043 | if (unlikely(f2fs_cp_error(sbi))) | 1058 | if (unlikely(f2fs_cp_error(sbi))) |
| 1044 | goto out; | 1059 | goto out; |
| 1060 | if (f2fs_readonly(sbi->sb)) | ||
| 1061 | goto out; | ||
| 1045 | if (block_operations(sbi)) | 1062 | if (block_operations(sbi)) |
| 1046 | goto out; | 1063 | goto out; |
| 1047 | 1064 | ||
| @@ -1102,8 +1119,8 @@ int __init create_checkpoint_caches(void) | |||
| 1102 | sizeof(struct ino_entry)); | 1119 | sizeof(struct ino_entry)); |
| 1103 | if (!ino_entry_slab) | 1120 | if (!ino_entry_slab) |
| 1104 | return -ENOMEM; | 1121 | return -ENOMEM; |
| 1105 | inode_entry_slab = f2fs_kmem_cache_create("f2fs_dirty_dir_entry", | 1122 | inode_entry_slab = f2fs_kmem_cache_create("f2fs_inode_entry", |
| 1106 | sizeof(struct dir_inode_entry)); | 1123 | sizeof(struct inode_entry)); |
| 1107 | if (!inode_entry_slab) { | 1124 | if (!inode_entry_slab) { |
| 1108 | kmem_cache_destroy(ino_entry_slab); | 1125 | kmem_cache_destroy(ino_entry_slab); |
| 1109 | return -ENOMEM; | 1126 | return -ENOMEM; |
