This patch fixes the bug which does not cover a large section case when checking
the sanity of superblock.

Reported-by: Matthias Prager <li...@matthiasprager.de>
Reported-by: David Gnedt <david.gn...@davizone.at>
Cc: stable 4.5+ <sta...@vger.kernel.org>
Signed-off-by: Jaegeuk Kim <jaeg...@kernel.org>
---
 fs/f2fs/super.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 15bb81f..fc9147f 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1000,6 +1000,7 @@ static inline bool sanity_check_area_boundary(struct 
super_block *sb,
        u32 segment_count_main = le32_to_cpu(raw_super->segment_count_main);
        u32 segment_count = le32_to_cpu(raw_super->segment_count);
        u32 log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
+       u32 segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
 
        if (segment0_blkaddr != cp_blkaddr) {
                f2fs_msg(sb, KERN_INFO,
@@ -1044,12 +1045,26 @@ static inline bool sanity_check_area_boundary(struct 
super_block *sb,
                return true;
        }
 
-       if (main_blkaddr + (segment_count_main << log_blocks_per_seg) !=
+       if (segs_per_sec == 1 &&
+               main_blkaddr + (segment_count_main << log_blocks_per_seg) !=
                segment0_blkaddr + (segment_count << log_blocks_per_seg)) {
                f2fs_msg(sb, KERN_INFO,
                        "Wrong MAIN_AREA boundary, start(%u) end(%u) 
blocks(%u)",
                        main_blkaddr,
-                       segment0_blkaddr + (segment_count << 
log_blocks_per_seg),
+                       segment0_blkaddr +
+                       (segment_count << log_blocks_per_seg),
+                       segment_count_main << log_blocks_per_seg);
+               return true;
+       }
+
+       if (segs_per_sec > 1 &&
+               main_blkaddr + (segment_count_main << log_blocks_per_seg) >
+               segment0_blkaddr + (segment_count << log_blocks_per_seg)) {
+               f2fs_msg(sb, KERN_INFO,
+                       "Wrong MAIN_AREA boundary in large section, start(%u) 
end(%u) blocks(%u)",
+                       main_blkaddr,
+                       segment0_blkaddr +
+                       (segment_count << log_blocks_per_seg),
                        segment_count_main << log_blocks_per_seg);
                return true;
        }
-- 
2.6.3

Reply via email to