bcachefs: Fix version checks in validate_bset()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 11 Jun 2025 17:32:58 +0000 (13:32 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 12 Jun 2025 03:21:30 +0000 (23:21 -0400)
It seems btree node scan picked up a partially overwritten btree node,
and corrected the "bset version older than sb version_min" error -
resulting in an invalid superblock with a bad version_min field.

Don't run this check at all when we're in btree node scan, and when we
do run it, do something saner if the bset version is totally crazy.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_io.c

index 6787d5b91eabb3d7b003ed1cdb7de6f05c04382d..d8f3c4c65e90cd74d3baa8b92f05d6ec622e4c23 100644 (file)
@@ -741,16 +741,22 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
                     BCH_VERSION_MAJOR(version),
                     BCH_VERSION_MINOR(version));
 
-       if (btree_err_on(version < c->sb.version_min,
+       if (c->recovery.curr_pass != BCH_RECOVERY_PASS_scan_for_btree_nodes &&
+           btree_err_on(version < c->sb.version_min,
                         -BCH_ERR_btree_node_read_err_fixable,
                         c, NULL, b, i, NULL,
                         btree_node_bset_older_than_sb_min,
                         "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 (bch2_version_compatible(version)) {
+                       mutex_lock(&c->sb_lock);
+                       c->disk_sb.sb->version_min = cpu_to_le16(version);
+                       bch2_write_super(c);
+                       mutex_unlock(&c->sb_lock);
+               } else {
+                       /* We have no idea what's going on: */
+                       i->version = cpu_to_le16(c->sb.version);
+               }
        }
 
        if (btree_err_on(BCH_VERSION_MAJOR(version) >