version_upgrade is now a runtime option.

In the future we'll want to add compatible upgrades at runtime, and call
the full check_version_upgrade() when the option changes, but we don't
have compatible optional upgrades just yet.

Signed-off-by: Kent Overstreet <kent.overstr...@linux.dev>
---
 fs/bcachefs/opts.c     |  9 +++++++++
 fs/bcachefs/opts.h     |  2 +-
 fs/bcachefs/recovery.c |  4 ++--
 fs/bcachefs/super-io.c | 25 +++++++++++++++++++++++++
 fs/bcachefs/super-io.h |  1 +
 5 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
index 386482ff8e7b..b1cf88905b81 100644
--- a/fs/bcachefs/opts.c
+++ b/fs/bcachefs/opts.c
@@ -595,6 +595,15 @@ void bch2_opt_hook_post_set(struct bch_fs *c, struct 
bch_dev *ca, u64 inum,
                        mutex_unlock(&c->sb_lock);
                }
                break;
+       case Opt_version_upgrade:
+               /*
+                * XXX: in the future we'll likely want to do compatible
+                * upgrades at runtime as well, but right now there's nothing
+                * that does that:
+                */
+               if (new_opts->version_upgrade == 
BCH_VERSION_UPGRADE_incompatible)
+                       bch2_sb_upgrade_incompat(c);
+               break;
        default:
                break;
        }
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
index f69ba5e63e15..5cdb18802138 100644
--- a/fs/bcachefs/opts.h
+++ b/fs/bcachefs/opts.h
@@ -445,7 +445,7 @@ enum fsck_err_opts {
          BCH2_NO_SB_OPT,               false,                          \
          NULL,         "Reconstruct alloc btree")                      \
        x(version_upgrade,              u8,                             \
-         OPT_FS|OPT_MOUNT,                                             \
+         OPT_FS|OPT_MOUNT|OPT_RUNTIME,                                 \
          OPT_STR(bch2_version_upgrade_opts),                           \
          BCH_SB_VERSION_UPGRADE,       BCH_VERSION_UPGRADE_compatible, \
          NULL,         "Set superblock to latest version,\n"           \
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index 606d684e6f23..58ee1ebdcbaa 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -666,7 +666,7 @@ static bool check_version_upgrade(struct bch_fs *c)
                                     
bch2_recovery_passes_from_stable(le64_to_cpu(passes)));
                }
 
-               bch_info(c, "%s", buf.buf);
+               bch_notice(c, "%s", buf.buf);
                printbuf_exit(&buf);
 
                ret = true;
@@ -682,7 +682,7 @@ static bool check_version_upgrade(struct bch_fs *c)
                bch2_version_to_text(&buf, c->sb.version_incompat_allowed);
                prt_newline(&buf);
 
-               bch_info(c, "%s", buf.buf);
+               bch_notice(c, "%s", buf.buf);
                printbuf_exit(&buf);
 
                ret = true;
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
index fa4d323ddada..791dee30f042 100644
--- a/fs/bcachefs/super-io.c
+++ b/fs/bcachefs/super-io.c
@@ -1273,6 +1273,31 @@ void bch2_sb_upgrade(struct bch_fs *c, unsigned 
new_version, bool incompat)
        }
 }
 
+void bch2_sb_upgrade_incompat(struct bch_fs *c)
+{
+       mutex_lock(&c->sb_lock);
+       if (c->sb.version == c->sb.version_incompat_allowed)
+               goto unlock;
+
+       struct printbuf buf = PRINTBUF;
+
+       prt_str(&buf, "Now allowing incompatible features up to ");
+       bch2_version_to_text(&buf, c->sb.version);
+       prt_str(&buf, ", previously allowed up to ");
+       bch2_version_to_text(&buf, c->sb.version_incompat_allowed);
+       prt_newline(&buf);
+
+       bch_notice(c, "%s", buf.buf);
+       printbuf_exit(&buf);
+
+       c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL);
+       SET_BCH_SB_VERSION_INCOMPAT_ALLOWED(c->disk_sb.sb,
+                       max(BCH_SB_VERSION_INCOMPAT_ALLOWED(c->disk_sb.sb), 
c->sb.version));
+       bch2_write_super(c);
+unlock:
+       mutex_unlock(&c->sb_lock);
+}
+
 static int bch2_sb_ext_validate(struct bch_sb *sb, struct bch_sb_field *f,
                                enum bch_validate_flags flags, struct printbuf 
*err)
 {
diff --git a/fs/bcachefs/super-io.h b/fs/bcachefs/super-io.h
index 78f708a6fbcd..a3b7a90f2533 100644
--- a/fs/bcachefs/super-io.h
+++ b/fs/bcachefs/super-io.h
@@ -107,6 +107,7 @@ static inline void bch2_check_set_feature(struct bch_fs *c, 
unsigned feat)
 
 bool bch2_check_version_downgrade(struct bch_fs *);
 void bch2_sb_upgrade(struct bch_fs *, unsigned, bool);
+void bch2_sb_upgrade_incompat(struct bch_fs *);
 
 void __bch2_sb_field_to_text(struct printbuf *, struct bch_sb *,
                             struct bch_sb_field *);
-- 
2.49.0


Reply via email to