Loading fs/bcachefs/opts.c +50 −58 Original line number Diff line number Diff line Loading @@ -163,16 +163,6 @@ const char * const bch2_d_types[BCH_DT_MAX] = { [DT_SUBVOL] = "subvol", }; u64 BCH2_NO_SB_OPT(const struct bch_sb *sb) { BUG(); } void SET_BCH2_NO_SB_OPT(struct bch_sb *sb, u64 v) { BUG(); } void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src) { #define x(_name, ...) \ Loading Loading @@ -223,6 +213,21 @@ void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v) } } /* dummy option, for options that aren't stored in the superblock */ typedef u64 (*sb_opt_get_fn)(const struct bch_sb *); typedef void (*sb_opt_set_fn)(struct bch_sb *, u64); typedef u64 (*member_opt_get_fn)(const struct bch_member *); typedef void (*member_opt_set_fn)(struct bch_member *, u64); __maybe_unused static const sb_opt_get_fn BCH2_NO_SB_OPT = NULL; __maybe_unused static const sb_opt_set_fn SET_BCH2_NO_SB_OPT = NULL; __maybe_unused static const member_opt_get_fn BCH2_NO_MEMBER_OPT = NULL; __maybe_unused static const member_opt_set_fn SET_BCH2_NO_MEMBER_OPT = NULL; #define type_compatible_or_null(_p, _type) \ __builtin_choose_expr( \ __builtin_types_compatible_p(typeof(_p), typeof(_type)), _p, NULL) const struct bch_option bch2_opt_table[] = { #define OPT_BOOL() .type = BCH_OPT_BOOL, .min = 0, .max = 2 #define OPT_UINT(_min, _max) .type = BCH_OPT_UINT, \ Loading @@ -239,15 +244,15 @@ const struct bch_option bch2_opt_table[] = { #define x(_name, _bits, _flags, _type, _sb_opt, _default, _hint, _help) \ [Opt_##_name] = { \ .attr = { \ .name = #_name, \ .mode = (_flags) & OPT_RUNTIME ? 0644 : 0444, \ }, \ .attr.name = #_name, \ .attr.mode = (_flags) & OPT_RUNTIME ? 0644 : 0444, \ .flags = _flags, \ .hint = _hint, \ .help = _help, \ .get_sb = _sb_opt, \ .set_sb = SET_##_sb_opt, \ .get_sb = type_compatible_or_null(_sb_opt, *BCH2_NO_SB_OPT), \ .set_sb = type_compatible_or_null(SET_##_sb_opt,*SET_BCH2_NO_SB_OPT), \ .get_member = type_compatible_or_null(_sb_opt, *BCH2_NO_MEMBER_OPT), \ .set_member = type_compatible_or_null(SET_##_sb_opt,*SET_BCH2_NO_MEMBER_OPT),\ _type \ }, Loading Loading @@ -495,12 +500,8 @@ int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v) int bch2_opts_check_may_set(struct bch_fs *c) { unsigned i; int ret; for (i = 0; i < bch2_opts_nr; i++) { ret = bch2_opt_check_may_set(c, i, bch2_opt_get_by_id(&c->opts, i)); for (unsigned i = 0; i < bch2_opts_nr; i++) { int ret = bch2_opt_check_may_set(c, i, bch2_opt_get_by_id(&c->opts, i)); if (ret) return ret; } Loading Loading @@ -619,12 +620,25 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts, return ret; } u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id) u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id, int dev_idx) { const struct bch_option *opt = bch2_opt_table + id; u64 v; if (dev_idx < 0) { v = opt->get_sb(sb); } else { if (WARN(!bch2_member_exists(sb, dev_idx), "tried to set device option %s on nonexistent device %i", opt->attr.name, dev_idx)) return 0; struct bch_member m = bch2_sb_member_get(sb, dev_idx); v = opt->get_member(&m); } if (opt->flags & OPT_SB_FIELD_ONE_BIAS) --v; if (opt->flags & OPT_SB_FIELD_ILOG2) v = 1ULL << v; Loading @@ -641,35 +655,19 @@ u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id) */ int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb) { unsigned id; for (id = 0; id < bch2_opts_nr; id++) { for (unsigned id = 0; id < bch2_opts_nr; id++) { const struct bch_option *opt = bch2_opt_table + id; if (opt->get_sb == BCH2_NO_SB_OPT) continue; bch2_opt_set_by_id(opts, id, bch2_opt_from_sb(sb, id)); if (opt->get_sb) bch2_opt_set_by_id(opts, id, bch2_opt_from_sb(sb, id, -1)); } return 0; } struct bch_dev_sb_opt_set { void (*set_sb)(struct bch_member *, u64); }; static const struct bch_dev_sb_opt_set bch2_dev_sb_opt_setters [] = { #define x(n, set) [Opt_##n] = { .set_sb = SET_##set }, BCH_DEV_OPT_SETTERS() #undef x }; void __bch2_opt_set_sb(struct bch_sb *sb, int dev_idx, const struct bch_option *opt, u64 v) { enum bch_opt_id id = opt - bch2_opt_table; if (opt->flags & OPT_SB_FIELD_SECTORS) v >>= 9; Loading @@ -679,24 +677,18 @@ void __bch2_opt_set_sb(struct bch_sb *sb, int dev_idx, if (opt->flags & OPT_SB_FIELD_ONE_BIAS) v++; if (opt->flags & OPT_FS) { if (opt->set_sb != SET_BCH2_NO_SB_OPT) if ((opt->flags & OPT_FS) && opt->set_sb) opt->set_sb(sb, v); } if ((opt->flags & OPT_DEVICE) && dev_idx >= 0) { if ((opt->flags & OPT_DEVICE) && opt->set_member && dev_idx >= 0) { if (WARN(!bch2_member_exists(sb, dev_idx), "tried to set device option %s on nonexistent device %i", opt->attr.name, dev_idx)) return; struct bch_member *m = bch2_members_v2_get_mut(sb, dev_idx); const struct bch_dev_sb_opt_set *set = bch2_dev_sb_opt_setters + id; if (set->set_sb) set->set_sb(m, v); else pr_err("option %s cannot be set via opt_set_sb()", opt->attr.name); opt->set_member(bch2_members_v2_get_mut(sb, dev_idx), v); } } Loading fs/bcachefs/opts.h +25 −25 Original line number Diff line number Diff line Loading @@ -50,10 +50,6 @@ static inline const char *bch2_d_type_str(unsigned d_type) * apply the options from that struct that are defined. */ /* dummy option, for options that aren't stored in the superblock */ u64 BCH2_NO_SB_OPT(const struct bch_sb *); void SET_BCH2_NO_SB_OPT(struct bch_sb *, u64); /* When can be set: */ enum opt_flags { OPT_FS = BIT(0), /* Filesystem option */ Loading Loading @@ -318,11 +314,6 @@ enum fsck_err_opts { OPT_BOOL(), \ BCH2_NO_SB_OPT, false, \ NULL, "Don't kick drives out when splitbrain detected")\ x(discard, u8, \ OPT_FS|OPT_MOUNT|OPT_DEVICE, \ OPT_BOOL(), \ BCH2_NO_SB_OPT, true, \ NULL, "Enable discard/TRIM support") \ x(verbose, u8, \ OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ OPT_BOOL(), \ Loading Loading @@ -503,27 +494,37 @@ enum fsck_err_opts { BCH2_NO_SB_OPT, false, \ NULL, "Skip submit_bio() for data reads and writes, " \ "for performance testing purposes") \ x(fs_size, u64, \ x(state, u64, \ OPT_DEVICE, \ OPT_STR(bch2_member_states), \ BCH_MEMBER_STATE, BCH_MEMBER_STATE_rw, \ "state", "rw,ro,failed,spare") \ x(fs_size, u64, \ OPT_DEVICE|OPT_HIDDEN, \ OPT_UINT(0, S64_MAX), \ BCH2_NO_SB_OPT, 0, \ BCH2_NO_MEMBER_OPT, 0, \ "size", "Size of filesystem on device") \ x(bucket, u32, \ OPT_DEVICE, \ x(bucket_size, u32, \ OPT_DEVICE|OPT_HUMAN_READABLE|OPT_SB_FIELD_SECTORS, \ OPT_UINT(0, S64_MAX), \ BCH2_NO_SB_OPT, 0, \ BCH_MEMBER_BUCKET_SIZE, 0, \ "size", "Specifies the bucket size; must be greater than the btree node size")\ x(durability, u8, \ OPT_DEVICE|OPT_SB_FIELD_ONE_BIAS, \ OPT_DEVICE|OPT_RUNTIME|OPT_SB_FIELD_ONE_BIAS, \ OPT_UINT(0, BCH_REPLICAS_MAX), \ BCH2_NO_SB_OPT, 1, \ BCH_MEMBER_DURABILITY, 1, \ "n", "Data written to this device will be considered\n"\ "to have already been replicated n times") \ x(data_allowed, u8, \ OPT_DEVICE, \ OPT_BITFIELD(__bch2_data_types), \ BCH2_NO_SB_OPT, BIT(BCH_DATA_journal)|BIT(BCH_DATA_btree)|BIT(BCH_DATA_user),\ BCH_MEMBER_DATA_ALLOWED, BIT(BCH_DATA_journal)|BIT(BCH_DATA_btree)|BIT(BCH_DATA_user),\ "types", "Allowed data types for this device: journal, btree, and/or user")\ x(discard, u8, \ OPT_MOUNT|OPT_DEVICE|OPT_RUNTIME, \ OPT_BOOL(), \ BCH_MEMBER_DISCARD, true, \ NULL, "Enable discard/TRIM support") \ x(btree_node_prefetch, u8, \ OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ OPT_BOOL(), \ Loading @@ -531,11 +532,6 @@ enum fsck_err_opts { NULL, "BTREE_ITER_prefetch casuse btree nodes to be\n"\ " prefetched sequentially") #define BCH_DEV_OPT_SETTERS() \ x(discard, BCH_MEMBER_DISCARD) \ x(durability, BCH_MEMBER_DURABILITY) \ x(data_allowed, BCH_MEMBER_DATA_ALLOWED) struct bch_opts { #define x(_name, _bits, ...) unsigned _name##_defined:1; BCH_OPTS() Loading Loading @@ -592,8 +588,6 @@ struct printbuf; struct bch_option { struct attribute attr; u64 (*get_sb)(const struct bch_sb *); void (*set_sb)(struct bch_sb *, u64); enum opt_type type; enum opt_flags flags; u64 min, max; Loading @@ -605,6 +599,12 @@ struct bch_option { const char *hint; const char *help; u64 (*get_sb)(const struct bch_sb *); void (*set_sb)(struct bch_sb *, u64); u64 (*get_member)(const struct bch_member *); void (*set_member)(struct bch_member *, u64); }; extern const struct bch_option bch2_opt_table[]; Loading @@ -613,7 +613,7 @@ bool bch2_opt_defined_by_id(const struct bch_opts *, enum bch_opt_id); u64 bch2_opt_get_by_id(const struct bch_opts *, enum bch_opt_id); void bch2_opt_set_by_id(struct bch_opts *, enum bch_opt_id, u64); u64 bch2_opt_from_sb(struct bch_sb *, enum bch_opt_id); u64 bch2_opt_from_sb(struct bch_sb *, enum bch_opt_id, int); int bch2_opts_from_sb(struct bch_opts *, struct bch_sb *); void __bch2_opt_set_sb(struct bch_sb *, int, const struct bch_option *, u64); Loading fs/bcachefs/sb-members_format.h +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ struct bch_member { #define BCH_MEMBER_V1_BYTES 56 LE16_BITMASK(BCH_MEMBER_BUCKET_SIZE, struct bch_member, bucket_size, 0, 16) LE64_BITMASK(BCH_MEMBER_STATE, struct bch_member, flags, 0, 4) /* 4-14 unused, was TIER, HAS_(META)DATA, REPLACEMENT */ LE64_BITMASK(BCH_MEMBER_DISCARD, struct bch_member, flags, 14, 15) Loading fs/bcachefs/super-io.c +4 −4 Original line number Diff line number Diff line Loading @@ -489,8 +489,8 @@ int bch2_sb_validate(struct bch_sb *sb, u64 read_offset, for (opt_id = 0; opt_id < bch2_opts_nr; opt_id++) { const struct bch_option *opt = bch2_opt_table + opt_id; if (opt->get_sb != BCH2_NO_SB_OPT) { u64 v = bch2_opt_from_sb(sb, opt_id); if (opt->get_sb) { u64 v = bch2_opt_from_sb(sb, opt_id, -1); prt_printf(out, "Invalid option "); ret = bch2_opt_validate(opt, v, out); Loading Loading @@ -1473,8 +1473,8 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb, for (id = 0; id < bch2_opts_nr; id++) { const struct bch_option *opt = bch2_opt_table + id; if (opt->get_sb != BCH2_NO_SB_OPT) { u64 v = bch2_opt_from_sb(sb, id); if (opt->get_sb) { u64 v = bch2_opt_from_sb(sb, id, -1); prt_printf(out, "%s:\t", opt->attr.name); bch2_opt_to_text(out, NULL, sb, opt, v, Loading Loading
fs/bcachefs/opts.c +50 −58 Original line number Diff line number Diff line Loading @@ -163,16 +163,6 @@ const char * const bch2_d_types[BCH_DT_MAX] = { [DT_SUBVOL] = "subvol", }; u64 BCH2_NO_SB_OPT(const struct bch_sb *sb) { BUG(); } void SET_BCH2_NO_SB_OPT(struct bch_sb *sb, u64 v) { BUG(); } void bch2_opts_apply(struct bch_opts *dst, struct bch_opts src) { #define x(_name, ...) \ Loading Loading @@ -223,6 +213,21 @@ void bch2_opt_set_by_id(struct bch_opts *opts, enum bch_opt_id id, u64 v) } } /* dummy option, for options that aren't stored in the superblock */ typedef u64 (*sb_opt_get_fn)(const struct bch_sb *); typedef void (*sb_opt_set_fn)(struct bch_sb *, u64); typedef u64 (*member_opt_get_fn)(const struct bch_member *); typedef void (*member_opt_set_fn)(struct bch_member *, u64); __maybe_unused static const sb_opt_get_fn BCH2_NO_SB_OPT = NULL; __maybe_unused static const sb_opt_set_fn SET_BCH2_NO_SB_OPT = NULL; __maybe_unused static const member_opt_get_fn BCH2_NO_MEMBER_OPT = NULL; __maybe_unused static const member_opt_set_fn SET_BCH2_NO_MEMBER_OPT = NULL; #define type_compatible_or_null(_p, _type) \ __builtin_choose_expr( \ __builtin_types_compatible_p(typeof(_p), typeof(_type)), _p, NULL) const struct bch_option bch2_opt_table[] = { #define OPT_BOOL() .type = BCH_OPT_BOOL, .min = 0, .max = 2 #define OPT_UINT(_min, _max) .type = BCH_OPT_UINT, \ Loading @@ -239,15 +244,15 @@ const struct bch_option bch2_opt_table[] = { #define x(_name, _bits, _flags, _type, _sb_opt, _default, _hint, _help) \ [Opt_##_name] = { \ .attr = { \ .name = #_name, \ .mode = (_flags) & OPT_RUNTIME ? 0644 : 0444, \ }, \ .attr.name = #_name, \ .attr.mode = (_flags) & OPT_RUNTIME ? 0644 : 0444, \ .flags = _flags, \ .hint = _hint, \ .help = _help, \ .get_sb = _sb_opt, \ .set_sb = SET_##_sb_opt, \ .get_sb = type_compatible_or_null(_sb_opt, *BCH2_NO_SB_OPT), \ .set_sb = type_compatible_or_null(SET_##_sb_opt,*SET_BCH2_NO_SB_OPT), \ .get_member = type_compatible_or_null(_sb_opt, *BCH2_NO_MEMBER_OPT), \ .set_member = type_compatible_or_null(SET_##_sb_opt,*SET_BCH2_NO_MEMBER_OPT),\ _type \ }, Loading Loading @@ -495,12 +500,8 @@ int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v) int bch2_opts_check_may_set(struct bch_fs *c) { unsigned i; int ret; for (i = 0; i < bch2_opts_nr; i++) { ret = bch2_opt_check_may_set(c, i, bch2_opt_get_by_id(&c->opts, i)); for (unsigned i = 0; i < bch2_opts_nr; i++) { int ret = bch2_opt_check_may_set(c, i, bch2_opt_get_by_id(&c->opts, i)); if (ret) return ret; } Loading Loading @@ -619,12 +620,25 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts, return ret; } u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id) u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id, int dev_idx) { const struct bch_option *opt = bch2_opt_table + id; u64 v; if (dev_idx < 0) { v = opt->get_sb(sb); } else { if (WARN(!bch2_member_exists(sb, dev_idx), "tried to set device option %s on nonexistent device %i", opt->attr.name, dev_idx)) return 0; struct bch_member m = bch2_sb_member_get(sb, dev_idx); v = opt->get_member(&m); } if (opt->flags & OPT_SB_FIELD_ONE_BIAS) --v; if (opt->flags & OPT_SB_FIELD_ILOG2) v = 1ULL << v; Loading @@ -641,35 +655,19 @@ u64 bch2_opt_from_sb(struct bch_sb *sb, enum bch_opt_id id) */ int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb) { unsigned id; for (id = 0; id < bch2_opts_nr; id++) { for (unsigned id = 0; id < bch2_opts_nr; id++) { const struct bch_option *opt = bch2_opt_table + id; if (opt->get_sb == BCH2_NO_SB_OPT) continue; bch2_opt_set_by_id(opts, id, bch2_opt_from_sb(sb, id)); if (opt->get_sb) bch2_opt_set_by_id(opts, id, bch2_opt_from_sb(sb, id, -1)); } return 0; } struct bch_dev_sb_opt_set { void (*set_sb)(struct bch_member *, u64); }; static const struct bch_dev_sb_opt_set bch2_dev_sb_opt_setters [] = { #define x(n, set) [Opt_##n] = { .set_sb = SET_##set }, BCH_DEV_OPT_SETTERS() #undef x }; void __bch2_opt_set_sb(struct bch_sb *sb, int dev_idx, const struct bch_option *opt, u64 v) { enum bch_opt_id id = opt - bch2_opt_table; if (opt->flags & OPT_SB_FIELD_SECTORS) v >>= 9; Loading @@ -679,24 +677,18 @@ void __bch2_opt_set_sb(struct bch_sb *sb, int dev_idx, if (opt->flags & OPT_SB_FIELD_ONE_BIAS) v++; if (opt->flags & OPT_FS) { if (opt->set_sb != SET_BCH2_NO_SB_OPT) if ((opt->flags & OPT_FS) && opt->set_sb) opt->set_sb(sb, v); } if ((opt->flags & OPT_DEVICE) && dev_idx >= 0) { if ((opt->flags & OPT_DEVICE) && opt->set_member && dev_idx >= 0) { if (WARN(!bch2_member_exists(sb, dev_idx), "tried to set device option %s on nonexistent device %i", opt->attr.name, dev_idx)) return; struct bch_member *m = bch2_members_v2_get_mut(sb, dev_idx); const struct bch_dev_sb_opt_set *set = bch2_dev_sb_opt_setters + id; if (set->set_sb) set->set_sb(m, v); else pr_err("option %s cannot be set via opt_set_sb()", opt->attr.name); opt->set_member(bch2_members_v2_get_mut(sb, dev_idx), v); } } Loading
fs/bcachefs/opts.h +25 −25 Original line number Diff line number Diff line Loading @@ -50,10 +50,6 @@ static inline const char *bch2_d_type_str(unsigned d_type) * apply the options from that struct that are defined. */ /* dummy option, for options that aren't stored in the superblock */ u64 BCH2_NO_SB_OPT(const struct bch_sb *); void SET_BCH2_NO_SB_OPT(struct bch_sb *, u64); /* When can be set: */ enum opt_flags { OPT_FS = BIT(0), /* Filesystem option */ Loading Loading @@ -318,11 +314,6 @@ enum fsck_err_opts { OPT_BOOL(), \ BCH2_NO_SB_OPT, false, \ NULL, "Don't kick drives out when splitbrain detected")\ x(discard, u8, \ OPT_FS|OPT_MOUNT|OPT_DEVICE, \ OPT_BOOL(), \ BCH2_NO_SB_OPT, true, \ NULL, "Enable discard/TRIM support") \ x(verbose, u8, \ OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ OPT_BOOL(), \ Loading Loading @@ -503,27 +494,37 @@ enum fsck_err_opts { BCH2_NO_SB_OPT, false, \ NULL, "Skip submit_bio() for data reads and writes, " \ "for performance testing purposes") \ x(fs_size, u64, \ x(state, u64, \ OPT_DEVICE, \ OPT_STR(bch2_member_states), \ BCH_MEMBER_STATE, BCH_MEMBER_STATE_rw, \ "state", "rw,ro,failed,spare") \ x(fs_size, u64, \ OPT_DEVICE|OPT_HIDDEN, \ OPT_UINT(0, S64_MAX), \ BCH2_NO_SB_OPT, 0, \ BCH2_NO_MEMBER_OPT, 0, \ "size", "Size of filesystem on device") \ x(bucket, u32, \ OPT_DEVICE, \ x(bucket_size, u32, \ OPT_DEVICE|OPT_HUMAN_READABLE|OPT_SB_FIELD_SECTORS, \ OPT_UINT(0, S64_MAX), \ BCH2_NO_SB_OPT, 0, \ BCH_MEMBER_BUCKET_SIZE, 0, \ "size", "Specifies the bucket size; must be greater than the btree node size")\ x(durability, u8, \ OPT_DEVICE|OPT_SB_FIELD_ONE_BIAS, \ OPT_DEVICE|OPT_RUNTIME|OPT_SB_FIELD_ONE_BIAS, \ OPT_UINT(0, BCH_REPLICAS_MAX), \ BCH2_NO_SB_OPT, 1, \ BCH_MEMBER_DURABILITY, 1, \ "n", "Data written to this device will be considered\n"\ "to have already been replicated n times") \ x(data_allowed, u8, \ OPT_DEVICE, \ OPT_BITFIELD(__bch2_data_types), \ BCH2_NO_SB_OPT, BIT(BCH_DATA_journal)|BIT(BCH_DATA_btree)|BIT(BCH_DATA_user),\ BCH_MEMBER_DATA_ALLOWED, BIT(BCH_DATA_journal)|BIT(BCH_DATA_btree)|BIT(BCH_DATA_user),\ "types", "Allowed data types for this device: journal, btree, and/or user")\ x(discard, u8, \ OPT_MOUNT|OPT_DEVICE|OPT_RUNTIME, \ OPT_BOOL(), \ BCH_MEMBER_DISCARD, true, \ NULL, "Enable discard/TRIM support") \ x(btree_node_prefetch, u8, \ OPT_FS|OPT_MOUNT|OPT_RUNTIME, \ OPT_BOOL(), \ Loading @@ -531,11 +532,6 @@ enum fsck_err_opts { NULL, "BTREE_ITER_prefetch casuse btree nodes to be\n"\ " prefetched sequentially") #define BCH_DEV_OPT_SETTERS() \ x(discard, BCH_MEMBER_DISCARD) \ x(durability, BCH_MEMBER_DURABILITY) \ x(data_allowed, BCH_MEMBER_DATA_ALLOWED) struct bch_opts { #define x(_name, _bits, ...) unsigned _name##_defined:1; BCH_OPTS() Loading Loading @@ -592,8 +588,6 @@ struct printbuf; struct bch_option { struct attribute attr; u64 (*get_sb)(const struct bch_sb *); void (*set_sb)(struct bch_sb *, u64); enum opt_type type; enum opt_flags flags; u64 min, max; Loading @@ -605,6 +599,12 @@ struct bch_option { const char *hint; const char *help; u64 (*get_sb)(const struct bch_sb *); void (*set_sb)(struct bch_sb *, u64); u64 (*get_member)(const struct bch_member *); void (*set_member)(struct bch_member *, u64); }; extern const struct bch_option bch2_opt_table[]; Loading @@ -613,7 +613,7 @@ bool bch2_opt_defined_by_id(const struct bch_opts *, enum bch_opt_id); u64 bch2_opt_get_by_id(const struct bch_opts *, enum bch_opt_id); void bch2_opt_set_by_id(struct bch_opts *, enum bch_opt_id, u64); u64 bch2_opt_from_sb(struct bch_sb *, enum bch_opt_id); u64 bch2_opt_from_sb(struct bch_sb *, enum bch_opt_id, int); int bch2_opts_from_sb(struct bch_opts *, struct bch_sb *); void __bch2_opt_set_sb(struct bch_sb *, int, const struct bch_option *, u64); Loading
fs/bcachefs/sb-members_format.h +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ struct bch_member { #define BCH_MEMBER_V1_BYTES 56 LE16_BITMASK(BCH_MEMBER_BUCKET_SIZE, struct bch_member, bucket_size, 0, 16) LE64_BITMASK(BCH_MEMBER_STATE, struct bch_member, flags, 0, 4) /* 4-14 unused, was TIER, HAS_(META)DATA, REPLACEMENT */ LE64_BITMASK(BCH_MEMBER_DISCARD, struct bch_member, flags, 14, 15) Loading
fs/bcachefs/super-io.c +4 −4 Original line number Diff line number Diff line Loading @@ -489,8 +489,8 @@ int bch2_sb_validate(struct bch_sb *sb, u64 read_offset, for (opt_id = 0; opt_id < bch2_opts_nr; opt_id++) { const struct bch_option *opt = bch2_opt_table + opt_id; if (opt->get_sb != BCH2_NO_SB_OPT) { u64 v = bch2_opt_from_sb(sb, opt_id); if (opt->get_sb) { u64 v = bch2_opt_from_sb(sb, opt_id, -1); prt_printf(out, "Invalid option "); ret = bch2_opt_validate(opt, v, out); Loading Loading @@ -1473,8 +1473,8 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb, for (id = 0; id < bch2_opts_nr; id++) { const struct bch_option *opt = bch2_opt_table + id; if (opt->get_sb != BCH2_NO_SB_OPT) { u64 v = bch2_opt_from_sb(sb, id); if (opt->get_sb) { u64 v = bch2_opt_from_sb(sb, id, -1); prt_printf(out, "%s:\t", opt->attr.name); bch2_opt_to_text(out, NULL, sb, opt, v, Loading