diff options
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r-- | fs/f2fs/checkpoint.c | 107 |
1 files changed, 46 insertions, 61 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index ed70b68b2b38..a0eef95b9e0e 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -146,8 +146,8 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, | |||
146 | 146 | ||
147 | exist = f2fs_test_bit(offset, se->cur_valid_map); | 147 | exist = f2fs_test_bit(offset, se->cur_valid_map); |
148 | if (!exist && type == DATA_GENERIC_ENHANCE) { | 148 | if (!exist && type == DATA_GENERIC_ENHANCE) { |
149 | f2fs_msg(sbi->sb, KERN_ERR, "Inconsistent error " | 149 | f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d", |
150 | "blkaddr:%u, sit bitmap:%d", blkaddr, exist); | 150 | blkaddr, exist); |
151 | set_sbi_flag(sbi, SBI_NEED_FSCK); | 151 | set_sbi_flag(sbi, SBI_NEED_FSCK); |
152 | WARN_ON(1); | 152 | WARN_ON(1); |
153 | } | 153 | } |
@@ -184,8 +184,8 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, | |||
184 | case DATA_GENERIC_ENHANCE_READ: | 184 | case DATA_GENERIC_ENHANCE_READ: |
185 | if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || | 185 | if (unlikely(blkaddr >= MAX_BLKADDR(sbi) || |
186 | blkaddr < MAIN_BLKADDR(sbi))) { | 186 | blkaddr < MAIN_BLKADDR(sbi))) { |
187 | f2fs_msg(sbi->sb, KERN_WARNING, | 187 | f2fs_warn(sbi, "access invalid blkaddr:%u", |
188 | "access invalid blkaddr:%u", blkaddr); | 188 | blkaddr); |
189 | set_sbi_flag(sbi, SBI_NEED_FSCK); | 189 | set_sbi_flag(sbi, SBI_NEED_FSCK); |
190 | WARN_ON(1); | 190 | WARN_ON(1); |
191 | return false; | 191 | return false; |
@@ -657,9 +657,8 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) | |||
657 | 657 | ||
658 | err_out: | 658 | err_out: |
659 | set_sbi_flag(sbi, SBI_NEED_FSCK); | 659 | set_sbi_flag(sbi, SBI_NEED_FSCK); |
660 | f2fs_msg(sbi->sb, KERN_WARNING, | 660 | f2fs_warn(sbi, "%s: orphan failed (ino=%x), run fsck to fix.", |
661 | "%s: orphan failed (ino=%x), run fsck to fix.", | 661 | __func__, ino); |
662 | __func__, ino); | ||
663 | return err; | 662 | return err; |
664 | } | 663 | } |
665 | 664 | ||
@@ -676,13 +675,12 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) | |||
676 | return 0; | 675 | return 0; |
677 | 676 | ||
678 | if (bdev_read_only(sbi->sb->s_bdev)) { | 677 | if (bdev_read_only(sbi->sb->s_bdev)) { |
679 | f2fs_msg(sbi->sb, KERN_INFO, "write access " | 678 | f2fs_info(sbi, "write access unavailable, skipping orphan cleanup"); |
680 | "unavailable, skipping orphan cleanup"); | ||
681 | return 0; | 679 | return 0; |
682 | } | 680 | } |
683 | 681 | ||
684 | if (s_flags & SB_RDONLY) { | 682 | if (s_flags & SB_RDONLY) { |
685 | f2fs_msg(sbi->sb, KERN_INFO, "orphan cleanup on readonly fs"); | 683 | f2fs_info(sbi, "orphan cleanup on readonly fs"); |
686 | sbi->sb->s_flags &= ~SB_RDONLY; | 684 | sbi->sb->s_flags &= ~SB_RDONLY; |
687 | } | 685 | } |
688 | 686 | ||
@@ -827,26 +825,14 @@ static int get_checkpoint_version(struct f2fs_sb_info *sbi, block_t cp_addr, | |||
827 | if (crc_offset < CP_MIN_CHKSUM_OFFSET || | 825 | if (crc_offset < CP_MIN_CHKSUM_OFFSET || |
828 | crc_offset > CP_CHKSUM_OFFSET) { | 826 | crc_offset > CP_CHKSUM_OFFSET) { |
829 | f2fs_put_page(*cp_page, 1); | 827 | f2fs_put_page(*cp_page, 1); |
830 | f2fs_msg(sbi->sb, KERN_WARNING, | 828 | f2fs_warn(sbi, "invalid crc_offset: %zu", crc_offset); |
831 | "invalid crc_offset: %zu", crc_offset); | ||
832 | return -EINVAL; | 829 | return -EINVAL; |
833 | } | 830 | } |
834 | 831 | ||
835 | if (__is_set_ckpt_flags(*cp_block, CP_LARGE_NAT_BITMAP_FLAG)) { | ||
836 | if (crc_offset != CP_MIN_CHKSUM_OFFSET) { | ||
837 | f2fs_put_page(*cp_page, 1); | ||
838 | f2fs_msg(sbi->sb, KERN_WARNING, | ||
839 | "layout of large_nat_bitmap is deprecated, " | ||
840 | "run fsck to repair, chksum_offset: %zu", | ||
841 | crc_offset); | ||
842 | return -EINVAL; | ||
843 | } | ||
844 | } | ||
845 | |||
846 | crc = f2fs_checkpoint_chksum(sbi, *cp_block); | 832 | crc = f2fs_checkpoint_chksum(sbi, *cp_block); |
847 | if (crc != cur_cp_crc(*cp_block)) { | 833 | if (crc != cur_cp_crc(*cp_block)) { |
848 | f2fs_put_page(*cp_page, 1); | 834 | f2fs_put_page(*cp_page, 1); |
849 | f2fs_msg(sbi->sb, KERN_WARNING, "invalid crc value"); | 835 | f2fs_warn(sbi, "invalid crc value"); |
850 | return -EINVAL; | 836 | return -EINVAL; |
851 | } | 837 | } |
852 | 838 | ||
@@ -869,9 +855,8 @@ static struct page *validate_checkpoint(struct f2fs_sb_info *sbi, | |||
869 | 855 | ||
870 | if (le32_to_cpu(cp_block->cp_pack_total_block_count) > | 856 | if (le32_to_cpu(cp_block->cp_pack_total_block_count) > |
871 | sbi->blocks_per_seg) { | 857 | sbi->blocks_per_seg) { |
872 | f2fs_msg(sbi->sb, KERN_WARNING, | 858 | f2fs_warn(sbi, "invalid cp_pack_total_block_count:%u", |
873 | "invalid cp_pack_total_block_count:%u", | 859 | le32_to_cpu(cp_block->cp_pack_total_block_count)); |
874 | le32_to_cpu(cp_block->cp_pack_total_block_count)); | ||
875 | goto invalid_cp; | 860 | goto invalid_cp; |
876 | } | 861 | } |
877 | pre_version = *version; | 862 | pre_version = *version; |
@@ -905,6 +890,7 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) | |||
905 | unsigned int cp_blks = 1 + __cp_payload(sbi); | 890 | unsigned int cp_blks = 1 + __cp_payload(sbi); |
906 | block_t cp_blk_no; | 891 | block_t cp_blk_no; |
907 | int i; | 892 | int i; |
893 | int err; | ||
908 | 894 | ||
909 | sbi->ckpt = f2fs_kzalloc(sbi, array_size(blk_size, cp_blks), | 895 | sbi->ckpt = f2fs_kzalloc(sbi, array_size(blk_size, cp_blks), |
910 | GFP_KERNEL); | 896 | GFP_KERNEL); |
@@ -932,6 +918,7 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) | |||
932 | } else if (cp2) { | 918 | } else if (cp2) { |
933 | cur_page = cp2; | 919 | cur_page = cp2; |
934 | } else { | 920 | } else { |
921 | err = -EFSCORRUPTED; | ||
935 | goto fail_no_cp; | 922 | goto fail_no_cp; |
936 | } | 923 | } |
937 | 924 | ||
@@ -944,8 +931,10 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) | |||
944 | sbi->cur_cp_pack = 2; | 931 | sbi->cur_cp_pack = 2; |
945 | 932 | ||
946 | /* Sanity checking of checkpoint */ | 933 | /* Sanity checking of checkpoint */ |
947 | if (f2fs_sanity_check_ckpt(sbi)) | 934 | if (f2fs_sanity_check_ckpt(sbi)) { |
935 | err = -EFSCORRUPTED; | ||
948 | goto free_fail_no_cp; | 936 | goto free_fail_no_cp; |
937 | } | ||
949 | 938 | ||
950 | if (cp_blks <= 1) | 939 | if (cp_blks <= 1) |
951 | goto done; | 940 | goto done; |
@@ -959,8 +948,10 @@ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi) | |||
959 | unsigned char *ckpt = (unsigned char *)sbi->ckpt; | 948 | unsigned char *ckpt = (unsigned char *)sbi->ckpt; |
960 | 949 | ||
961 | cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i); | 950 | cur_page = f2fs_get_meta_page(sbi, cp_blk_no + i); |
962 | if (IS_ERR(cur_page)) | 951 | if (IS_ERR(cur_page)) { |
952 | err = PTR_ERR(cur_page); | ||
963 | goto free_fail_no_cp; | 953 | goto free_fail_no_cp; |
954 | } | ||
964 | sit_bitmap_ptr = page_address(cur_page); | 955 | sit_bitmap_ptr = page_address(cur_page); |
965 | memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); | 956 | memcpy(ckpt + i * blk_size, sit_bitmap_ptr, blk_size); |
966 | f2fs_put_page(cur_page, 1); | 957 | f2fs_put_page(cur_page, 1); |
@@ -975,7 +966,7 @@ free_fail_no_cp: | |||
975 | f2fs_put_page(cp2, 1); | 966 | f2fs_put_page(cp2, 1); |
976 | fail_no_cp: | 967 | fail_no_cp: |
977 | kvfree(sbi->ckpt); | 968 | kvfree(sbi->ckpt); |
978 | return -EINVAL; | 969 | return err; |
979 | } | 970 | } |
980 | 971 | ||
981 | static void __add_dirty_inode(struct inode *inode, enum inode_type type) | 972 | static void __add_dirty_inode(struct inode *inode, enum inode_type type) |
@@ -1142,17 +1133,24 @@ static void __prepare_cp_block(struct f2fs_sb_info *sbi) | |||
1142 | 1133 | ||
1143 | static bool __need_flush_quota(struct f2fs_sb_info *sbi) | 1134 | static bool __need_flush_quota(struct f2fs_sb_info *sbi) |
1144 | { | 1135 | { |
1136 | bool ret = false; | ||
1137 | |||
1145 | if (!is_journalled_quota(sbi)) | 1138 | if (!is_journalled_quota(sbi)) |
1146 | return false; | 1139 | return false; |
1147 | if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH)) | 1140 | |
1148 | return false; | 1141 | down_write(&sbi->quota_sem); |
1149 | if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR)) | 1142 | if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH)) { |
1150 | return false; | 1143 | ret = false; |
1151 | if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_FLUSH)) | 1144 | } else if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR)) { |
1152 | return true; | 1145 | ret = false; |
1153 | if (get_pages(sbi, F2FS_DIRTY_QDATA)) | 1146 | } else if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_FLUSH)) { |
1154 | return true; | 1147 | clear_sbi_flag(sbi, SBI_QUOTA_NEED_FLUSH); |
1155 | return false; | 1148 | ret = true; |
1149 | } else if (get_pages(sbi, F2FS_DIRTY_QDATA)) { | ||
1150 | ret = true; | ||
1151 | } | ||
1152 | up_write(&sbi->quota_sem); | ||
1153 | return ret; | ||
1156 | } | 1154 | } |
1157 | 1155 | ||
1158 | /* | 1156 | /* |
@@ -1171,26 +1169,22 @@ static int block_operations(struct f2fs_sb_info *sbi) | |||
1171 | blk_start_plug(&plug); | 1169 | blk_start_plug(&plug); |
1172 | 1170 | ||
1173 | retry_flush_quotas: | 1171 | retry_flush_quotas: |
1172 | f2fs_lock_all(sbi); | ||
1174 | if (__need_flush_quota(sbi)) { | 1173 | if (__need_flush_quota(sbi)) { |
1175 | int locked; | 1174 | int locked; |
1176 | 1175 | ||
1177 | if (++cnt > DEFAULT_RETRY_QUOTA_FLUSH_COUNT) { | 1176 | if (++cnt > DEFAULT_RETRY_QUOTA_FLUSH_COUNT) { |
1178 | set_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH); | 1177 | set_sbi_flag(sbi, SBI_QUOTA_SKIP_FLUSH); |
1179 | f2fs_lock_all(sbi); | 1178 | set_sbi_flag(sbi, SBI_QUOTA_NEED_FLUSH); |
1180 | goto retry_flush_dents; | 1179 | goto retry_flush_dents; |
1181 | } | 1180 | } |
1182 | clear_sbi_flag(sbi, SBI_QUOTA_NEED_FLUSH); | 1181 | f2fs_unlock_all(sbi); |
1183 | 1182 | ||
1184 | /* only failed during mount/umount/freeze/quotactl */ | 1183 | /* only failed during mount/umount/freeze/quotactl */ |
1185 | locked = down_read_trylock(&sbi->sb->s_umount); | 1184 | locked = down_read_trylock(&sbi->sb->s_umount); |
1186 | f2fs_quota_sync(sbi->sb, -1); | 1185 | f2fs_quota_sync(sbi->sb, -1); |
1187 | if (locked) | 1186 | if (locked) |
1188 | up_read(&sbi->sb->s_umount); | 1187 | up_read(&sbi->sb->s_umount); |
1189 | } | ||
1190 | |||
1191 | f2fs_lock_all(sbi); | ||
1192 | if (__need_flush_quota(sbi)) { | ||
1193 | f2fs_unlock_all(sbi); | ||
1194 | cond_resched(); | 1188 | cond_resched(); |
1195 | goto retry_flush_quotas; | 1189 | goto retry_flush_quotas; |
1196 | } | 1190 | } |
@@ -1212,12 +1206,6 @@ retry_flush_dents: | |||
1212 | */ | 1206 | */ |
1213 | down_write(&sbi->node_change); | 1207 | down_write(&sbi->node_change); |
1214 | 1208 | ||
1215 | if (__need_flush_quota(sbi)) { | ||
1216 | up_write(&sbi->node_change); | ||
1217 | f2fs_unlock_all(sbi); | ||
1218 | goto retry_flush_quotas; | ||
1219 | } | ||
1220 | |||
1221 | if (get_pages(sbi, F2FS_DIRTY_IMETA)) { | 1209 | if (get_pages(sbi, F2FS_DIRTY_IMETA)) { |
1222 | up_write(&sbi->node_change); | 1210 | up_write(&sbi->node_change); |
1223 | f2fs_unlock_all(sbi); | 1211 | f2fs_unlock_all(sbi); |
@@ -1313,7 +1301,8 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1313 | else | 1301 | else |
1314 | __clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); | 1302 | __clear_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG); |
1315 | 1303 | ||
1316 | if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) | 1304 | if (is_sbi_flag_set(sbi, SBI_NEED_FSCK) || |
1305 | is_sbi_flag_set(sbi, SBI_IS_RESIZEFS)) | ||
1317 | __set_ckpt_flags(ckpt, CP_FSCK_FLAG); | 1306 | __set_ckpt_flags(ckpt, CP_FSCK_FLAG); |
1318 | 1307 | ||
1319 | if (is_sbi_flag_set(sbi, SBI_CP_DISABLED)) | 1308 | if (is_sbi_flag_set(sbi, SBI_CP_DISABLED)) |
@@ -1328,10 +1317,8 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1328 | 1317 | ||
1329 | if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH)) | 1318 | if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH)) |
1330 | __set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG); | 1319 | __set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG); |
1331 | /* | 1320 | else |
1332 | * TODO: we count on fsck.f2fs to clear this flag until we figure out | 1321 | __clear_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG); |
1333 | * missing cases which clear it incorrectly. | ||
1334 | */ | ||
1335 | 1322 | ||
1336 | if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR)) | 1323 | if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR)) |
1337 | __set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG); | 1324 | __set_ckpt_flags(ckpt, CP_QUOTA_NEED_FSCK_FLAG); |
@@ -1571,8 +1558,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) | |||
1571 | if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { | 1558 | if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { |
1572 | if (cpc->reason != CP_PAUSE) | 1559 | if (cpc->reason != CP_PAUSE) |
1573 | return 0; | 1560 | return 0; |
1574 | f2fs_msg(sbi->sb, KERN_WARNING, | 1561 | f2fs_warn(sbi, "Start checkpoint disabled!"); |
1575 | "Start checkpoint disabled!"); | ||
1576 | } | 1562 | } |
1577 | mutex_lock(&sbi->cp_mutex); | 1563 | mutex_lock(&sbi->cp_mutex); |
1578 | 1564 | ||
@@ -1638,8 +1624,7 @@ stop: | |||
1638 | stat_inc_cp_count(sbi->stat_info); | 1624 | stat_inc_cp_count(sbi->stat_info); |
1639 | 1625 | ||
1640 | if (cpc->reason & CP_RECOVERY) | 1626 | if (cpc->reason & CP_RECOVERY) |
1641 | f2fs_msg(sbi->sb, KERN_NOTICE, | 1627 | f2fs_notice(sbi, "checkpoint: version = %llx", ckpt_ver); |
1642 | "checkpoint: version = %llx", ckpt_ver); | ||
1643 | 1628 | ||
1644 | /* do checkpoint periodically */ | 1629 | /* do checkpoint periodically */ |
1645 | f2fs_update_time(sbi, CP_TIME); | 1630 | f2fs_update_time(sbi, CP_TIME); |