aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-07-10 01:44:55 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-07-10 01:44:55 -0400
commitffa950ce1d59344ff621659b845416b8a526127f (patch)
treea393d0a2792720ddb21c5d47610f9d21a3e98a93
parent5d507f795b0b679a67e972a48cbd0854c4ad0f02 (diff)
downloadbcachefs-tools-ffa950ce1d59344ff621659b845416b8a526127f.tar.gz
Update bcachefs sources to 1e3ca87f7b bcachefs: bcachefs_metadata_version_major_minor
-rw-r--r--.bcachefs_revision2
-rw-r--r--libbcachefs/bcachefs.h1
-rw-r--r--libbcachefs/bcachefs_format.h46
-rw-r--r--libbcachefs/btree_io.c7
-rw-r--r--libbcachefs/journal_io.c12
-rw-r--r--libbcachefs/recovery.c66
-rw-r--r--libbcachefs/super-io.c58
-rw-r--r--libbcachefs/super-io.h3
8 files changed, 133 insertions, 62 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index 9f546cce..f1aa0f0c 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-da7d42a9a2f78ca2a8ccffb0f15bf61bc7a7bc49
+1e3ca87f7b8e33f8d96260afebc7e78959f93073
diff --git a/libbcachefs/bcachefs.h b/libbcachefs/bcachefs.h
index cfd4a7b9..88a1782b 100644
--- a/libbcachefs/bcachefs.h
+++ b/libbcachefs/bcachefs.h
@@ -568,7 +568,6 @@ enum {
BCH_FS_INITIAL_GC_UNFIXED, /* kill when we enumerate fsck errors */
BCH_FS_NEED_ANOTHER_GC,
- BCH_FS_VERSION_UPGRADE,
BCH_FS_HAVE_DELETED_SNAPSHOTS,
/* errors: */
diff --git a/libbcachefs/bcachefs_format.h b/libbcachefs/bcachefs_format.h
index 8a0f90a8..78771d8d 100644
--- a/libbcachefs/bcachefs_format.h
+++ b/libbcachefs/bcachefs_format.h
@@ -1574,28 +1574,32 @@ struct bch_sb_field_journal_seq_blacklist {
* One common version number for all on disk data structures - superblock, btree
* nodes, journal entries
*/
+#define BCH_VERSION_MAJOR(_v) ((__u16) ((_v) >> 10))
+#define BCH_VERSION_MINOR(_v) ((__u16) ((_v) & ~(~0U << 10)))
+#define BCH_VERSION(_major, _minor) (((_major) << 10)|(_minor) << 0)
#define BCH_METADATA_VERSIONS() \
- x(bkey_renumber, 10) \
- x(inode_btree_change, 11) \
- x(snapshot, 12) \
- x(inode_backpointers, 13) \
- x(btree_ptr_sectors_written, 14) \
- x(snapshot_2, 15) \
- x(reflink_p_fix, 16) \
- x(subvol_dirent, 17) \
- x(inode_v2, 18) \
- x(freespace, 19) \
- x(alloc_v4, 20) \
- x(new_data_types, 21) \
- x(backpointers, 22) \
- x(inode_v3, 23) \
- x(unwritten_extents, 24) \
- x(bucket_gens, 25) \
- x(lru_v2, 26) \
- x(fragmentation_lru, 27) \
- x(no_bps_in_alloc_keys, 28) \
- x(snapshot_trees, 29)
+ x(bkey_renumber, BCH_VERSION(0, 10)) \
+ x(inode_btree_change, BCH_VERSION(0, 11)) \
+ x(snapshot, BCH_VERSION(0, 12)) \
+ x(inode_backpointers, BCH_VERSION(0, 13)) \
+ x(btree_ptr_sectors_written, BCH_VERSION(0, 14)) \
+ x(snapshot_2, BCH_VERSION(0, 15)) \
+ x(reflink_p_fix, BCH_VERSION(0, 16)) \
+ x(subvol_dirent, BCH_VERSION(0, 17)) \
+ x(inode_v2, BCH_VERSION(0, 18)) \
+ x(freespace, BCH_VERSION(0, 19)) \
+ x(alloc_v4, BCH_VERSION(0, 20)) \
+ x(new_data_types, BCH_VERSION(0, 21)) \
+ x(backpointers, BCH_VERSION(0, 22)) \
+ x(inode_v3, BCH_VERSION(0, 23)) \
+ x(unwritten_extents, BCH_VERSION(0, 24)) \
+ x(bucket_gens, BCH_VERSION(0, 25)) \
+ x(lru_v2, BCH_VERSION(0, 26)) \
+ x(fragmentation_lru, BCH_VERSION(0, 27)) \
+ x(no_bps_in_alloc_keys, BCH_VERSION(0, 28)) \
+ x(snapshot_trees, BCH_VERSION(0, 29)) \
+ x(major_minor, BCH_VERSION(1, 0))
enum bcachefs_metadata_version {
bcachefs_metadata_version_min = 9,
@@ -1605,7 +1609,7 @@ enum bcachefs_metadata_version {
bcachefs_metadata_version_max
};
-static const unsigned bcachefs_metadata_required_upgrade_below = bcachefs_metadata_version_snapshot_trees;
+static const unsigned bcachefs_metadata_required_upgrade_below = bcachefs_metadata_version_major_minor;
#define bcachefs_metadata_version_current (bcachefs_metadata_version_max - 1)
diff --git a/libbcachefs/btree_io.c b/libbcachefs/btree_io.c
index 1face387..fa1229eb 100644
--- a/libbcachefs/btree_io.c
+++ b/libbcachefs/btree_io.c
@@ -703,7 +703,9 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
btree_err_on(!bch2_version_compatible(version),
BTREE_ERR_INCOMPATIBLE, c, ca, b, i,
- "unsupported bset version %u", version);
+ "unsupported bset version %u.%u",
+ BCH_VERSION_MAJOR(version),
+ BCH_VERSION_MINOR(version));
if (btree_err_on(version < c->sb.version_min,
BTREE_ERR_FIXABLE, c, NULL, b, i,
@@ -715,7 +717,8 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
mutex_unlock(&c->sb_lock);
}
- if (btree_err_on(version > c->sb.version,
+ if (btree_err_on(BCH_VERSION_MAJOR(version) >
+ BCH_VERSION_MAJOR(c->sb.version),
BTREE_ERR_FIXABLE, c, NULL, b, i,
"bset version %u newer than superblock version %u",
version, c->sb.version)) {
diff --git a/libbcachefs/journal_io.c b/libbcachefs/journal_io.c
index c7c2ae32..f861ae2f 100644
--- a/libbcachefs/journal_io.c
+++ b/libbcachefs/journal_io.c
@@ -747,9 +747,11 @@ static int jset_validate(struct bch_fs *c,
version = le32_to_cpu(jset->version);
if (journal_entry_err_on(!bch2_version_compatible(version), c, jset, NULL,
- "%s sector %llu seq %llu: incompatible journal entry version %u",
+ "%s sector %llu seq %llu: incompatible journal entry version %u.%u",
ca ? ca->name : c->name,
- sector, le64_to_cpu(jset->seq), version)) {
+ sector, le64_to_cpu(jset->seq),
+ BCH_VERSION_MAJOR(version),
+ BCH_VERSION_MINOR(version))) {
/* don't try to continue: */
return -EINVAL;
}
@@ -794,9 +796,11 @@ static int jset_validate_early(struct bch_fs *c,
version = le32_to_cpu(jset->version);
if (journal_entry_err_on(!bch2_version_compatible(version), c, jset, NULL,
- "%s sector %llu seq %llu: unknown journal entry version %u",
+ "%s sector %llu seq %llu: unknown journal entry version %u.%u",
ca ? ca->name : c->name,
- sector, le64_to_cpu(jset->seq), version)) {
+ sector, le64_to_cpu(jset->seq),
+ BCH_VERSION_MAJOR(version),
+ BCH_VERSION_MINOR(version))) {
/* don't try to continue: */
return -EINVAL;
}
diff --git a/libbcachefs/recovery.c b/libbcachefs/recovery.c
index 3b9120bd..995e1b13 100644
--- a/libbcachefs/recovery.c
+++ b/libbcachefs/recovery.c
@@ -1111,31 +1111,69 @@ static int bch2_fs_upgrade_for_subvolumes(struct bch_fs *c)
static void check_version_upgrade(struct bch_fs *c)
{
- unsigned version = c->sb.version_upgrade_complete ?: c->sb.version;
+ unsigned latest_compatible = bch2_version_compatible(c->sb.version);
+ unsigned latest_version = bcachefs_metadata_version_current;
+ unsigned old_version = c->sb.version_upgrade_complete ?: c->sb.version;
+ unsigned new_version = 0;
+
+ if (old_version < bcachefs_metadata_required_upgrade_below) {
+ if (c->opts.version_upgrade == BCH_VERSION_UPGRADE_incompatible ||
+ latest_compatible < bcachefs_metadata_required_upgrade_below)
+ new_version = latest_version;
+ else
+ new_version = latest_compatible;
+ } else {
+ switch (c->opts.version_upgrade) {
+ case BCH_VERSION_UPGRADE_compatible:
+ new_version = latest_compatible;
+ break;
+ case BCH_VERSION_UPGRADE_incompatible:
+ new_version = latest_version;
+ break;
+ case BCH_VERSION_UPGRADE_none:
+ new_version = old_version;
+ break;
+ }
+ }
- if (version < bcachefs_metadata_required_upgrade_below ||
- (version < bcachefs_metadata_version_current &&
- c->opts.version_upgrade != BCH_VERSION_UPGRADE_none)) {
+ if (new_version > old_version) {
struct printbuf buf = PRINTBUF;
- if (version != c->sb.version) {
- prt_str(&buf, "version upgrade to ");
+ if (old_version < bcachefs_metadata_required_upgrade_below)
+ prt_str(&buf, "Version upgrade required:\n");
+
+ if (old_version != c->sb.version) {
+ prt_str(&buf, "Version upgrade from ");
+ bch2_version_to_text(&buf, c->sb.version_upgrade_complete);
+ prt_str(&buf, " to ");
bch2_version_to_text(&buf, c->sb.version);
- prt_str(&buf, " incomplete:\n");
+ prt_str(&buf, " incomplete\n");
}
- prt_str(&buf, "version ");
- bch2_version_to_text(&buf, version);
- prt_str(&buf, " prior to ");
- bch2_version_to_text(&buf, bcachefs_metadata_required_upgrade_below);
- prt_str(&buf, ", upgrade and fsck required");
+ prt_str(&buf, "Doing ");
+ if (BCH_VERSION_MAJOR(old_version) != BCH_VERSION_MAJOR(new_version))
+ prt_str(&buf, "incompatible");
+ else
+ prt_str(&buf, "compatible");
+ prt_str(&buf, "version upgrade from ");
+ bch2_version_to_text(&buf, old_version);
+ prt_str(&buf, " to ");
+ bch2_version_to_text(&buf, new_version);
+ prt_newline(&buf);
+
+ prt_str(&buf, "fsck required");
bch_info(c, "%s", buf.buf);
- printbuf_exit(&buf);
c->opts.fsck = true;
c->opts.fix_errors = FSCK_OPT_YES;
- set_bit(BCH_FS_VERSION_UPGRADE, &c->flags);
+
+ 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);
+ mutex_unlock(&c->sb_lock);
+
+ printbuf_exit(&buf);
}
}
diff --git a/libbcachefs/super-io.c b/libbcachefs/super-io.c
index b174003b..b4aec5b6 100644
--- a/libbcachefs/super-io.c
+++ b/libbcachefs/super-io.c
@@ -23,19 +23,42 @@
#include <linux/backing-dev.h>
#include <linux/sort.h>
-static const char * const bch2_metadata_versions[] = {
-#define x(t, n) [n] = #t,
+struct bch2_metadata_version_str {
+ u16 version;
+ const char *name;
+};
+
+static const struct bch2_metadata_version_str bch2_metadata_versions[] = {
+#define x(n, v) { .version = v, .name = #n },
BCH_METADATA_VERSIONS()
#undef x
};
void bch2_version_to_text(struct printbuf *out, unsigned v)
{
- const char *str = v < ARRAY_SIZE(bch2_metadata_versions)
- ? bch2_metadata_versions[v]
- : "(unknown version)";
+ const char *str = "(unknown version)";
+
+ for (unsigned i = 0; i < ARRAY_SIZE(bch2_metadata_versions); i++)
+ if (bch2_metadata_versions[i].version == v) {
+ str = bch2_metadata_versions[i].name;
+ break;
+ }
+
+ prt_printf(out, "%u.%u: %s", BCH_VERSION_MAJOR(v), BCH_VERSION_MINOR(v), str);
+}
+
+unsigned bch2_latest_compatible_version(unsigned v)
+{
+ if (!BCH_VERSION_MAJOR(v))
+ return v;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(bch2_metadata_versions); i++)
+ if (bch2_metadata_versions[i].version > v &&
+ BCH_VERSION_MAJOR(bch2_metadata_versions[i].version) ==
+ BCH_VERSION_MAJOR(v))
+ v = bch2_metadata_versions[i].version;
- prt_printf(out, "%u: %s", v, str);
+ return v;
}
const char * const bch2_sb_fields[] = {
@@ -809,10 +832,9 @@ int bch2_write_super(struct bch_fs *c)
closure_init_stack(cl);
memset(&sb_written, 0, sizeof(sb_written));
- if (test_bit(BCH_FS_VERSION_UPGRADE, &c->flags)) {
- c->disk_sb.sb->magic = BCHFS_MAGIC;
- c->disk_sb.sb->layout.magic = BCHFS_MAGIC;
- }
+ /* Make sure we're using the new magic numbers: */
+ c->disk_sb.sb->magic = BCHFS_MAGIC;
+ c->disk_sb.sb->layout.magic = BCHFS_MAGIC;
le64_add_cpu(&c->disk_sb.sb->seq, 1);
@@ -1187,19 +1209,19 @@ int bch2_fs_mark_dirty(struct bch_fs *c)
mutex_lock(&c->sb_lock);
SET_BCH_SB_CLEAN(c->disk_sb.sb, false);
+ /*
+ * Downgrade, if superblock is at a higher version than currently
+ * supported:
+ */
if (BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb) > bcachefs_metadata_version_current)
SET_BCH_SB_VERSION_UPGRADE_COMPLETE(c->disk_sb.sb, bcachefs_metadata_version_current);
-
- if (test_bit(BCH_FS_VERSION_UPGRADE, &c->flags) ||
- c->sb.version > bcachefs_metadata_version_current)
+ if (c->sb.version > bcachefs_metadata_version_current)
c->disk_sb.sb->version = cpu_to_le16(bcachefs_metadata_version_current);
-
- if (test_bit(BCH_FS_VERSION_UPGRADE, &c->flags))
- c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL);
+ 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);
c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALWAYS);
-
- c->disk_sb.sb->compat[0] &= cpu_to_le64((1ULL << BCH_COMPAT_NR) - 1);
ret = bch2_write_super(c);
mutex_unlock(&c->sb_lock);
diff --git a/libbcachefs/super-io.h b/libbcachefs/super-io.h
index cda71ec8..a850cc4a 100644
--- a/libbcachefs/super-io.h
+++ b/libbcachefs/super-io.h
@@ -11,11 +11,12 @@
static inline bool bch2_version_compatible(u16 version)
{
- return version <= bcachefs_metadata_version_current &&
+ return BCH_VERSION_MAJOR(version) <= BCH_VERSION_MAJOR(bcachefs_metadata_version_current) &&
version >= bcachefs_metadata_version_min;
}
void bch2_version_to_text(struct printbuf *, unsigned);
+unsigned bch2_latest_compatible_version(unsigned);
struct bch_sb_field *bch2_sb_field_get(struct bch_sb *, enum bch_sb_field_type);
struct bch_sb_field *bch2_sb_field_resize(struct bch_sb_handle *,