diff options
Diffstat (limited to 'fs/f2fs')
-rw-r--r-- | fs/f2fs/super.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 1d7fe11fea30..ddb665f54d17 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -387,7 +387,7 @@ static int sanity_check_raw_super(struct super_block *sb, | |||
387 | /* Currently, support only 4KB page cache size */ | 387 | /* Currently, support only 4KB page cache size */ |
388 | if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) { | 388 | if (F2FS_BLKSIZE != PAGE_CACHE_SIZE) { |
389 | f2fs_msg(sb, KERN_INFO, | 389 | f2fs_msg(sb, KERN_INFO, |
390 | "Invalid page_cache_size (%u), supports only 4KB\n", | 390 | "Invalid page_cache_size (%lu), supports only 4KB\n", |
391 | PAGE_CACHE_SIZE); | 391 | PAGE_CACHE_SIZE); |
392 | return 1; | 392 | return 1; |
393 | } | 393 | } |
@@ -462,6 +462,32 @@ static void init_sb_info(struct f2fs_sb_info *sbi) | |||
462 | atomic_set(&sbi->nr_pages[i], 0); | 462 | atomic_set(&sbi->nr_pages[i], 0); |
463 | } | 463 | } |
464 | 464 | ||
465 | static int validate_superblock(struct super_block *sb, | ||
466 | struct f2fs_super_block **raw_super, | ||
467 | struct buffer_head **raw_super_buf, sector_t block) | ||
468 | { | ||
469 | const char *super = (block == 0 ? "first" : "second"); | ||
470 | |||
471 | /* read f2fs raw super block */ | ||
472 | *raw_super_buf = sb_bread(sb, block); | ||
473 | if (!*raw_super_buf) { | ||
474 | f2fs_msg(sb, KERN_ERR, "unable to read %s superblock", | ||
475 | super); | ||
476 | return 1; | ||
477 | } | ||
478 | |||
479 | *raw_super = (struct f2fs_super_block *) | ||
480 | ((char *)(*raw_super_buf)->b_data + F2FS_SUPER_OFFSET); | ||
481 | |||
482 | /* sanity checking of raw super */ | ||
483 | if (!sanity_check_raw_super(sb, *raw_super)) | ||
484 | return 0; | ||
485 | |||
486 | f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem " | ||
487 | "in %s superblock", super); | ||
488 | return 1; | ||
489 | } | ||
490 | |||
465 | static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | 491 | static int f2fs_fill_super(struct super_block *sb, void *data, int silent) |
466 | { | 492 | { |
467 | struct f2fs_sb_info *sbi; | 493 | struct f2fs_sb_info *sbi; |
@@ -482,16 +508,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
482 | goto free_sbi; | 508 | goto free_sbi; |
483 | } | 509 | } |
484 | 510 | ||
485 | /* read f2fs raw super block */ | 511 | if (validate_superblock(sb, &raw_super, &raw_super_buf, 0)) { |
486 | raw_super_buf = sb_bread(sb, 0); | 512 | brelse(raw_super_buf); |
487 | if (!raw_super_buf) { | 513 | if (validate_superblock(sb, &raw_super, &raw_super_buf, 1)) |
488 | err = -EIO; | 514 | goto free_sb_buf; |
489 | f2fs_msg(sb, KERN_ERR, "unable to read superblock"); | ||
490 | goto free_sbi; | ||
491 | } | 515 | } |
492 | raw_super = (struct f2fs_super_block *) | ||
493 | ((char *)raw_super_buf->b_data + F2FS_SUPER_OFFSET); | ||
494 | |||
495 | /* init some FS parameters */ | 516 | /* init some FS parameters */ |
496 | sbi->active_logs = NR_CURSEG_TYPE; | 517 | sbi->active_logs = NR_CURSEG_TYPE; |
497 | 518 | ||
@@ -507,12 +528,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
507 | if (parse_options(sb, sbi, (char *)data)) | 528 | if (parse_options(sb, sbi, (char *)data)) |
508 | goto free_sb_buf; | 529 | goto free_sb_buf; |
509 | 530 | ||
510 | /* sanity checking of raw super */ | ||
511 | if (sanity_check_raw_super(sb, raw_super)) { | ||
512 | f2fs_msg(sb, KERN_ERR, "Can't find a valid F2FS filesystem"); | ||
513 | goto free_sb_buf; | ||
514 | } | ||
515 | |||
516 | sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); | 531 | sb->s_maxbytes = max_file_size(le32_to_cpu(raw_super->log_blocksize)); |
517 | sb->s_max_links = F2FS_LINK_MAX; | 532 | sb->s_max_links = F2FS_LINK_MAX; |
518 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 533 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |