bcachefs: Validate bset version field against sb version fields

The superblock version fields need to be accurate to know whether a
filesystem is supported, thus we should be verifying them.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2021-03-21 16:03:23 -04:00 committed by Kent Overstreet
parent d361a26d02
commit 84cc758d6b
3 changed files with 22 additions and 0 deletions

View file

@ -592,6 +592,7 @@ struct bch_fs {
__uuid_t user_uuid;
u16 version;
u16 version_min;
u16 encoded_extent_max;
u8 nr_devices;

View file

@ -560,6 +560,26 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
BTREE_ERR_FATAL, c, ca, b, i,
"unsupported bset version");
if (btree_err_on(version < c->sb.version_min,
BTREE_ERR_FIXABLE, c, NULL, b, i,
"bset version %u older than superblock version_min %u",
version, c->sb.version_min)) {
mutex_lock(&c->sb_lock);
c->disk_sb.sb->version_min = cpu_to_le16(version);
bch2_write_super(c);
mutex_unlock(&c->sb_lock);
}
if (btree_err_on(version > c->sb.version,
BTREE_ERR_FIXABLE, c, NULL, b, i,
"bset version %u newer than superblock version %u",
version, c->sb.version)) {
mutex_lock(&c->sb_lock);
c->disk_sb.sb->version = cpu_to_le16(version);
bch2_write_super(c);
mutex_unlock(&c->sb_lock);
}
if (btree_err_on(b->written + sectors > c->opts.btree_node_size,
BTREE_ERR_FIXABLE, c, ca, b, i,
"bset past end of btree node")) {

View file

@ -369,6 +369,7 @@ static void bch2_sb_update(struct bch_fs *c)
c->sb.uuid = src->uuid;
c->sb.user_uuid = src->user_uuid;
c->sb.version = le16_to_cpu(src->version);
c->sb.version_min = le16_to_cpu(src->version_min);
c->sb.nr_devices = src->nr_devices;
c->sb.clean = BCH_SB_CLEAN(src);
c->sb.encryption_type = BCH_SB_ENCRYPTION_TYPE(src);