OSDN Git Service

Merge 4.4.179 into android-4.4-p
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / f2fs / super.c
index a622eb4..814c4fe 100644 (file)
@@ -740,6 +740,10 @@ static int parse_options(struct super_block *sb, char *options)
                        } else if (strlen(name) == 6 &&
                                        !strncmp(name, "strict", 6)) {
                                F2FS_OPTION(sbi).fsync_mode = FSYNC_MODE_STRICT;
+                       } else if (strlen(name) == 9 &&
+                                       !strncmp(name, "nobarrier", 9)) {
+                               F2FS_OPTION(sbi).fsync_mode =
+                                                       FSYNC_MODE_NOBARRIER;
                        } else {
                                kfree(name);
                                return -EINVAL;
@@ -2228,12 +2232,17 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
        struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
        unsigned int ovp_segments, reserved_segments;
        unsigned int main_segs, blocks_per_seg;
-       int i;
+       unsigned int sit_segs, nat_segs;
+       unsigned int sit_bitmap_size, nat_bitmap_size;
+       unsigned int log_blocks_per_seg;
+       int i, j;
 
        total = le32_to_cpu(raw_super->segment_count);
        fsmeta = le32_to_cpu(raw_super->segment_count_ckpt);
-       fsmeta += le32_to_cpu(raw_super->segment_count_sit);
-       fsmeta += le32_to_cpu(raw_super->segment_count_nat);
+       sit_segs = le32_to_cpu(raw_super->segment_count_sit);
+       fsmeta += sit_segs;
+       nat_segs = le32_to_cpu(raw_super->segment_count_nat);
+       fsmeta += nat_segs;
        fsmeta += le32_to_cpu(ckpt->rsvd_segment_count);
        fsmeta += le32_to_cpu(raw_super->segment_count_ssa);
 
@@ -2257,11 +2266,55 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
                if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs ||
                        le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg)
                        return 1;
+               for (j = i + 1; j < NR_CURSEG_NODE_TYPE; j++) {
+                       if (le32_to_cpu(ckpt->cur_node_segno[i]) ==
+                               le32_to_cpu(ckpt->cur_node_segno[j])) {
+                               f2fs_msg(sbi->sb, KERN_ERR,
+                                       "Node segment (%u, %u) has the same "
+                                       "segno: %u", i, j,
+                                       le32_to_cpu(ckpt->cur_node_segno[i]));
+                               return 1;
+                       }
+               }
        }
        for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) {
                if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs ||
                        le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg)
                        return 1;
+               for (j = i + 1; j < NR_CURSEG_DATA_TYPE; j++) {
+                       if (le32_to_cpu(ckpt->cur_data_segno[i]) ==
+                               le32_to_cpu(ckpt->cur_data_segno[j])) {
+                               f2fs_msg(sbi->sb, KERN_ERR,
+                                       "Data segment (%u, %u) has the same "
+                                       "segno: %u", i, j,
+                                       le32_to_cpu(ckpt->cur_data_segno[i]));
+                               return 1;
+                       }
+               }
+       }
+       for (i = 0; i < NR_CURSEG_NODE_TYPE; i++) {
+               for (j = i; j < NR_CURSEG_DATA_TYPE; j++) {
+                       if (le32_to_cpu(ckpt->cur_node_segno[i]) ==
+                               le32_to_cpu(ckpt->cur_data_segno[j])) {
+                               f2fs_msg(sbi->sb, KERN_ERR,
+                                       "Data segment (%u) and Data segment (%u)"
+                                       " has the same segno: %u", i, j,
+                                       le32_to_cpu(ckpt->cur_node_segno[i]));
+                               return 1;
+                       }
+               }
+       }
+
+       sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize);
+       nat_bitmap_size = le32_to_cpu(ckpt->nat_ver_bitmap_bytesize);
+       log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
+
+       if (sit_bitmap_size != ((sit_segs / 2) << log_blocks_per_seg) / 8 ||
+               nat_bitmap_size != ((nat_segs / 2) << log_blocks_per_seg) / 8) {
+               f2fs_msg(sbi->sb, KERN_ERR,
+                       "Wrong bitmap size: sit: %u, nat:%u",
+                       sit_bitmap_size, nat_bitmap_size);
+               return 1;
        }
 
        if (unlikely(f2fs_cp_error(sbi))) {
@@ -3071,6 +3124,12 @@ static int __init init_f2fs_fs(void)
 {
        int err;
 
+       if (PAGE_SIZE != F2FS_BLKSIZE) {
+               printk("F2FS not supported on PAGE_SIZE(%lu) != %d\n",
+                               PAGE_SIZE, F2FS_BLKSIZE);
+               return -EINVAL;
+       }
+
        f2fs_build_trace_ios();
 
        err = init_inodecache();
@@ -3100,8 +3159,13 @@ static int __init init_f2fs_fs(void)
        err = f2fs_create_root_stats();
        if (err)
                goto free_filesystem;
+       err = f2fs_init_post_read_processing();
+       if (err)
+               goto free_root_stats;
        return 0;
 
+free_root_stats:
+       f2fs_destroy_root_stats();
 free_filesystem:
        unregister_filesystem(&f2fs_fs_type);
 free_shrinker:
@@ -3124,6 +3188,7 @@ fail:
 
 static void __exit exit_f2fs_fs(void)
 {
+       f2fs_destroy_post_read_processing();
        f2fs_destroy_root_stats();
        unregister_filesystem(&f2fs_fs_type);
        unregister_shrinker(&f2fs_shrinker_info);