From: Sasha Levin Date: Mon, 14 Oct 2019 04:14:07 +0000 (-0400) Subject: fixes for 4.19 X-Git-Tag: v4.4.197~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d426ab637b2b89aa324de2a3607e7cacd28a0a7;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/f2fs-use-einval-for-superblock-with-invalid-magic.patch b/queue-4.19/f2fs-use-einval-for-superblock-with-invalid-magic.patch new file mode 100644 index 00000000000..9bd68b70cc4 --- /dev/null +++ b/queue-4.19/f2fs-use-einval-for-superblock-with-invalid-magic.patch @@ -0,0 +1,189 @@ +From d6cfabce0981894c0264326d32c96d7d1a6aa834 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Jul 2019 11:08:52 +0800 +Subject: f2fs: use EINVAL for superblock with invalid magic + +From: Icenowy Zheng + +[ Upstream commit 38fb6d0ea34299d97b031ed64fe994158b6f8eb3 ] + +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 +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + fs/f2fs/super.c | 36 ++++++++++++++++++------------------ + 1 file changed, 18 insertions(+), 18 deletions(-) + +diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c +index fdafcfd8b20e2..6851afc3bf805 100644 +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -2196,11 +2196,11 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + struct super_block *sb = sbi->sb; + unsigned int blocksize; + +- if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) { ++ if (le32_to_cpu(raw_super->magic) != F2FS_SUPER_MAGIC) { + f2fs_msg(sb, KERN_INFO, + "Magic Mismatch, valid(0x%x) - read(0x%x)", + F2FS_SUPER_MAGIC, le32_to_cpu(raw_super->magic)); +- return 1; ++ return -EINVAL; + } + + /* Currently, support only 4KB page cache size */ +@@ -2208,7 +2208,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + f2fs_msg(sb, KERN_INFO, + "Invalid page_cache_size (%lu), supports only 4KB\n", + PAGE_SIZE); +- return 1; ++ return -EFSCORRUPTED; + } + + /* Currently, support only 4KB block size */ +@@ -2217,7 +2217,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + f2fs_msg(sb, KERN_INFO, + "Invalid blocksize (%u), supports only 4KB\n", + blocksize); +- return 1; ++ return -EFSCORRUPTED; + } + + /* check log blocks per segment */ +@@ -2225,7 +2225,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + f2fs_msg(sb, KERN_INFO, + "Invalid log blocks per segment (%u)\n", + le32_to_cpu(raw_super->log_blocks_per_seg)); +- return 1; ++ return -EFSCORRUPTED; + } + + /* Currently, support 512/1024/2048/4096 bytes sector size */ +@@ -2235,7 +2235,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + F2FS_MIN_LOG_SECTOR_SIZE) { + f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize (%u)", + le32_to_cpu(raw_super->log_sectorsize)); +- return 1; ++ return -EFSCORRUPTED; + } + if (le32_to_cpu(raw_super->log_sectors_per_block) + + le32_to_cpu(raw_super->log_sectorsize) != +@@ -2244,7 +2244,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + "Invalid log sectors per block(%u) log sectorsize(%u)", + le32_to_cpu(raw_super->log_sectors_per_block), + le32_to_cpu(raw_super->log_sectorsize)); +- return 1; ++ return -EFSCORRUPTED; + } + + segment_count = le32_to_cpu(raw_super->segment_count); +@@ -2260,7 +2260,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + f2fs_msg(sb, KERN_INFO, + "Invalid segment count (%u)", + segment_count); +- return 1; ++ return -EFSCORRUPTED; + } + + if (total_sections > segment_count || +@@ -2269,28 +2269,28 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + f2fs_msg(sb, KERN_INFO, + "Invalid segment/section count (%u, %u x %u)", + segment_count, total_sections, segs_per_sec); +- return 1; ++ return -EFSCORRUPTED; + } + + if ((segment_count / segs_per_sec) < total_sections) { + f2fs_msg(sb, KERN_INFO, + "Small segment_count (%u < %u * %u)", + segment_count, segs_per_sec, total_sections); +- return 1; ++ return -EFSCORRUPTED; + } + + if (segment_count > (le64_to_cpu(raw_super->block_count) >> 9)) { + f2fs_msg(sb, KERN_INFO, + "Wrong segment_count / block_count (%u > %llu)", + segment_count, le64_to_cpu(raw_super->block_count)); +- return 1; ++ return -EFSCORRUPTED; + } + + if (secs_per_zone > total_sections || !secs_per_zone) { + f2fs_msg(sb, KERN_INFO, + "Wrong secs_per_zone / total_sections (%u, %u)", + secs_per_zone, total_sections); +- return 1; ++ return -EFSCORRUPTED; + } + if (le32_to_cpu(raw_super->extension_count) > F2FS_MAX_EXTENSION || + raw_super->hot_ext_count > F2FS_MAX_EXTENSION || +@@ -2301,7 +2301,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + le32_to_cpu(raw_super->extension_count), + raw_super->hot_ext_count, + F2FS_MAX_EXTENSION); +- return 1; ++ return -EFSCORRUPTED; + } + + if (le32_to_cpu(raw_super->cp_payload) > +@@ -2310,7 +2310,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + "Insane cp_payload (%u > %u)", + le32_to_cpu(raw_super->cp_payload), + blocks_per_seg - F2FS_CP_PACKS); +- return 1; ++ return -EFSCORRUPTED; + } + + /* check reserved ino info */ +@@ -2322,12 +2322,12 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, + le32_to_cpu(raw_super->node_ino), + le32_to_cpu(raw_super->meta_ino), + le32_to_cpu(raw_super->root_ino)); +- return 1; ++ return -EFSCORRUPTED; + } + + /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */ + if (sanity_check_area_boundary(sbi, bh)) +- return 1; ++ return -EFSCORRUPTED; + + return 0; + } +@@ -2612,11 +2612,11 @@ static int read_raw_super_block(struct f2fs_sb_info *sbi, + } + + /* sanity checking of raw super */ +- if (sanity_check_raw_super(sbi, bh)) { ++ err = sanity_check_raw_super(sbi, bh); ++ if (err) { + f2fs_msg(sb, KERN_ERR, + "Can't find valid F2FS filesystem in %dth superblock", + block + 1); +- err = -EFSCORRUPTED; + brelse(bh); + continue; + } +-- +2.20.1 + diff --git a/queue-4.19/series b/queue-4.19/series index 5d3c3c5b219..70e26c23b0c 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -1 +1,2 @@ panic-ensure-preemption-is-disabled-during-panic.patch +f2fs-use-einval-for-superblock-with-invalid-magic.patch