3 #include "bkey_methods.h"
4 #include "btree_types.h"
13 const struct bkey_ops bch2_bkey_ops[] = {
14 [BKEY_TYPE_EXTENTS] = bch2_bkey_extent_ops,
15 [BKEY_TYPE_INODES] = bch2_bkey_inode_ops,
16 [BKEY_TYPE_DIRENTS] = bch2_bkey_dirent_ops,
17 [BKEY_TYPE_XATTRS] = bch2_bkey_xattr_ops,
18 [BKEY_TYPE_ALLOC] = bch2_bkey_alloc_ops,
19 [BKEY_TYPE_QUOTAS] = bch2_bkey_quota_ops,
20 [BKEY_TYPE_BTREE] = bch2_bkey_btree_ops,
23 const char *bch2_bkey_val_invalid(struct bch_fs *c, enum bkey_type type,
26 const struct bkey_ops *ops = &bch2_bkey_ops[type];
29 case KEY_TYPE_DELETED:
30 case KEY_TYPE_DISCARD:
34 return bkey_val_bytes(k.k) != 0
35 ? "value size should be zero"
39 return bkey_val_bytes(k.k) != sizeof(struct bch_cookie)
40 ? "incorrect value size"
44 if (k.k->type < KEY_TYPE_GENERIC_NR)
45 return "invalid type";
47 return ops->key_invalid(c, k);
51 const char *__bch2_bkey_invalid(struct bch_fs *c, enum bkey_type type,
54 const struct bkey_ops *ops = &bch2_bkey_ops[type];
56 if (k.k->u64s < BKEY_U64s)
57 return "u64s too small";
59 if (!ops->is_extents) {
61 return "nonzero size field";
63 if ((k.k->size == 0) != bkey_deleted(k.k))
64 return "bad size field";
67 if (ops->is_extents &&
70 return "zero size field";
73 return "nonzero snapshot";
75 if (type != BKEY_TYPE_BTREE &&
76 !bkey_cmp(k.k->p, POS_MAX))
82 const char *bch2_bkey_invalid(struct bch_fs *c, enum bkey_type type,
85 return __bch2_bkey_invalid(c, type, k) ?:
86 bch2_bkey_val_invalid(c, type, k);
89 const char *bch2_bkey_in_btree_node(struct btree *b, struct bkey_s_c k)
91 if (bkey_cmp(bkey_start_pos(k.k), b->data->min_key) < 0)
92 return "key before start of btree node";
94 if (bkey_cmp(k.k->p, b->data->max_key) > 0)
95 return "key past end of btree node";
100 void bch2_bkey_debugcheck(struct bch_fs *c, struct btree *b, struct bkey_s_c k)
102 enum bkey_type type = btree_node_type(b);
103 const struct bkey_ops *ops = &bch2_bkey_ops[type];
108 invalid = bch2_bkey_invalid(c, type, k) ?:
109 bch2_bkey_in_btree_node(b, k);
113 bch2_bkey_val_to_text(c, type, buf, sizeof(buf), k);
114 bch2_fs_bug(c, "invalid bkey %s: %s", buf, invalid);
118 if (k.k->type >= KEY_TYPE_GENERIC_NR &&
120 ops->key_debugcheck(c, b, k);
123 #define p(...) (out += scnprintf(out, end - out, __VA_ARGS__))
125 int bch2_bkey_to_text(char *buf, size_t size, const struct bkey *k)
127 char *out = buf, *end = buf + size;
129 p("u64s %u type %u ", k->u64s, k->type);
131 if (bkey_cmp(k->p, POS_MAX))
132 p("%llu:%llu", k->p.inode, k->p.offset);
136 p(" snap %u len %u ver %llu", k->p.snapshot, k->size, k->version.lo);
141 int bch2_val_to_text(struct bch_fs *c, enum bkey_type type,
142 char *buf, size_t size, struct bkey_s_c k)
144 const struct bkey_ops *ops = &bch2_bkey_ops[type];
145 char *out = buf, *end = buf + size;
148 case KEY_TYPE_DELETED:
151 case KEY_TYPE_DISCARD:
157 case KEY_TYPE_COOKIE:
161 if (k.k->type >= KEY_TYPE_GENERIC_NR && ops->val_to_text)
162 ops->val_to_text(c, buf, size, k);
169 int bch2_bkey_val_to_text(struct bch_fs *c, enum bkey_type type,
170 char *buf, size_t size, struct bkey_s_c k)
172 char *out = buf, *end = buf + size;
174 out += bch2_bkey_to_text(out, end - out, k.k);
175 out += scnprintf(out, end - out, ": ");
176 out += bch2_val_to_text(c, type, out, end - out, k);
181 void bch2_bkey_swab(enum bkey_type type,
182 const struct bkey_format *f,
183 struct bkey_packed *k)
185 const struct bkey_ops *ops = &bch2_bkey_ops[type];
187 bch2_bkey_swab_key(f, k);