diff options
author | Nikita Ofitserov <himikof@gmail.com> | 2025-09-07 00:03:54 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-09-06 17:56:19 -0400 |
commit | 020763ad669681821922031097e4140cd39f7d67 (patch) | |
tree | 0ef9941647097c25c38a38e2b7eb59f8fc69899b /c_src | |
parent | 277ddb57ef0ad14785a4898f886bf63fac3c1d37 (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')
-rw-r--r-- | c_src/cmd_migrate.c | 27 |
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(); |