summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-05-27 21:12:17 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2021-05-27 21:12:17 -0400
commitea750088b07eab9507f3ad2ca84ddc7ceb545712 (patch)
treee3326cfd257c6f1fdbd6469957299a3f1ac0a7f6
parent27d75d929f0374b69f0161bfb6791a9fff000a21 (diff)
Write a backup superblock at the end of the disk
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--libbcachefs.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/libbcachefs.c b/libbcachefs.c
index 65ca07e2..34246dc9 100644
--- a/libbcachefs.c
+++ b/libbcachefs.c
@@ -38,7 +38,7 @@ static u64 min_size(unsigned bucket_size)
static void init_layout(struct bch_sb_layout *l,
unsigned block_size,
unsigned sb_size,
- u64 start, u64 end)
+ u64 sb_start, u64 sb_end)
{
unsigned i;
@@ -51,14 +51,14 @@ static void init_layout(struct bch_sb_layout *l,
/* Create two superblocks in the allowed range: */
for (i = 0; i < l->nr_superblocks; i++) {
- if (start != BCH_SB_SECTOR)
- start = round_up(start, block_size);
+ if (sb_start != BCH_SB_SECTOR)
+ sb_start = round_up(sb_start, block_size);
- l->sb_offset[i] = cpu_to_le64(start);
- start += sb_size;
+ l->sb_offset[i] = cpu_to_le64(sb_start);
+ sb_start += sb_size;
}
- if (start >= end)
+ if (sb_start >= sb_end)
die("insufficient space for superblocks");
}
@@ -292,6 +292,21 @@ struct bch_sb *bch2_format(struct bch_opt_strs fs_opt_strs,
opts.superblock_size,
i->sb_offset, i->sb_end);
+ /*
+ * Also create a backup superblock at the end of the disk:
+ *
+ * If we're not creating a superblock at the default offset, it
+ * means we're being run from the migrate tool and we could be
+ * overwriting existing data if we write to the end of the disk:
+ */
+ if (i->sb_offset == BCH_SB_SECTOR) {
+ struct bch_sb_layout *l = &sb.sb->layout;
+ u64 backup_sb = i->size - (1 << l->sb_max_size_bits);
+
+ backup_sb = rounddown(backup_sb, i->bucket_size);
+ l->sb_offset[l->nr_superblocks++] = cpu_to_le64(backup_sb);
+ }
+
if (i->sb_offset == BCH_SB_SECTOR) {
/* Zero start of disk */
static const char zeroes[BCH_SB_SECTOR << 9];