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