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" | |
1241df58 | 9 | #include "sb-members.h" |
1c6fdbd8 KO |
10 | |
11 | #include <asm/byteorder.h> | |
12 | ||
a02a0121 KO |
13 | static inline bool bch2_version_compatible(u16 version) |
14 | { | |
ba8eeae8 | 15 | return BCH_VERSION_MAJOR(version) <= BCH_VERSION_MAJOR(bcachefs_metadata_version_current) && |
a02a0121 KO |
16 | version >= bcachefs_metadata_version_min; |
17 | } | |
18 | ||
e3804b55 | 19 | void bch2_version_to_text(struct printbuf *, unsigned); |
ba8eeae8 | 20 | unsigned bch2_latest_compatible_version(unsigned); |
e3804b55 | 21 | |
065bd335 KO |
22 | u64 bch2_upgrade_recovery_passes(struct bch_fs *c, |
23 | unsigned, | |
24 | unsigned); | |
25 | ||
1c6fdbd8 KO |
26 | struct bch_sb_field *bch2_sb_field_get(struct bch_sb *, enum bch_sb_field_type); |
27 | struct bch_sb_field *bch2_sb_field_resize(struct bch_sb_handle *, | |
28 | enum bch_sb_field_type, unsigned); | |
af9d3bc2 | 29 | void bch2_sb_field_delete(struct bch_sb_handle *, enum bch_sb_field_type); |
1c6fdbd8 KO |
30 | |
31 | #define field_to_type(_f, _name) \ | |
32 | container_of_or_null(_f, struct bch_sb_field_##_name, field) | |
33 | ||
34 | #define x(_name, _nr) \ | |
35 | static inline struct bch_sb_field_##_name * \ | |
36 | bch2_sb_get_##_name(struct bch_sb *sb) \ | |
37 | { \ | |
38 | return field_to_type(bch2_sb_field_get(sb, \ | |
39 | BCH_SB_FIELD_##_name), _name); \ | |
40 | } \ | |
41 | \ | |
42 | static inline struct bch_sb_field_##_name * \ | |
43 | bch2_sb_resize_##_name(struct bch_sb_handle *sb, unsigned u64s) \ | |
44 | { \ | |
45 | return field_to_type(bch2_sb_field_resize(sb, \ | |
46 | BCH_SB_FIELD_##_name, u64s), _name); \ | |
47 | } | |
48 | ||
49 | BCH_SB_FIELDS() | |
50 | #undef x | |
51 | ||
52 | extern const char * const bch2_sb_fields[]; | |
53 | ||
54 | struct bch_sb_field_ops { | |
efe68e1d KO |
55 | int (*validate)(struct bch_sb *, struct bch_sb_field *, struct printbuf *); |
56 | void (*to_text)(struct printbuf *, struct bch_sb *, struct bch_sb_field *); | |
1c6fdbd8 KO |
57 | }; |
58 | ||
1c6fdbd8 KO |
59 | static inline __le64 bch2_sb_magic(struct bch_fs *c) |
60 | { | |
61 | __le64 ret; | |
1e81f89b | 62 | |
1c6fdbd8 KO |
63 | memcpy(&ret, &c->sb.uuid, sizeof(ret)); |
64 | return ret; | |
65 | } | |
66 | ||
67 | static inline __u64 jset_magic(struct bch_fs *c) | |
68 | { | |
69 | return __le64_to_cpu(bch2_sb_magic(c) ^ JSET_MAGIC); | |
70 | } | |
71 | ||
72 | static inline __u64 bset_magic(struct bch_fs *c) | |
73 | { | |
74 | return __le64_to_cpu(bch2_sb_magic(c) ^ BSET_MAGIC); | |
75 | } | |
76 | ||
77 | int bch2_sb_to_fs(struct bch_fs *, struct bch_sb *); | |
78 | int bch2_sb_from_fs(struct bch_fs *, struct bch_dev *); | |
79 | ||
80 | void bch2_free_super(struct bch_sb_handle *); | |
81 | int bch2_sb_realloc(struct bch_sb_handle *, unsigned); | |
82 | ||
1c6fdbd8 | 83 | int bch2_read_super(const char *, struct bch_opts *, struct bch_sb_handle *); |
03e183cb | 84 | int bch2_write_super(struct bch_fs *); |
ba239c95 KO |
85 | void __bch2_check_set_feature(struct bch_fs *, unsigned); |
86 | ||
87 | static inline void bch2_check_set_feature(struct bch_fs *c, unsigned feat) | |
88 | { | |
89 | if (!(c->sb.features & (1ULL << feat))) | |
90 | __bch2_check_set_feature(c, feat); | |
91 | } | |
1c6fdbd8 | 92 | |
1c6fdbd8 KO |
93 | /* BCH_SB_FIELD_members: */ |
94 | ||
95 | static inline bool bch2_member_exists(struct bch_member *m) | |
96 | { | |
97 | return !bch2_is_zero(&m->uuid, sizeof(m->uuid)); | |
98 | } | |
99 | ||
100 | static inline bool bch2_dev_exists(struct bch_sb *sb, | |
1c6fdbd8 KO |
101 | unsigned dev) |
102 | { | |
1241df58 HS |
103 | if (dev < sb->nr_devices) { |
104 | struct bch_member m = bch2_sb_member_get(sb, dev); | |
105 | return bch2_member_exists(&m); | |
106 | } | |
107 | return false; | |
1c6fdbd8 KO |
108 | } |
109 | ||
110 | static inline struct bch_member_cpu bch2_mi_to_cpu(struct bch_member *mi) | |
111 | { | |
112 | return (struct bch_member_cpu) { | |
113 | .nbuckets = le64_to_cpu(mi->nbuckets), | |
114 | .first_bucket = le16_to_cpu(mi->first_bucket), | |
115 | .bucket_size = le16_to_cpu(mi->bucket_size), | |
116 | .group = BCH_MEMBER_GROUP(mi), | |
117 | .state = BCH_MEMBER_STATE(mi), | |
1c6fdbd8 KO |
118 | .discard = BCH_MEMBER_DISCARD(mi), |
119 | .data_allowed = BCH_MEMBER_DATA_ALLOWED(mi), | |
120 | .durability = BCH_MEMBER_DURABILITY(mi) | |
121 | ? BCH_MEMBER_DURABILITY(mi) - 1 | |
122 | : 1, | |
c6b2826c | 123 | .freespace_initialized = BCH_MEMBER_FREESPACE_INITIALIZED(mi), |
1c6fdbd8 KO |
124 | .valid = bch2_member_exists(mi), |
125 | }; | |
126 | } | |
127 | ||
6619d846 KO |
128 | void bch2_sb_maybe_downgrade(struct bch_fs *); |
129 | void bch2_sb_upgrade(struct bch_fs *, unsigned); | |
130 | ||
319f9ac3 KO |
131 | void bch2_sb_field_to_text(struct printbuf *, struct bch_sb *, |
132 | struct bch_sb_field *); | |
12bf93a4 KO |
133 | void bch2_sb_layout_to_text(struct printbuf *, struct bch_sb_layout *); |
134 | void bch2_sb_to_text(struct printbuf *, struct bch_sb *, bool, unsigned); | |
1c6fdbd8 KO |
135 | |
136 | #endif /* _BCACHEFS_SUPER_IO_H */ |