| /* SPDX-License-Identifier: GPL-2.0 */ | |
| #ifndef _BCACHEFS_DISK_GROUPS_H | |
| #define _BCACHEFS_DISK_GROUPS_H | |
| #include "disk_groups_types.h" | |
| extern const struct bch_sb_field_ops bch_sb_field_ops_disk_groups; | |
| static inline unsigned disk_groups_nr(struct bch_sb_field_disk_groups *groups) | |
| { | |
| return groups | |
| ? (vstruct_end(&groups->field) - | |
| (void *) &groups->entries[0]) / sizeof(struct bch_disk_group) | |
| : 0; | |
| } | |
| struct target { | |
| enum { | |
| TARGET_NULL, | |
| TARGET_DEV, | |
| TARGET_GROUP, | |
| } type; | |
| union { | |
| unsigned dev; | |
| unsigned group; | |
| }; | |
| }; | |
| #define TARGET_DEV_START 1 | |
| #define TARGET_GROUP_START (256 + TARGET_DEV_START) | |
| static inline u16 dev_to_target(unsigned dev) | |
| { | |
| return TARGET_DEV_START + dev; | |
| } | |
| static inline u16 group_to_target(unsigned group) | |
| { | |
| return TARGET_GROUP_START + group; | |
| } | |
| static inline struct target target_decode(unsigned target) | |
| { | |
| if (target >= TARGET_GROUP_START) | |
| return (struct target) { | |
| .type = TARGET_GROUP, | |
| .group = target - TARGET_GROUP_START | |
| }; | |
| if (target >= TARGET_DEV_START) | |
| return (struct target) { | |
| .type = TARGET_DEV, | |
| .group = target - TARGET_DEV_START | |
| }; | |
| return (struct target) { .type = TARGET_NULL }; | |
| } | |
| const struct bch_devs_mask *bch2_target_to_mask(struct bch_fs *, unsigned); | |
| static inline struct bch_devs_mask target_rw_devs(struct bch_fs *c, | |
| enum bch_data_type data_type, | |
| u16 target) | |
| { | |
| struct bch_devs_mask devs = c->rw_devs[data_type]; | |
| const struct bch_devs_mask *t = bch2_target_to_mask(c, target); | |
| if (t) | |
| bitmap_and(devs.d, devs.d, t->d, BCH_SB_MEMBERS_MAX); | |
| return devs; | |
| } | |
| static inline bool bch2_target_accepts_data(struct bch_fs *c, | |
| enum bch_data_type data_type, | |
| u16 target) | |
| { | |
| struct bch_devs_mask rw_devs = target_rw_devs(c, data_type, target); | |
| return !bitmap_empty(rw_devs.d, BCH_SB_MEMBERS_MAX); | |
| } | |
| bool bch2_dev_in_target(struct bch_fs *, unsigned, unsigned); | |
| int bch2_disk_path_find(struct bch_sb_handle *, const char *); | |
| /* Exported for userspace bcachefs-tools: */ | |
| int bch2_disk_path_find_or_create(struct bch_sb_handle *, const char *); | |
| void bch2_disk_path_to_text(struct printbuf *, struct bch_fs *, unsigned); | |
| void bch2_disk_path_to_text_sb(struct printbuf *, struct bch_sb *, unsigned); | |
| void bch2_target_to_text(struct printbuf *out, struct bch_fs *, unsigned); | |
| int bch2_opt_target_parse(struct bch_fs *, const char *, u64 *, struct printbuf *); | |
| void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, struct bch_sb *, u64); | |
| #define bch2_opt_target (struct bch_opt_fn) { \ | |
| .parse = bch2_opt_target_parse, \ | |
| .to_text = bch2_opt_target_to_text, \ | |
| } | |
| int bch2_sb_disk_groups_to_cpu(struct bch_fs *); | |
| int __bch2_dev_group_set(struct bch_fs *, struct bch_dev *, const char *); | |
| int bch2_dev_group_set(struct bch_fs *, struct bch_dev *, const char *); | |
| const char *bch2_sb_validate_disk_groups(struct bch_sb *, | |
| struct bch_sb_field *); | |
| void bch2_disk_groups_to_text(struct printbuf *, struct bch_fs *); | |
| #endif /* _BCACHEFS_DISK_GROUPS_H */ |