]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
bcachefs: Validate bset version field against sb version fields
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 21 Mar 2021 20:03:23 +0000 (16:03 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:56 +0000 (17:08 -0400)
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>
fs/bcachefs/bcachefs.h
fs/bcachefs/btree_io.c
fs/bcachefs/super-io.c

index 9f4e7a3ada368f561e6fb62867d77bf46d56808f..51aefecb5cbbaf2e848eb37f2d45d5c59765ac31 100644 (file)
@@ -592,6 +592,7 @@ struct bch_fs {
                __uuid_t        user_uuid;
 
                u16             version;
+               u16             version_min;
                u16             encoded_extent_max;
 
                u8              nr_devices;
index 7ec14cd8f02b63eb4cd47843d0f87d176495f23a..adeb4f9fb5fd5e09e56c84896debbc05de2fd4af 100644 (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")) {
index 6e61cf5ab2174e25f2d8719a6808e3b2106a6b91..e397a2a70c9cf73fe7970211db5e06b78b36cb4b 100644 (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);