Commit | Line | Data |
---|---|---|
1c6fdbd8 KO |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _BCACHEFS_SUPER_IO_H | |
3 | #define _BCACHEFS_SUPER_IO_H | |
4 | ||
5 | #include "extents.h" | |
6 | #include "eytzinger.h" | |
7 | #include "super_types.h" | |
8 | #include "super.h" | |
9 | ||
10 | #include <asm/byteorder.h> | |
11 | ||
12 | struct bch_sb_field *bch2_sb_field_get(struct bch_sb *, enum bch_sb_field_type); | |
13 | struct bch_sb_field *bch2_sb_field_resize(struct bch_sb_handle *, | |
14 | enum bch_sb_field_type, unsigned); | |
af9d3bc2 | 15 | void bch2_sb_field_delete(struct bch_sb_handle *, enum bch_sb_field_type); |
1c6fdbd8 KO |
16 | |
17 | #define field_to_type(_f, _name) \ | |
18 | container_of_or_null(_f, struct bch_sb_field_##_name, field) | |
19 | ||
20 | #define x(_name, _nr) \ | |
21 | static inline struct bch_sb_field_##_name * \ | |
22 | bch2_sb_get_##_name(struct bch_sb *sb) \ | |
23 | { \ | |
24 | return field_to_type(bch2_sb_field_get(sb, \ | |
25 | BCH_SB_FIELD_##_name), _name); \ | |
26 | } \ | |
27 | \ | |
28 | static inline struct bch_sb_field_##_name * \ | |
29 | bch2_sb_resize_##_name(struct bch_sb_handle *sb, unsigned u64s) \ | |
30 | { \ | |
31 | return field_to_type(bch2_sb_field_resize(sb, \ | |
32 | BCH_SB_FIELD_##_name, u64s), _name); \ | |
33 | } | |
34 | ||
35 | BCH_SB_FIELDS() | |
36 | #undef x | |
37 | ||
38 | extern const char * const bch2_sb_fields[]; | |
39 | ||
40 | struct bch_sb_field_ops { | |
41 | const char * (*validate)(struct bch_sb *, struct bch_sb_field *); | |
319f9ac3 | 42 | void (*to_text)(struct printbuf *, struct bch_sb *, |
1c6fdbd8 KO |
43 | struct bch_sb_field *); |
44 | }; | |
45 | ||
46 | static inline bool bch2_sb_test_feature(struct bch_sb *sb, | |
47 | enum bch_sb_features f) | |
48 | { | |
49 | unsigned w = f / 64; | |
50 | unsigned b = f % 64; | |
51 | ||
52 | return le64_to_cpu(sb->features[w]) & (1ULL << b); | |
53 | } | |
54 | ||
55 | static inline void bch2_sb_set_feature(struct bch_sb *sb, | |
56 | enum bch_sb_features f) | |
57 | { | |
58 | if (!bch2_sb_test_feature(sb, f)) { | |
59 | unsigned w = f / 64; | |
60 | unsigned b = f % 64; | |
61 | ||
62 | le64_add_cpu(&sb->features[w], 1ULL << b); | |
63 | } | |
64 | } | |
65 | ||
66 | static inline __le64 bch2_sb_magic(struct bch_fs *c) | |
67 | { | |
68 | __le64 ret; | |
69 | memcpy(&ret, &c->sb.uuid, sizeof(ret)); | |
70 | return ret; | |
71 | } | |
72 | ||
73 | static inline __u64 jset_magic(struct bch_fs *c) | |
74 | { | |
75 | return __le64_to_cpu(bch2_sb_magic(c) ^ JSET_MAGIC); | |
76 | } | |
77 | ||
78 | static inline __u64 bset_magic(struct bch_fs *c) | |
79 | { | |
80 | return __le64_to_cpu(bch2_sb_magic(c) ^ BSET_MAGIC); | |
81 | } | |
82 | ||
83 | int bch2_sb_to_fs(struct bch_fs *, struct bch_sb *); | |
84 | int bch2_sb_from_fs(struct bch_fs *, struct bch_dev *); | |
85 | ||
86 | void bch2_free_super(struct bch_sb_handle *); | |
87 | int bch2_sb_realloc(struct bch_sb_handle *, unsigned); | |
88 | ||
89 | const char *bch2_sb_validate(struct bch_sb_handle *); | |
90 | ||
91 | int bch2_read_super(const char *, struct bch_opts *, struct bch_sb_handle *); | |
92 | void bch2_write_super(struct bch_fs *); | |
93 | ||
94 | /* BCH_SB_FIELD_journal: */ | |
95 | ||
96 | static inline unsigned bch2_nr_journal_buckets(struct bch_sb_field_journal *j) | |
97 | { | |
98 | return j | |
99 | ? (__le64 *) vstruct_end(&j->field) - j->buckets | |
100 | : 0; | |
101 | } | |
102 | ||
103 | /* BCH_SB_FIELD_members: */ | |
104 | ||
105 | static inline bool bch2_member_exists(struct bch_member *m) | |
106 | { | |
107 | return !bch2_is_zero(&m->uuid, sizeof(m->uuid)); | |
108 | } | |
109 | ||
110 | static inline bool bch2_dev_exists(struct bch_sb *sb, | |
111 | struct bch_sb_field_members *mi, | |
112 | unsigned dev) | |
113 | { | |
114 | return dev < sb->nr_devices && | |
115 | bch2_member_exists(&mi->members[dev]); | |
116 | } | |
117 | ||
118 | static inline struct bch_member_cpu bch2_mi_to_cpu(struct bch_member *mi) | |
119 | { | |
120 | return (struct bch_member_cpu) { | |
121 | .nbuckets = le64_to_cpu(mi->nbuckets), | |
122 | .first_bucket = le16_to_cpu(mi->first_bucket), | |
123 | .bucket_size = le16_to_cpu(mi->bucket_size), | |
124 | .group = BCH_MEMBER_GROUP(mi), | |
125 | .state = BCH_MEMBER_STATE(mi), | |
126 | .replacement = BCH_MEMBER_REPLACEMENT(mi), | |
127 | .discard = BCH_MEMBER_DISCARD(mi), | |
128 | .data_allowed = BCH_MEMBER_DATA_ALLOWED(mi), | |
129 | .durability = BCH_MEMBER_DURABILITY(mi) | |
130 | ? BCH_MEMBER_DURABILITY(mi) - 1 | |
131 | : 1, | |
132 | .valid = bch2_member_exists(mi), | |
133 | }; | |
134 | } | |
135 | ||
136 | /* BCH_SB_FIELD_clean: */ | |
137 | ||
3ccc5c50 KO |
138 | struct jset_entry * |
139 | bch2_journal_super_entries_add_common(struct bch_fs *, | |
140 | struct jset_entry *, u64); | |
141 | ||
26609b61 KO |
142 | void bch2_sb_clean_renumber(struct bch_sb_field_clean *, int); |
143 | ||
134915f3 KO |
144 | int bch2_fs_mark_dirty(struct bch_fs *); |
145 | void bch2_fs_mark_clean(struct bch_fs *); | |
1c6fdbd8 | 146 | |
319f9ac3 KO |
147 | void bch2_sb_field_to_text(struct printbuf *, struct bch_sb *, |
148 | struct bch_sb_field *); | |
1c6fdbd8 KO |
149 | |
150 | #endif /* _BCACHEFS_SUPER_IO_H */ |