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";
78 const char *bch2_bkey_invalid(struct bch_fs *c, enum bkey_type type,
81 return __bch2_bkey_invalid(c, type, k) ?:
82 bch2_bkey_val_invalid(c, type, k);
85 const char *bch2_bkey_in_btree_node(struct btree *b, struct bkey_s_c k)
87 if (bkey_cmp(bkey_start_pos(k.k), b->data->min_key) < 0)
88 return "key before start of btree node";
90 if (bkey_cmp(k.k->p, b->data->max_key) > 0)
91 return "key past end of btree node";
96 void bch2_bkey_debugcheck(struct bch_fs *c, struct btree *b, struct bkey_s_c k)
98 enum bkey_type type = btree_node_type(b);
99 const struct bkey_ops *ops = bch2_bkey_ops[type];
104 invalid = bch2_bkey_invalid(c, type, k) ?:
105 bch2_bkey_in_btree_node(b, k);
109 bch2_bkey_val_to_text(c, type, buf, sizeof(buf), k);
110 bch2_fs_bug(c, "invalid bkey %s: %s", buf, invalid);
114 if (k.k->type >= KEY_TYPE_GENERIC_NR &&
116 ops->key_debugcheck(c, b, k);
119 #define p(...) (out += scnprintf(out, end - out, __VA_ARGS__))
121 int bch2_bkey_to_text(char *buf, size_t size, const struct bkey *k)
123 char *out = buf, *end = buf + size;
125 p("u64s %u type %u ", k->u64s, k->type);
127 if (bkey_cmp(k->p, POS_MAX))
128 p("%llu:%llu", k->p.inode, k->p.offset);
132 p(" snap %u len %u ver %llu", k->p.snapshot, k->size, k->version.lo);
137 int bch2_val_to_text(struct bch_fs *c, enum bkey_type type,
138 char *buf, size_t size, struct bkey_s_c k)
140 const struct bkey_ops *ops = bch2_bkey_ops[type];
141 char *out = buf, *end = buf + size;
144 case KEY_TYPE_DELETED:
147 case KEY_TYPE_DISCARD:
153 case KEY_TYPE_COOKIE:
157 if (k.k->type >= KEY_TYPE_GENERIC_NR && ops->val_to_text)
158 ops->val_to_text(c, buf, size, k);
165 int bch2_bkey_val_to_text(struct bch_fs *c, enum bkey_type type,
166 char *buf, size_t size, struct bkey_s_c k)
168 char *out = buf, *end = buf + size;
170 out += bch2_bkey_to_text(out, end - out, k.k);
171 out += scnprintf(out, end - out, ": ");
172 out += bch2_val_to_text(c, type, out, end - out, k);
177 void bch2_bkey_swab(enum bkey_type type,
178 const struct bkey_format *f,
179 struct bkey_packed *k)
181 const struct bkey_ops *ops = bch2_bkey_ops[type];
183 bch2_bkey_swab_key(f, k);