diff options
Diffstat (limited to 'libbcachefs.c')
-rw-r--r-- | libbcachefs.c | 127 |
1 files changed, 110 insertions, 17 deletions
diff --git a/libbcachefs.c b/libbcachefs.c index bdf2924f..9baaff04 100644 --- a/libbcachefs.c +++ b/libbcachefs.c @@ -124,12 +124,41 @@ void bch2_pick_bucket_size(struct format_opts opts, struct dev_opts *dev) } +static unsigned parse_target(struct dev_opts *devs, size_t nr_devs, + struct bch_sb_field_disk_groups *gi, + const char *s) +{ + struct bch_disk_group *g; + struct dev_opts *i; + + if (!s) + return 0; + + for (i = devs; i < devs + nr_devs; i++) + if (!strcmp(s, i->path)) + return dev_to_target(i - devs); + + for (g = gi->entries; + g < gi->entries + disk_groups_nr(gi); + g++) { + unsigned len = strnlen(g->label, sizeof(g->label)); + + if (len == strlen(s) && + !memcmp(s, g->label, len)) + return group_to_target(g - gi->entries); + } + + die("Invalid target %s", s); + return 0; +} + struct bch_sb *bch2_format(struct format_opts opts, struct dev_opts *devs, size_t nr_devs) { struct bch_sb *sb; struct dev_opts *i; struct bch_sb_field_members *mi; + struct bch_sb_field_disk_groups *gi = NULL; unsigned u64s; /* calculate block size: */ @@ -164,6 +193,8 @@ struct bch_sb *bch2_format(struct format_opts opts, sb = calloc(1, sizeof(*sb) + sizeof(struct bch_sb_field_members) + sizeof(struct bch_member) * nr_devs + + sizeof(struct bch_sb_field_disk_groups) + + sizeof(struct bch_disk_group) * nr_devs + sizeof(struct bch_sb_field_crypt)); sb->version = cpu_to_le64(BCH_SB_VERSION_MAX); @@ -201,27 +232,15 @@ struct bch_sb *bch2_format(struct format_opts opts, sb->time_base_lo = cpu_to_le64(now.tv_sec * NSEC_PER_SEC + now.tv_nsec); sb->time_precision = cpu_to_le32(1); - if (opts.encrypted) { - struct bch_sb_field_crypt *crypt = vstruct_end(sb); - - u64s = sizeof(struct bch_sb_field_crypt) / sizeof(u64); - - le32_add_cpu(&sb->u64s, u64s); - crypt->field.u64s = cpu_to_le32(u64s); - crypt->field.type = BCH_SB_FIELD_crypt; - - bch_sb_crypt_init(sb, crypt, opts.passphrase); - SET_BCH_SB_ENCRYPTION_TYPE(sb, 1); - } - mi = vstruct_end(sb); u64s = (sizeof(struct bch_sb_field_members) + sizeof(struct bch_member) * nr_devs) / sizeof(u64); le32_add_cpu(&sb->u64s, u64s); - mi->field.u64s = cpu_to_le32(u64s); + le32_add_cpu(&mi->field.u64s, u64s); mi->field.type = BCH_SB_FIELD_members; + /* Member info: */ for (i = devs; i < devs + nr_devs; i++) { struct bch_member *m = mi->members + (i - devs); @@ -230,12 +249,67 @@ struct bch_sb *bch2_format(struct format_opts opts, m->first_bucket = 0; m->bucket_size = cpu_to_le16(i->bucket_size); - SET_BCH_MEMBER_TIER(m, i->tier); SET_BCH_MEMBER_REPLACEMENT(m, CACHE_REPLACEMENT_LRU); SET_BCH_MEMBER_DISCARD(m, i->discard); SET_BCH_MEMBER_DATA_ALLOWED(m, i->data_allowed); } + /* Disk groups */ + for (i = devs; i < devs + nr_devs; i++) { + struct bch_member *m = mi->members + (i - devs); + struct bch_disk_group *g; + size_t len; + int idx; + + if (!i->group) + continue; + + len = min_t(size_t, strlen(i->group) + 1, BCH_SB_LABEL_SIZE); + + if (!gi) { + gi = vstruct_end(sb); + u64s = sizeof(*gi) / sizeof(u64); + le32_add_cpu(&sb->u64s, u64s); + le32_add_cpu(&gi->field.u64s, u64s); + gi->field.type = BCH_SB_FIELD_disk_groups; + } + + idx = __bch2_disk_group_find(gi, i->group); + if (idx >= 0) { + g = gi->entries + idx; + } else { + u64s = sizeof(*g) / sizeof(u64); + g = vstruct_end(&gi->field); + le32_add_cpu(&sb->u64s, u64s); + le32_add_cpu(&gi->field.u64s, u64s); + memcpy(g->label, i->group, len); + SET_BCH_GROUP_DATA_ALLOWED(g, ~0); + } + + SET_BCH_MEMBER_GROUP(m, (g - gi->entries) + 1); + } + + SET_BCH_SB_FOREGROUND_TARGET(sb, + parse_target(devs, nr_devs, gi, opts.foreground_target)); + SET_BCH_SB_BACKGROUND_TARGET(sb, + parse_target(devs, nr_devs, gi, opts.background_target)); + SET_BCH_SB_PROMOTE_TARGET(sb, + parse_target(devs, nr_devs, gi, opts.promote_target)); + + /* Crypt: */ + if (opts.encrypted) { + struct bch_sb_field_crypt *crypt = vstruct_end(sb); + + u64s = sizeof(struct bch_sb_field_crypt) / sizeof(u64); + + le32_add_cpu(&sb->u64s, u64s); + crypt->field.u64s = cpu_to_le32(u64s); + crypt->field.type = BCH_SB_FIELD_crypt; + + bch_sb_crypt_init(sb, crypt, opts.passphrase); + SET_BCH_SB_ENCRYPTION_TYPE(sb, 1); + } + for (i = devs; i < devs + nr_devs; i++) { sb->dev_idx = i - devs; @@ -355,6 +429,7 @@ static void bch2_sb_print_members(struct bch_sb *sb, struct bch_sb_field *f, enum units units) { struct bch_sb_field_members *mi = field_to_type(f, members); + struct bch_sb_field_disk_groups *gi = bch2_sb_get_disk_groups(sb); unsigned i; for (i = 0; i < sb->nr_devices; i++) { @@ -363,11 +438,21 @@ static void bch2_sb_print_members(struct bch_sb *sb, struct bch_sb_field *f, char member_uuid_str[40]; char data_allowed_str[100]; char data_has_str[100]; + char group[64]; if (!bch2_member_exists(m)) continue; uuid_unparse(m->uuid.b, member_uuid_str); + + if (BCH_MEMBER_GROUP(m)) { + if (BCH_MEMBER_GROUP(m) < disk_groups_nr(gi)) + memcpy(group, gi->entries[BCH_MEMBER_GROUP(m)].label, + BCH_SB_LABEL_SIZE); + else + strcpy(group, "(bad disk groups section"); + } + bch2_scnprint_flag_list(data_allowed_str, sizeof(data_allowed_str), bch2_data_types, @@ -390,7 +475,7 @@ static void bch2_sb_print_members(struct bch_sb *sb, struct bch_sb_field *f, " Buckets: %llu\n" " Last mount: %s\n" " State: %s\n" - " Tier: %llu\n" + " Group: %s\n" " Data allowed: %s\n" " Has data: %s\n" @@ -409,7 +494,7 @@ static void bch2_sb_print_members(struct bch_sb *sb, struct bch_sb_field *f, ? bch2_dev_state[BCH_MEMBER_STATE(m)] : "unknown", - BCH_MEMBER_TIER(m), + group, data_allowed_str, data_has_str, @@ -540,6 +625,10 @@ void bch2_sb_print(struct bch_sb *sb, bool print_layout, "Data checksum type: %s (%llu)\n" "Compression type: %s (%llu)\n" + "Foreground write target: %llu\n" + "Background write target: %llu\n" + "Promote target: %llu\n" + "String hash type: %s (%llu)\n" "32 bit inodes: %llu\n" "GC reserve percentage: %llu%%\n" @@ -579,6 +668,10 @@ void bch2_sb_print(struct bch_sb *sb, bool print_layout, : "unknown", BCH_SB_COMPRESSION_TYPE(sb), + BCH_SB_FOREGROUND_TARGET(sb), + BCH_SB_BACKGROUND_TARGET(sb), + BCH_SB_PROMOTE_TARGET(sb), + BCH_SB_STR_HASH_TYPE(sb) < BCH_STR_HASH_NR ? bch2_str_hash_types[BCH_SB_STR_HASH_TYPE(sb)] : "unknown", |