scoutfs: check super blkno fields

We had a bug where mkfs would set a free data blkno allocator bit past
the end of the device.  (Just at it, in fact.  Those fenceposts.)  Add
some checks at mount to make sure that the allocator blkno ranges in the
super don't have obvious mistakes.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2020-08-26 14:39:12 -07:00
committed by Zach Brown
parent 69e5f5ae5f
commit 07ba053021
+46
View File
@@ -242,6 +242,7 @@ int scoutfs_read_super(struct super_block *sb,
{
struct scoutfs_super_block *super;
__le32 calc;
u64 blkno;
int ret;
super = kmalloc(sizeof(struct scoutfs_super_block), GFP_NOFS);
@@ -294,6 +295,51 @@ int scoutfs_read_super(struct super_block *sb,
goto out;
}
blkno = (SCOUTFS_QUORUM_BLKNO + SCOUTFS_QUORUM_BLOCKS) >>
SCOUTFS_BLOCK_SM_LG_SHIFT;
if (le64_to_cpu(super->first_meta_blkno) < blkno) {
scoutfs_err(sb, "super block first meta blkno %llu is within quorum blocks",
le64_to_cpu(super->first_meta_blkno));
ret = -EINVAL;
goto out;
}
if (le64_to_cpu(super->first_meta_blkno) >
le64_to_cpu(super->last_meta_blkno)) {
scoutfs_err(sb, "super block first meta blkno %llu is greater than last meta blkno %llu",
le64_to_cpu(super->first_meta_blkno),
le64_to_cpu(super->last_meta_blkno));
ret = -EINVAL;
goto out;
}
blkno = (le64_to_cpu(super->last_meta_blkno) + 1) <<
SCOUTFS_BLOCK_SM_LG_SHIFT;
if (le64_to_cpu(super->first_data_blkno) < blkno) {
scoutfs_err(sb, "super block first data blkno %llu is within last meta blkno %llu",
le64_to_cpu(super->first_data_blkno), blkno);
ret = -EINVAL;
goto out;
}
if (le64_to_cpu(super->first_data_blkno) >
le64_to_cpu(super->last_data_blkno)) {
scoutfs_err(sb, "super block first data blkno %llu is greater than last data blkno %llu",
le64_to_cpu(super->first_data_blkno),
le64_to_cpu(super->last_data_blkno));
ret = -EINVAL;
goto out;
}
blkno = (i_size_read(sb->s_bdev->bd_inode) >>
SCOUTFS_BLOCK_SM_SHIFT) - 1;
if (le64_to_cpu(super->last_data_blkno) > blkno) {
scoutfs_err(sb, "super block last data blkno %llu is outsite device size last blkno %llu",
le64_to_cpu(super->last_data_blkno), blkno);
ret = -EINVAL;
goto out;
}
*super_res = *super;
ret = 0;
out: