aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/super.c
diff options
context:
space:
mode:
authorIcenowy Zheng <icenowy@aosc.io>2019-07-24 23:08:52 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2019-07-29 01:59:14 -0400
commit38fb6d0ea34299d97b031ed64fe994158b6f8eb3 (patch)
tree94250e27b6a2b7453443f3ed37d9a724e655b8bd /fs/f2fs/super.c
parent543b8c468f55f27f3c0178a22a91a51aabbbc428 (diff)
f2fs: use EINVAL for superblock with invalid magic
The kernel mount_block_root() function expects -EACESS or -EINVAL for a unmountable filesystem when trying to mount the root with different filesystem types. However, in 5.3-rc1 the behavior when F2FS code cannot find valid block changed to return -EFSCORRUPTED(-EUCLEAN), and this error code makes mount_block_root() fail when trying to probe F2FS. When the magic number of the superblock mismatches, it has a high probability that it's just not a F2FS. In this case return -EINVAL seems to be a better result, and this return value can make mount_block_root() probing work again. Return -EINVAL when the superblock has magic mismatch, -EFSCORRUPTED in other cases (the magic matches but the superblock cannot be recognized). Fixes: 10f966bbf521 ("f2fs: use generic EFSBADCRC/EFSCORRUPTED") Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Reviewed-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r--fs/f2fs/super.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index d95a681ef7c9..1838dd852a50 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2422,6 +2422,12 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2422 size_t crc_offset = 0; 2422 size_t crc_offset = 0;
2423 __u32 crc = 0; 2423 __u32 crc = 0;
2424 2424
2425 if (le32_to_cpu(raw_super->magic) != F2FS_SUPER_MAGIC) {
2426 f2fs_info(sbi, "Magic Mismatch, valid(0x%x) - read(0x%x)",
2427 F2FS_SUPER_MAGIC, le32_to_cpu(raw_super->magic));
2428 return -EINVAL;
2429 }
2430
2425 /* Check checksum_offset and crc in superblock */ 2431 /* Check checksum_offset and crc in superblock */
2426 if (__F2FS_HAS_FEATURE(raw_super, F2FS_FEATURE_SB_CHKSUM)) { 2432 if (__F2FS_HAS_FEATURE(raw_super, F2FS_FEATURE_SB_CHKSUM)) {
2427 crc_offset = le32_to_cpu(raw_super->checksum_offset); 2433 crc_offset = le32_to_cpu(raw_super->checksum_offset);
@@ -2429,26 +2435,20 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2429 offsetof(struct f2fs_super_block, crc)) { 2435 offsetof(struct f2fs_super_block, crc)) {
2430 f2fs_info(sbi, "Invalid SB checksum offset: %zu", 2436 f2fs_info(sbi, "Invalid SB checksum offset: %zu",
2431 crc_offset); 2437 crc_offset);
2432 return 1; 2438 return -EFSCORRUPTED;
2433 } 2439 }
2434 crc = le32_to_cpu(raw_super->crc); 2440 crc = le32_to_cpu(raw_super->crc);
2435 if (!f2fs_crc_valid(sbi, crc, raw_super, crc_offset)) { 2441 if (!f2fs_crc_valid(sbi, crc, raw_super, crc_offset)) {
2436 f2fs_info(sbi, "Invalid SB checksum value: %u", crc); 2442 f2fs_info(sbi, "Invalid SB checksum value: %u", crc);
2437 return 1; 2443 return -EFSCORRUPTED;
2438 } 2444 }
2439 } 2445 }
2440 2446
2441 if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) {
2442 f2fs_info(sbi, "Magic Mismatch, valid(0x%x) - read(0x%x)",
2443 F2FS_SUPER_MAGIC, le32_to_cpu(raw_super->magic));
2444 return 1;
2445 }
2446
2447 /* Currently, support only 4KB page cache size */ 2447 /* Currently, support only 4KB page cache size */
2448 if (F2FS_BLKSIZE != PAGE_SIZE) { 2448 if (F2FS_BLKSIZE != PAGE_SIZE) {
2449 f2fs_info(sbi, "Invalid page_cache_size (%lu), supports only 4KB", 2449 f2fs_info(sbi, "Invalid page_cache_size (%lu), supports only 4KB",
2450 PAGE_SIZE); 2450 PAGE_SIZE);
2451 return 1; 2451 return -EFSCORRUPTED;
2452 } 2452 }
2453 2453
2454 /* Currently, support only 4KB block size */ 2454 /* Currently, support only 4KB block size */
@@ -2456,14 +2456,14 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2456 if (blocksize != F2FS_BLKSIZE) { 2456 if (blocksize != F2FS_BLKSIZE) {
2457 f2fs_info(sbi, "Invalid blocksize (%u), supports only 4KB", 2457 f2fs_info(sbi, "Invalid blocksize (%u), supports only 4KB",
2458 blocksize); 2458 blocksize);
2459 return 1; 2459 return -EFSCORRUPTED;
2460 } 2460 }
2461 2461
2462 /* check log blocks per segment */ 2462 /* check log blocks per segment */
2463 if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) { 2463 if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) {
2464 f2fs_info(sbi, "Invalid log blocks per segment (%u)", 2464 f2fs_info(sbi, "Invalid log blocks per segment (%u)",
2465 le32_to_cpu(raw_super->log_blocks_per_seg)); 2465 le32_to_cpu(raw_super->log_blocks_per_seg));
2466 return 1; 2466 return -EFSCORRUPTED;
2467 } 2467 }
2468 2468
2469 /* Currently, support 512/1024/2048/4096 bytes sector size */ 2469 /* Currently, support 512/1024/2048/4096 bytes sector size */
@@ -2473,7 +2473,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2473 F2FS_MIN_LOG_SECTOR_SIZE) { 2473 F2FS_MIN_LOG_SECTOR_SIZE) {
2474 f2fs_info(sbi, "Invalid log sectorsize (%u)", 2474 f2fs_info(sbi, "Invalid log sectorsize (%u)",
2475 le32_to_cpu(raw_super->log_sectorsize)); 2475 le32_to_cpu(raw_super->log_sectorsize));
2476 return 1; 2476 return -EFSCORRUPTED;
2477 } 2477 }
2478 if (le32_to_cpu(raw_super->log_sectors_per_block) + 2478 if (le32_to_cpu(raw_super->log_sectors_per_block) +
2479 le32_to_cpu(raw_super->log_sectorsize) != 2479 le32_to_cpu(raw_super->log_sectorsize) !=
@@ -2481,7 +2481,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2481 f2fs_info(sbi, "Invalid log sectors per block(%u) log sectorsize(%u)", 2481 f2fs_info(sbi, "Invalid log sectors per block(%u) log sectorsize(%u)",
2482 le32_to_cpu(raw_super->log_sectors_per_block), 2482 le32_to_cpu(raw_super->log_sectors_per_block),
2483 le32_to_cpu(raw_super->log_sectorsize)); 2483 le32_to_cpu(raw_super->log_sectorsize));
2484 return 1; 2484 return -EFSCORRUPTED;
2485 } 2485 }
2486 2486
2487 segment_count = le32_to_cpu(raw_super->segment_count); 2487 segment_count = le32_to_cpu(raw_super->segment_count);
@@ -2495,7 +2495,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2495 if (segment_count > F2FS_MAX_SEGMENT || 2495 if (segment_count > F2FS_MAX_SEGMENT ||
2496 segment_count < F2FS_MIN_SEGMENTS) { 2496 segment_count < F2FS_MIN_SEGMENTS) {
2497 f2fs_info(sbi, "Invalid segment count (%u)", segment_count); 2497 f2fs_info(sbi, "Invalid segment count (%u)", segment_count);
2498 return 1; 2498 return -EFSCORRUPTED;
2499 } 2499 }
2500 2500
2501 if (total_sections > segment_count || 2501 if (total_sections > segment_count ||
@@ -2503,25 +2503,25 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2503 segs_per_sec > segment_count || !segs_per_sec) { 2503 segs_per_sec > segment_count || !segs_per_sec) {
2504 f2fs_info(sbi, "Invalid segment/section count (%u, %u x %u)", 2504 f2fs_info(sbi, "Invalid segment/section count (%u, %u x %u)",
2505 segment_count, total_sections, segs_per_sec); 2505 segment_count, total_sections, segs_per_sec);
2506 return 1; 2506 return -EFSCORRUPTED;
2507 } 2507 }
2508 2508
2509 if ((segment_count / segs_per_sec) < total_sections) { 2509 if ((segment_count / segs_per_sec) < total_sections) {
2510 f2fs_info(sbi, "Small segment_count (%u < %u * %u)", 2510 f2fs_info(sbi, "Small segment_count (%u < %u * %u)",
2511 segment_count, segs_per_sec, total_sections); 2511 segment_count, segs_per_sec, total_sections);
2512 return 1; 2512 return -EFSCORRUPTED;
2513 } 2513 }
2514 2514
2515 if (segment_count > (le64_to_cpu(raw_super->block_count) >> 9)) { 2515 if (segment_count > (le64_to_cpu(raw_super->block_count) >> 9)) {
2516 f2fs_info(sbi, "Wrong segment_count / block_count (%u > %llu)", 2516 f2fs_info(sbi, "Wrong segment_count / block_count (%u > %llu)",
2517 segment_count, le64_to_cpu(raw_super->block_count)); 2517 segment_count, le64_to_cpu(raw_super->block_count));
2518 return 1; 2518 return -EFSCORRUPTED;
2519 } 2519 }
2520 2520
2521 if (secs_per_zone > total_sections || !secs_per_zone) { 2521 if (secs_per_zone > total_sections || !secs_per_zone) {
2522 f2fs_info(sbi, "Wrong secs_per_zone / total_sections (%u, %u)", 2522 f2fs_info(sbi, "Wrong secs_per_zone / total_sections (%u, %u)",
2523 secs_per_zone, total_sections); 2523 secs_per_zone, total_sections);
2524 return 1; 2524 return -EFSCORRUPTED;
2525 } 2525 }
2526 if (le32_to_cpu(raw_super->extension_count) > F2FS_MAX_EXTENSION || 2526 if (le32_to_cpu(raw_super->extension_count) > F2FS_MAX_EXTENSION ||
2527 raw_super->hot_ext_count > F2FS_MAX_EXTENSION || 2527 raw_super->hot_ext_count > F2FS_MAX_EXTENSION ||
@@ -2531,7 +2531,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2531 le32_to_cpu(raw_super->extension_count), 2531 le32_to_cpu(raw_super->extension_count),
2532 raw_super->hot_ext_count, 2532 raw_super->hot_ext_count,
2533 F2FS_MAX_EXTENSION); 2533 F2FS_MAX_EXTENSION);
2534 return 1; 2534 return -EFSCORRUPTED;
2535 } 2535 }
2536 2536
2537 if (le32_to_cpu(raw_super->cp_payload) > 2537 if (le32_to_cpu(raw_super->cp_payload) >
@@ -2539,7 +2539,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2539 f2fs_info(sbi, "Insane cp_payload (%u > %u)", 2539 f2fs_info(sbi, "Insane cp_payload (%u > %u)",
2540 le32_to_cpu(raw_super->cp_payload), 2540 le32_to_cpu(raw_super->cp_payload),
2541 blocks_per_seg - F2FS_CP_PACKS); 2541 blocks_per_seg - F2FS_CP_PACKS);
2542 return 1; 2542 return -EFSCORRUPTED;
2543 } 2543 }
2544 2544
2545 /* check reserved ino info */ 2545 /* check reserved ino info */
@@ -2550,12 +2550,12 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
2550 le32_to_cpu(raw_super->node_ino), 2550 le32_to_cpu(raw_super->node_ino),
2551 le32_to_cpu(raw_super->meta_ino), 2551 le32_to_cpu(raw_super->meta_ino),
2552 le32_to_cpu(raw_super->root_ino)); 2552 le32_to_cpu(raw_super->root_ino));
2553 return 1; 2553 return -EFSCORRUPTED;
2554 } 2554 }
2555 2555
2556 /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ 2556 /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
2557 if (sanity_check_area_boundary(sbi, bh)) 2557 if (sanity_check_area_boundary(sbi, bh))
2558 return 1; 2558 return -EFSCORRUPTED;
2559 2559
2560 return 0; 2560 return 0;
2561} 2561}
@@ -2872,10 +2872,10 @@ static int read_raw_super_block(struct f2fs_sb_info *sbi,
2872 } 2872 }
2873 2873
2874 /* sanity checking of raw super */ 2874 /* sanity checking of raw super */
2875 if (sanity_check_raw_super(sbi, bh)) { 2875 err = sanity_check_raw_super(sbi, bh);
2876 if (err) {
2876 f2fs_err(sbi, "Can't find valid F2FS filesystem in %dth superblock", 2877 f2fs_err(sbi, "Can't find valid F2FS filesystem in %dth superblock",
2877 block + 1); 2878 block + 1);
2878 err = -EFSCORRUPTED;
2879 brelse(bh); 2879 brelse(bh);
2880 continue; 2880 continue;
2881 } 2881 }