3 #include "bkey_methods.h"
4 #include "btree_types.h"
5 #include "alloc_background.h"
14 const char * const bch_bkey_types[] = {
15 #define x(name, nr) #name,
21 static const char *deleted_key_invalid(const struct bch_fs *c,
27 #define bch2_bkey_ops_deleted (struct bkey_ops) { \
28 .key_invalid = deleted_key_invalid, \
31 #define bch2_bkey_ops_discard (struct bkey_ops) { \
32 .key_invalid = deleted_key_invalid, \
35 static const char *empty_val_key_invalid(const struct bch_fs *c, struct bkey_s_c k)
37 if (bkey_val_bytes(k.k))
38 return "value size should be zero";
43 #define bch2_bkey_ops_error (struct bkey_ops) { \
44 .key_invalid = empty_val_key_invalid, \
47 static const char *key_type_cookie_invalid(const struct bch_fs *c,
50 if (bkey_val_bytes(k.k) != sizeof(struct bch_cookie))
51 return "incorrect value size";
56 #define bch2_bkey_ops_cookie (struct bkey_ops) { \
57 .key_invalid = key_type_cookie_invalid, \
60 #define bch2_bkey_ops_whiteout (struct bkey_ops) { \
61 .key_invalid = empty_val_key_invalid, \
64 static const struct bkey_ops bch2_bkey_ops[] = {
65 #define x(name, nr) [KEY_TYPE_##name] = bch2_bkey_ops_##name,
70 const char *bch2_bkey_val_invalid(struct bch_fs *c, struct bkey_s_c k)
72 if (k.k->type >= KEY_TYPE_MAX)
73 return "invalid type";
75 return bch2_bkey_ops[k.k->type].key_invalid(c, k);
78 const char *__bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
79 enum btree_node_type type)
81 if (k.k->u64s < BKEY_U64s)
82 return "u64s too small";
84 if (btree_node_type_is_extents(type)) {
85 if ((k.k->size == 0) != bkey_deleted(k.k))
86 return "bad size field";
89 return "nonzero size field";
93 return "nonzero snapshot";
95 if (type != BKEY_TYPE_BTREE &&
96 !bkey_cmp(k.k->p, POS_MAX))
102 const char *bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
103 enum btree_node_type type)
105 return __bch2_bkey_invalid(c, k, type) ?:
106 bch2_bkey_val_invalid(c, k);
109 const char *bch2_bkey_in_btree_node(struct btree *b, struct bkey_s_c k)
111 if (bkey_cmp(bkey_start_pos(k.k), b->data->min_key) < 0)
112 return "key before start of btree node";
114 if (bkey_cmp(k.k->p, b->data->max_key) > 0)
115 return "key past end of btree node";
120 void bch2_bkey_debugcheck(struct bch_fs *c, struct btree *b, struct bkey_s_c k)
122 const struct bkey_ops *ops = &bch2_bkey_ops[k.k->type];
127 invalid = bch2_bkey_invalid(c, k, btree_node_type(b)) ?:
128 bch2_bkey_in_btree_node(b, k);
132 bch2_bkey_val_to_text(&PBUF(buf), c, k);
133 bch2_fs_bug(c, "invalid bkey %s: %s", buf, invalid);
137 if (ops->key_debugcheck)
138 ops->key_debugcheck(c, b, k);
141 void bch2_bpos_to_text(struct printbuf *out, struct bpos pos)
143 if (!bkey_cmp(pos, POS_MIN))
144 pr_buf(out, "POS_MIN");
145 else if (!bkey_cmp(pos, POS_MAX))
146 pr_buf(out, "POS_MAX");
148 pr_buf(out, "%llu:%llu", pos.inode, pos.offset);
151 void bch2_bkey_to_text(struct printbuf *out, const struct bkey *k)
153 pr_buf(out, "u64s %u type %u ", k->u64s, k->type);
155 bch2_bpos_to_text(out, k->p);
157 pr_buf(out, " snap %u len %u ver %llu",
158 k->p.snapshot, k->size, k->version.lo);
161 void bch2_val_to_text(struct printbuf *out, struct bch_fs *c,
164 const struct bkey_ops *ops = &bch2_bkey_ops[k.k->type];
166 if (likely(ops->val_to_text))
167 ops->val_to_text(out, c, k);
169 pr_buf(out, " %s", bch_bkey_types[k.k->type]);
172 void bch2_bkey_val_to_text(struct printbuf *out, struct bch_fs *c,
175 bch2_bkey_to_text(out, k.k);
177 bch2_val_to_text(out, c, k);
180 void bch2_bkey_swab(const struct bkey_format *f,
181 struct bkey_packed *k)
183 const struct bkey_ops *ops = &bch2_bkey_ops[k->type];
185 bch2_bkey_swab_key(f, k);
191 bool bch2_bkey_normalize(struct bch_fs *c, struct bkey_s k)
193 const struct bkey_ops *ops = &bch2_bkey_ops[k.k->type];
195 return ops->key_normalize
196 ? ops->key_normalize(c, k)
200 enum merge_result bch2_bkey_merge(struct bch_fs *c,
201 struct bkey_i *l, struct bkey_i *r)
203 const struct bkey_ops *ops = &bch2_bkey_ops[l->k.type];
204 enum merge_result ret;
206 if (key_merging_disabled(c) ||
208 l->k.type != r->k.type ||
209 bversion_cmp(l->k.version, r->k.version) ||
210 bkey_cmp(l->k.p, bkey_start_pos(&r->k)))
211 return BCH_MERGE_NOMERGE;
213 ret = ops->key_merge(c, l, r);
215 if (ret != BCH_MERGE_NOMERGE)
216 l->k.needs_whiteout |= r->k.needs_whiteout;
220 static const struct old_bkey_type {
224 } bkey_renumber_table[] = {
225 {BKEY_TYPE_BTREE, 128, KEY_TYPE_btree_ptr },
226 {BKEY_TYPE_EXTENTS, 128, KEY_TYPE_extent },
227 {BKEY_TYPE_EXTENTS, 129, KEY_TYPE_extent },
228 {BKEY_TYPE_EXTENTS, 130, KEY_TYPE_reservation },
229 {BKEY_TYPE_INODES, 128, KEY_TYPE_inode },
230 {BKEY_TYPE_INODES, 130, KEY_TYPE_inode_generation },
231 {BKEY_TYPE_DIRENTS, 128, KEY_TYPE_dirent },
232 {BKEY_TYPE_DIRENTS, 129, KEY_TYPE_whiteout },
233 {BKEY_TYPE_XATTRS, 128, KEY_TYPE_xattr },
234 {BKEY_TYPE_XATTRS, 129, KEY_TYPE_whiteout },
235 {BKEY_TYPE_ALLOC, 128, KEY_TYPE_alloc },
236 {BKEY_TYPE_QUOTAS, 128, KEY_TYPE_quota },
239 void bch2_bkey_renumber(enum btree_node_type btree_node_type,
240 struct bkey_packed *k,
243 const struct old_bkey_type *i;
245 for (i = bkey_renumber_table;
246 i < bkey_renumber_table + ARRAY_SIZE(bkey_renumber_table);
248 if (btree_node_type == i->btree_node_type &&
249 k->type == (write ? i->new : i->old)) {
250 k->type = write ? i->old : i->new;