From bb6eccc2ecd4728871bfc70462d3a4a20daa9d68 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Wed, 24 Mar 2021 22:27:43 -0400 Subject: [PATCH] Increase default superblock size to 1MB Also - add an option to bcachefs format for specifying it, --superblock_size Signed-off-by: Kent Overstreet --- cmd_format.c | 8 ++++++++ cmd_migrate.c | 11 +++++++---- libbcachefs.c | 55 +++++++++++++++++++++------------------------------ libbcachefs.h | 6 ++++-- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/cmd_format.c b/cmd_format.c index bcd69783..b88ffe91 100644 --- a/cmd_format.c +++ b/cmd_format.c @@ -36,6 +36,7 @@ x(0, no_passphrase, no_argument) \ x('L', label, required_argument) \ x('U', uuid, required_argument) \ x(0, fs_size, required_argument) \ +x(0, superblock_size, required_argument) \ x(0, bucket_size, required_argument) \ x('g', group, required_argument) \ x(0, discard, no_argument) \ @@ -62,6 +63,7 @@ static void usage(void) " --no_passphrase Don't encrypt master encryption key\n" " -L, --label=label\n" " -U, --uuid=uuid\n" + " --superblock_size=size\n" "\n" "Device specific options:"); @@ -164,6 +166,12 @@ int cmd_format(int argc, char *argv[]) dev_opts.size >>= 9; break; + case O_superblock_size: + if (bch2_strtouint_h(optarg, &opts.superblock_size)) + die("invalid filesystem size"); + + opts.superblock_size >>= 9; + break; case O_bucket_size: dev_opts.bucket_size = hatoi_validate(optarg, "bucket size"); diff --git a/cmd_migrate.c b/cmd_migrate.c index 0beebc9c..a0d27427 100644 --- a/cmd_migrate.c +++ b/cmd_migrate.c @@ -599,7 +599,9 @@ static void copy_fs(struct bch_fs *c, int src_fd, const char *src_path, bch2_alloc_write(c, false); } -static void find_superblock_space(ranges extents, struct dev_opts *dev) +static void find_superblock_space(ranges extents, + struct format_opts opts, + struct dev_opts *dev) { struct range *i; @@ -609,9 +611,10 @@ static void find_superblock_space(ranges extents, struct dev_opts *dev) u64 end = round_down(i->end, dev->bucket_size << 9); - if (start + (128 << 10) <= end) { + /* Need space for two superblocks: */ + if (start + (opts.superblock_size << 9) * 2 <= end) { dev->sb_offset = start >> 9; - dev->sb_end = dev->sb_offset + 256; + dev->sb_end = dev->sb_offset + opts.superblock_size * 2; return; } } @@ -673,7 +676,7 @@ static int migrate_fs(const char *fs_path, get_size(dev.path, dev.fd) / 5, &bcachefs_inum, stat.st_dev, force); - find_superblock_space(extents, &dev); + find_superblock_space(extents, format_opts, &dev); struct bch_sb *sb = bch2_format(fs_opt_strs, fs_opts,format_opts, &dev, 1); diff --git a/libbcachefs.c b/libbcachefs.c index 081f7ec6..1ae9b9ab 100644 --- a/libbcachefs.c +++ b/libbcachefs.c @@ -35,52 +35,35 @@ static u64 min_size(unsigned bucket_size) return BCH_MIN_NR_NBUCKETS * bucket_size; } -static void init_layout(struct bch_sb_layout *l, unsigned block_size, +static void init_layout(struct bch_sb_layout *l, + unsigned block_size, + unsigned sb_size, u64 start, u64 end) { - unsigned sb_size; - u64 backup; /* offset of 2nd sb */ + unsigned i; memset(l, 0, sizeof(*l)); - if (start != BCH_SB_SECTOR) - start = round_up(start, block_size); - end = round_down(end, block_size); - - if (start >= end) - die("insufficient space for superblocks"); - - /* - * Create two superblocks in the allowed range: reserve a maximum of 64k - */ - sb_size = min_t(u64, 128, end - start / 2); - - backup = start + sb_size; - backup = round_up(backup, block_size); - - backup = min(backup, end); - - sb_size = min(end - backup, backup- start); - sb_size = rounddown_pow_of_two(sb_size); - - if (sb_size < 8) - die("insufficient space for superblocks"); - l->magic = BCACHE_MAGIC; l->layout_type = 0; l->nr_superblocks = 2; l->sb_max_size_bits = ilog2(sb_size); - l->sb_offset[0] = cpu_to_le64(start); - l->sb_offset[1] = cpu_to_le64(backup); + + /* 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); + + l->sb_offset[i] = cpu_to_le64(start); + start += sb_size; + } + + if (start >= end) + die("insufficient space for superblocks"); } void bch2_pick_bucket_size(struct bch_opts opts, struct dev_opts *dev) { - if (!dev->sb_offset) { - dev->sb_offset = BCH_SB_SECTOR; - dev->sb_end = BCH_SB_SECTOR + 256; - } - if (!dev->size) dev->size = get_size(dev->path, dev->fd) >> 9; @@ -300,7 +283,13 @@ struct bch_sb *bch2_format(struct bch_opt_strs fs_opt_strs, for (i = devs; i < devs + nr_devs; i++) { sb.sb->dev_idx = i - devs; + if (!i->sb_offset) { + i->sb_offset = BCH_SB_SECTOR; + i->sb_end = i->size; + } + init_layout(&sb.sb->layout, fs_opts.block_size, + opts.superblock_size, i->sb_offset, i->sb_end); if (i->sb_offset == BCH_SB_SECTOR) { diff --git a/libbcachefs.h b/libbcachefs.h index abc25ba0..59c62df3 100644 --- a/libbcachefs.h +++ b/libbcachefs.h @@ -12,6 +12,8 @@ /* option parsing */ +#define SUPERBLOCK_SIZE_DEFAULT 2048 /* 1 MB */ + struct bch_opt_strs { union { char *by_id[bch2_opts_nr]; @@ -31,9 +33,8 @@ struct format_opts { char *label; uuid_le uuid; unsigned version; - + unsigned superblock_size; unsigned encoded_extent_max; - bool encrypted; char *passphrase; }; @@ -42,6 +43,7 @@ static inline struct format_opts format_opts_default() { return (struct format_opts) { .version = bcachefs_metadata_version_current, + .superblock_size = SUPERBLOCK_SIZE_DEFAULT, .encoded_extent_max = 128, }; }