summaryrefslogtreecommitdiff
path: root/c_src/cmd_migrate.c
diff options
context:
space:
mode:
authorNikita Ofitserov <himikof@gmail.com>2025-09-07 00:03:54 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2025-09-06 17:56:19 -0400
commit020763ad669681821922031097e4140cd39f7d67 (patch)
tree0ef9941647097c25c38a38e2b7eb59f8fc69899b /c_src/cmd_migrate.c
parent277ddb57ef0ad14785a4898f886bf63fac3c1d37 (diff)
cmd_migrate: Reimplement cmd_migrate_superblock
Now the FS is first started RW, then new superblock is written and metadata updated. This ensures that all recovery/upgrades/downgrades are performed at the beginning. Signed-off-by: Nikita Ofitserov <himikof@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'c_src/cmd_migrate.c')
-rw-r--r--c_src/cmd_migrate.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/c_src/cmd_migrate.c b/c_src/cmd_migrate.c
index 8d2799ba..ee6590e3 100644
--- a/c_src/cmd_migrate.c
+++ b/c_src/cmd_migrate.c
@@ -443,17 +443,19 @@ int cmd_migrate_superblock(int argc, char *argv[])
int fd = xopen(devs.data[0], O_RDWR);
struct bch_sb *sb = __bch2_super_read(fd, sb_offset);
unsigned sb_size;
+ /* Check for invocation errors early */
add_default_sb_layout(sb, &sb_size);
- /* also write first 0-3.5k bytes with zeroes, ensure we blow away old
- * superblock */
+ /* Rewrite first 0-3.5k bytes with zeroes, ensuring we blow away
+ * the old superblock */
static const char zeroes[BCH_SB_SECTOR << 9];
- xpwrite(fd, zeroes, BCH_SB_SECTOR << 9, 0, "zeroing start of disk");
+ xpwrite(fd, zeroes, ARRAY_SIZE(zeroes), 0, "zeroing start of disk");
- bch2_super_write(fd, sb);
xclose(fd);
- /* mark new superblocks */
+ /* We start a normal FS instance with the sb buckets temporarily
+ * prohibited from allocation, performing any recovery/upgrade/downgrade
+ * as needed, and only then change the superblock layout */
struct bch_opts opts = bch2_opts_empty();
opt_set(opts, nostart, true);
@@ -472,6 +474,21 @@ int cmd_migrate_superblock(int argc, char *argv[])
if (ret)
die("Error starting filesystem: %s", bch2_err_str(ret));
+ BUG_ON(1U << ca->disk_sb.sb->layout.sb_max_size_bits != sb_size);
+
+ /* Here the FS is already RW.
+ * Apply the superblock layout changes first, everything else can be
+ * repaired on a subsequent recovery */
+ add_default_sb_layout(ca->disk_sb.sb, NULL);
+ ret = bch2_write_super(c);
+ if (ret)
+ die("Error writing superblock: %s", bch2_err_str(ret));
+
+ /* Now explicitly mark the new sb buckets in FS metadata */
+ ret = bch2_trans_mark_dev_sb(c, ca, BTREE_TRIGGER_transactional);
+ if (ret)
+ die("Error marking superblock buckets: %s", bch2_err_str(ret));
+
bch2_fs_stop(c);
opts = bch2_opts_empty();