1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _BCACHEFS_DISK_GROUPS_H 3 #define _BCACHEFS_DISK_GROUPS_H 4 5 extern const struct bch_sb_field_ops bch_sb_field_ops_disk_groups; 6 7 static inline unsigned disk_groups_nr(struct bch_sb_field_disk_groups *groups) 8 { 9 return groups 10 ? (vstruct_end(&groups->field) - 11 (void *) &groups->entries[0]) / sizeof(struct bch_disk_group) 12 : 0; 13 } 14 15 struct target { 16 enum { 17 TARGET_NULL, 18 TARGET_DEV, 19 TARGET_GROUP, 20 } type; 21 union { 22 unsigned dev; 23 unsigned group; 24 }; 25 }; 26 27 #define TARGET_DEV_START 1 28 #define TARGET_GROUP_START (256 + TARGET_DEV_START) 29 30 static inline u16 dev_to_target(unsigned dev) 31 { 32 return TARGET_DEV_START + dev; 33 } 34 35 static inline u16 group_to_target(unsigned group) 36 { 37 return TARGET_GROUP_START + group; 38 } 39 40 static inline struct target target_decode(unsigned target) 41 { 42 if (target >= TARGET_GROUP_START) 43 return (struct target) { 44 .type = TARGET_GROUP, 45 .group = target - TARGET_GROUP_START 46 }; 47 48 if (target >= TARGET_DEV_START) 49 return (struct target) { 50 .type = TARGET_DEV, 51 .group = target - TARGET_DEV_START 52 }; 53 54 return (struct target) { .type = TARGET_NULL }; 55 } 56 57 const struct bch_devs_mask *bch2_target_to_mask(struct bch_fs *, unsigned); 58 59 static inline struct bch_devs_mask target_rw_devs(struct bch_fs *c, 60 enum bch_data_type data_type, 61 u16 target) 62 { 63 struct bch_devs_mask devs = c->rw_devs[data_type]; 64 const struct bch_devs_mask *t = bch2_target_to_mask(c, target); 65 66 if (t) 67 bitmap_and(devs.d, devs.d, t->d, BCH_SB_MEMBERS_MAX); 68 return devs; 69 } 70 71 static inline bool bch2_target_accepts_data(struct bch_fs *c, 72 enum bch_data_type data_type, 73 u16 target) 74 { 75 struct bch_devs_mask rw_devs = target_rw_devs(c, data_type, target); 76 return !bitmap_empty(rw_devs.d, BCH_SB_MEMBERS_MAX); 77 } 78 79 bool bch2_dev_in_target(struct bch_fs *, unsigned, unsigned); 80 81 int bch2_disk_path_find(struct bch_sb_handle *, const char *); 82 83 /* Exported for userspace bcachefs-tools: */ 84 int bch2_disk_path_find_or_create(struct bch_sb_handle *, const char *); 85 86 void bch2_disk_path_to_text(struct printbuf *, struct bch_sb *, unsigned); 87 88 int bch2_opt_target_parse(struct bch_fs *, const char *, u64 *, struct printbuf *); 89 void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, struct bch_sb *, u64); 90 91 #define bch2_opt_target (struct bch_opt_fn) { \ 92 .parse = bch2_opt_target_parse, \ 93 .to_text = bch2_opt_target_to_text, \ 94 } 95 96 int bch2_sb_disk_groups_to_cpu(struct bch_fs *); 97 98 int __bch2_dev_group_set(struct bch_fs *, struct bch_dev *, const char *); 99 int bch2_dev_group_set(struct bch_fs *, struct bch_dev *, const char *); 100 101 const char *bch2_sb_validate_disk_groups(struct bch_sb *, 102 struct bch_sb_field *); 103 104 void bch2_disk_groups_to_text(struct printbuf *, struct bch_fs *); 105 106 #endif /* _BCACHEFS_DISK_GROUPS_H */ 107