diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index 17ffac089a5d..9ca6c236f508 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -1166,8 +1166,7 @@ static void check_version_upgrade(struct bch_fs *c) c->opts.fix_errors = FSCK_OPT_YES; mutex_lock(&c->sb_lock); - c->disk_sb.sb->version = cpu_to_le16(new_version); - c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL); + bch2_sb_upgrade(c, new_version); mutex_unlock(&c->sb_lock); printbuf_exit(&buf); @@ -1525,10 +1524,11 @@ int bch2_fs_initialize(struct bch_fs *c) c->disk_sb.sb->compat[0] |= cpu_to_le64(1ULL << BCH_COMPAT_extents_above_btree_updates_done); c->disk_sb.sb->compat[0] |= cpu_to_le64(1ULL << BCH_COMPAT_bformat_overflow_done); + bch2_sb_maybe_downgrade(c); + if (c->opts.version_upgrade != BCH_VERSION_UPGRADE_none) { - c->disk_sb.sb->version = cpu_to_le16(bcachefs_metadata_version_current); + bch2_sb_upgrade(c, bcachefs_metadata_version_current); SET_BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb, bcachefs_metadata_version_current); - c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL); bch2_write_super(c); } mutex_unlock(&c->sb_lock); diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index 23e25af001f0..a06310492e79 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -1204,17 +1204,10 @@ int bch2_sb_clean_validate_late(struct bch_fs *c, struct bch_sb_field_clean *cle return 0; } -int bch2_fs_mark_dirty(struct bch_fs *c) +/* Downgrade if superblock is at a higher version than currently supported: */ +void bch2_sb_maybe_downgrade(struct bch_fs *c) { - int ret; - - /* - * Unconditionally write superblock, to verify it hasn't changed before - * we go rw: - */ - - mutex_lock(&c->sb_lock); - SET_BCH_SB_CLEAN(c->disk_sb.sb, false); + lockdep_assert_held(&c->sb_lock); /* * Downgrade, if superblock is at a higher version than currently @@ -1227,8 +1220,31 @@ int bch2_fs_mark_dirty(struct bch_fs *c) if (c->sb.version_min > bcachefs_metadata_version_current) c->disk_sb.sb->version_min = cpu_to_le16(bcachefs_metadata_version_current); c->disk_sb.sb->compat[0] &= cpu_to_le64((1ULL << BCH_COMPAT_NR) - 1); +} +void bch2_sb_upgrade(struct bch_fs *c, unsigned new_version) +{ + lockdep_assert_held(&c->sb_lock); + + c->disk_sb.sb->version = cpu_to_le16(new_version); + c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL); +} + +int bch2_fs_mark_dirty(struct bch_fs *c) +{ + int ret; + + /* + * Unconditionally write superblock, to verify it hasn't changed before + * we go rw: + */ + + mutex_lock(&c->sb_lock); + SET_BCH_SB_CLEAN(c->disk_sb.sb, false); + + bch2_sb_maybe_downgrade(c); c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALWAYS); + ret = bch2_write_super(c); mutex_unlock(&c->sb_lock); diff --git a/fs/bcachefs/super-io.h b/fs/bcachefs/super-io.h index a850cc4ae6c7..b365f088ba41 100644 --- a/fs/bcachefs/super-io.h +++ b/fs/bcachefs/super-io.h @@ -124,6 +124,9 @@ void bch2_journal_super_entries_add_common(struct bch_fs *, int bch2_sb_clean_validate_late(struct bch_fs *, struct bch_sb_field_clean *, int); +void bch2_sb_maybe_downgrade(struct bch_fs *); +void bch2_sb_upgrade(struct bch_fs *, unsigned); + int bch2_fs_mark_dirty(struct bch_fs *); void bch2_fs_mark_clean(struct bch_fs *);