summaryrefslogtreecommitdiff
path: root/libbcache/bkey.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-10-03 19:22:17 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2017-02-28 03:05:38 -0900
commita5b5eba7f788bb77cf57f9c94f3474a2d439ab0b (patch)
tree278813d1b1a9024174531376d41a2ba04a3b27f6 /libbcache/bkey.c
parente4d1c93d85a5b86c04599bfc9f658308d741fd41 (diff)
New on disk format - encryption
Diffstat (limited to 'libbcache/bkey.c')
-rw-r--r--libbcache/bkey.c172
1 files changed, 39 insertions, 133 deletions
diff --git a/libbcache/bkey.c b/libbcache/bkey.c
index 64d2c84..374237e 100644
--- a/libbcache/bkey.c
+++ b/libbcache/bkey.c
@@ -81,9 +81,9 @@ int bch_bkey_to_text(char *buf, size_t size, const struct bkey *k)
#define p(...) (out += scnprintf(out, end - out, __VA_ARGS__))
- p("u64s %u type %u %llu:%llu snap %u len %u ver %u",
+ p("u64s %u type %u %llu:%llu snap %u len %u ver %llu",
k->u64s, k->type, k->p.inode, k->p.offset,
- k->p.snapshot, k->size, k->version);
+ k->p.snapshot, k->size, k->version.lo);
BUG_ON(bkey_packed(k));
@@ -258,13 +258,21 @@ bool bch_bkey_transform(const struct bkey_format *out_f,
return true;
}
+#define bkey_fields() \
+ x(BKEY_FIELD_INODE, p.inode) \
+ x(BKEY_FIELD_OFFSET, p.offset) \
+ x(BKEY_FIELD_SNAPSHOT, p.snapshot) \
+ x(BKEY_FIELD_SIZE, size) \
+ x(BKEY_FIELD_VERSION_HI, version.hi) \
+ x(BKEY_FIELD_VERSION_LO, version.lo)
+
struct bkey __bkey_unpack_key(const struct bkey_format *format,
const struct bkey_packed *in)
{
struct unpack_state state = unpack_state_init(format, in);
struct bkey out;
- EBUG_ON(format->nr_fields != 5);
+ EBUG_ON(format->nr_fields != BKEY_NR_FIELDS);
EBUG_ON(in->u64s < format->key_u64s);
EBUG_ON(in->format != KEY_FORMAT_LOCAL_BTREE);
EBUG_ON(in->u64s - format->key_u64s + BKEY_U64s > U8_MAX);
@@ -274,11 +282,10 @@ struct bkey __bkey_unpack_key(const struct bkey_format *format,
out.needs_whiteout = in->needs_whiteout;
out.type = in->type;
out.pad[0] = 0;
- out.p.inode = get_inc_field(&state, BKEY_FIELD_INODE);
- out.p.offset = get_inc_field(&state, BKEY_FIELD_OFFSET);
- out.p.snapshot = get_inc_field(&state, BKEY_FIELD_SNAPSHOT);
- out.size = get_inc_field(&state, BKEY_FIELD_SIZE);
- out.version = get_inc_field(&state, BKEY_FIELD_VERSION);
+
+#define x(id, field) out.field = get_inc_field(&state, id);
+ bkey_fields()
+#undef x
return out;
}
@@ -290,7 +297,7 @@ struct bpos __bkey_unpack_pos(const struct bkey_format *format,
struct unpack_state state = unpack_state_init(format, in);
struct bpos out;
- EBUG_ON(format->nr_fields != 5);
+ EBUG_ON(format->nr_fields != BKEY_NR_FIELDS);
EBUG_ON(in->u64s < format->key_u64s);
EBUG_ON(in->format != KEY_FORMAT_LOCAL_BTREE);
@@ -311,17 +318,14 @@ bool bkey_pack_key(struct bkey_packed *out, const struct bkey *in,
struct pack_state state = pack_state_init(format, out);
EBUG_ON((void *) in == (void *) out);
- EBUG_ON(format->nr_fields != 5);
+ EBUG_ON(format->nr_fields != BKEY_NR_FIELDS);
EBUG_ON(in->format != KEY_FORMAT_CURRENT);
out->_data[0] = 0;
- if (!set_inc_field(&state, BKEY_FIELD_INODE, in->p.inode) ||
- !set_inc_field(&state, BKEY_FIELD_OFFSET, in->p.offset) ||
- !set_inc_field(&state, BKEY_FIELD_SNAPSHOT, in->p.snapshot) ||
- !set_inc_field(&state, BKEY_FIELD_SIZE, in->size) ||
- !set_inc_field(&state, BKEY_FIELD_VERSION, in->version))
- return false;
+#define x(id, field) if (!set_inc_field(&state, id, in->field)) return false;
+ bkey_fields()
+#undef x
/*
* Extents - we have to guarantee that if an extent is packed, a trimmed
@@ -340,47 +344,6 @@ bool bkey_pack_key(struct bkey_packed *out, const struct bkey *in,
return true;
}
-/*
- * Alternate implementations using bch_bkey_transform_key() - unfortunately, too
- * slow
- */
-#if 0
-struct bkey __bkey_unpack_key(const struct bkey_format *format,
- const struct bkey_packed *in)
-{
- struct bkey out;
- bool s;
-
- EBUG_ON(format->nr_fields != 5);
- EBUG_ON(in->u64s < format->key_u64s);
- EBUG_ON(in->format != KEY_FORMAT_LOCAL_BTREE);
-
- s = bch_bkey_transform_key(&bch_bkey_format_current, (void *) &out,
- format, in);
- EBUG_ON(!s);
-
- out.format = KEY_FORMAT_CURRENT;
-
- return out;
-}
-
-bool bkey_pack_key(struct bkey_packed *out, const struct bkey *in,
- const struct bkey_format *format)
-{
- EBUG_ON(format->nr_fields != 5);
- EBUG_ON(in->format != KEY_FORMAT_CURRENT);
-
- if (!bch_bkey_transform_key(format, out,
- &bch_bkey_format_current, (void *) in))
- return false;
-
- out->format = KEY_FORMAT_LOCAL_BTREE;
-
- bch_bkey_pack_verify(out, in, format);
- return true;
-}
-#endif
-
/**
* bkey_unpack -- unpack the key and the value
*/
@@ -588,12 +551,10 @@ static void __bkey_format_add(struct bkey_format_state *s,
*/
void bch_bkey_format_add_key(struct bkey_format_state *s, const struct bkey *k)
{
- __bkey_format_add(s, BKEY_FIELD_INODE, k->p.inode);
- __bkey_format_add(s, BKEY_FIELD_OFFSET, k->p.offset);
+#define x(id, field) __bkey_format_add(s, id, k->field);
+ bkey_fields()
+#undef x
__bkey_format_add(s, BKEY_FIELD_OFFSET, bkey_start_offset(k));
- __bkey_format_add(s, BKEY_FIELD_SNAPSHOT, k->p.snapshot);
- __bkey_format_add(s, BKEY_FIELD_SIZE, k->size);
- __bkey_format_add(s, BKEY_FIELD_VERSION, k->version);
}
void bch_bkey_format_add_pos(struct bkey_format_state *s, struct bpos p)
@@ -636,6 +597,12 @@ struct bkey_format bch_bkey_format_done(struct bkey_format_state *s)
bits += ret.bits_per_field[i];
}
+ /* allow for extent merging: */
+ if (ret.bits_per_field[BKEY_FIELD_SIZE]) {
+ ret.bits_per_field[BKEY_FIELD_SIZE] += 4;
+ bits += 4;
+ }
+
ret.key_u64s = DIV_ROUND_UP(bits, 64);
/* if we have enough spare bits, round fields up to nearest byte */
@@ -1014,25 +981,13 @@ int bch_compile_bkey_format(const struct bkey_format *format, void *_out)
/* mov [rdi], eax */
I2(0x89, 0x07);
- out = compile_bkey_field(format, out, BKEY_FIELD_INODE,
- offsetof(struct bkey, p.inode), 8,
- &eax_zeroed);
-
- out = compile_bkey_field(format, out, BKEY_FIELD_OFFSET,
- offsetof(struct bkey, p.offset), 8,
- &eax_zeroed);
-
- out = compile_bkey_field(format, out, BKEY_FIELD_SNAPSHOT,
- offsetof(struct bkey, p.snapshot), 4,
- &eax_zeroed);
-
- out = compile_bkey_field(format, out, BKEY_FIELD_SIZE,
- offsetof(struct bkey, size), 4,
- &eax_zeroed);
-
- out = compile_bkey_field(format, out, BKEY_FIELD_VERSION,
- offsetof(struct bkey, version), 4,
+#define x(id, field) \
+ out = compile_bkey_field(format, out, id, \
+ offsetof(struct bkey, field), \
+ sizeof(((struct bkey *) NULL)->field), \
&eax_zeroed);
+ bkey_fields()
+#undef x
/* retq */
I1(0xc3);
@@ -1078,43 +1033,6 @@ static inline int __bkey_cmp_bits(const u64 *l, const u64 *r,
}
#endif
-/*
- * Would like to use this if we can make __bkey_cmp_bits() fast enough, it'll be
- * a decent reduction in code size
- */
-#if 0
-static int bkey_cmp_verify(const struct bkey *l, const struct bkey *r)
-{
- if (l->p.inode != r->p.inode)
- return l->p.inode < r->p.inode ? -1 : 1;
-
- if (l->p.offset != r->p.offset)
- return l->p.offset < r->p.offset ? -1 : 1;
-
- if (l->p.snapshot != r->p.snapshot)
- return l->p.snapshot < r->p.snapshot ? -1 : 1;
-
- return 0;
-}
-
-int bkey_cmp(const struct bkey *l, const struct bkey *r)
-{
- int ret;
-
- EBUG_ON(bkey_packed(l) || bkey_packed(r));
-
- ret = __bkey_cmp_bits((sizeof(l->inode) +
- sizeof(l->offset) +
- sizeof(l->snapshot)) * BITS_PER_BYTE,
- __high_word(BKEY_U64s, l),
- __high_word(BKEY_U64s, r));
-
- BUG_ON(ret != bkey_cmp_verify(l, r));
-
- return ret;
-}
-#endif
-
__pure
int __bkey_cmp_packed_format_checked(const struct bkey_packed *l,
const struct bkey_packed *r,
@@ -1214,7 +1132,7 @@ void bkey_pack_test(void)
struct bkey_format test_format = {
.key_u64s = 2,
- .nr_fields = 5,
+ .nr_fields = BKEY_NR_FIELDS,
.bits_per_field = {
13,
64,
@@ -1230,21 +1148,9 @@ void bkey_pack_test(void)
u64 a, v = get_inc_field(&in_s, i);
switch (i) {
- case 0:
- a = t.p.inode;
- break;
- case 1:
- a = t.p.offset;
- break;
- case 2:
- a = t.p.snapshot;
- break;
- case 3:
- a = t.size;
- break;
- case 4:
- a = t.version;
- break;
+#define x(id, field) case id: a = t.field; break;
+ bkey_fields()
+#undef x
default:
BUG();
}