]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/bkey.c
Update bcachefs sources to 14ce2a2031 bcachefs: fixes for building in userspace
[bcachefs-tools-debian] / libbcachefs / bkey.c
index b9ceb6ead6aaf7cd6b06fee09d19ce56f28444aa..970150848cee4ed643aa76d1279cf0bd6b6c7f72 100644 (file)
@@ -1,9 +1,18 @@
 
 #include "bcachefs.h"
 #include "bkey.h"
+#include "bkey_methods.h"
 #include "bset.h"
 #include "util.h"
 
+#undef EBUG_ON
+
+#ifdef DEBUG_BKEYS
+#define EBUG_ON(cond)          BUG_ON(cond)
+#else
+#define EBUG_ON(cond)
+#endif
+
 const struct bkey_format bch2_bkey_format_current = BKEY_FORMAT_CURRENT;
 
 struct bkey __bch2_bkey_unpack_key(const struct bkey_format *,
@@ -72,37 +81,6 @@ static inline void bch2_bkey_pack_verify(const struct bkey_packed *packed,
                                        const struct bkey_format *format) {}
 #endif
 
-int bch2_bkey_to_text(char *buf, size_t size, const struct bkey *k)
-{
-       char *out = buf, *end = buf + size;
-
-#define p(...) (out += scnprintf(out, end - out, __VA_ARGS__))
-
-       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.lo);
-
-       BUG_ON(bkey_packed(k));
-
-       switch (k->type) {
-       case KEY_TYPE_DELETED:
-               p(" deleted");
-               break;
-       case KEY_TYPE_DISCARD:
-               p(" discard");
-               break;
-       case KEY_TYPE_ERROR:
-               p(" error");
-               break;
-       case KEY_TYPE_COOKIE:
-               p(" cookie");
-               break;
-       }
-#undef p
-
-       return out - buf;
-}
-
 struct pack_state {
        const struct bkey_format *format;
        unsigned                bits;   /* bits remaining in current word */
@@ -287,7 +265,7 @@ struct bkey __bch2_bkey_unpack_key(const struct bkey_format *format,
        return out;
 }
 
-#ifndef HAVE_BCACHE_COMPILED_UNPACK
+#ifndef HAVE_BCACHEFS_COMPILED_UNPACK
 struct bpos __bkey_unpack_pos(const struct bkey_format *format,
                                     const struct bkey_packed *in)
 {
@@ -328,7 +306,8 @@ bool bch2_bkey_pack_key(struct bkey_packed *out, const struct bkey *in,
         * Extents - we have to guarantee that if an extent is packed, a trimmed
         * version will also pack:
         */
-       if (bkey_start_offset(in) < format->field_offset[BKEY_FIELD_OFFSET])
+       if (bkey_start_offset(in) <
+           le64_to_cpu(format->field_offset[BKEY_FIELD_OFFSET]))
                return false;
 
        pack_state_finish(&state, out);
@@ -626,25 +605,25 @@ const char *bch2_bkey_format_validate(struct bkey_format *f)
        unsigned i, bits = KEY_PACKED_BITS_START;
 
        if (f->nr_fields != BKEY_NR_FIELDS)
-               return "invalid format: incorrect number of fields";
+               return "incorrect number of fields";
 
        for (i = 0; i < f->nr_fields; i++) {
                u64 field_offset = le64_to_cpu(f->field_offset[i]);
 
                if (f->bits_per_field[i] > 64)
-                       return "invalid format: field too large";
+                       return "field too large";
 
                if (field_offset &&
                    (f->bits_per_field[i] == 64 ||
                    (field_offset + ((1ULL << f->bits_per_field[i]) - 1) <
                     field_offset)))
-                       return "invalid format: offset + bits overflow";
+                       return "offset + bits overflow";
 
                bits += f->bits_per_field[i];
        }
 
        if (f->key_u64s != DIV_ROUND_UP(bits, 64))
-               return "invalid format: incorrect key_u64s";
+               return "incorrect key_u64s";
 
        return NULL;
 }
@@ -791,11 +770,9 @@ static u8 *compile_bkey_field(const struct bkey_format *format, u8 *out,
                              unsigned dst_offset, unsigned dst_size,
                              bool *eax_zeroed)
 {
-       unsigned byte = format->key_u64s * sizeof(u64);
        unsigned bits = format->bits_per_field[field];
-       u64 offset = format->field_offset[field];
-       unsigned i, bit_offset = 0;
-       unsigned shl, shr;
+       u64 offset = le64_to_cpu(format->field_offset[field]);
+       unsigned i, byte, bit_offset, align, shl, shr;
 
        if (!bits && !offset) {
                if (!*eax_zeroed) {
@@ -842,11 +819,12 @@ static u8 *compile_bkey_field(const struct bkey_format *format, u8 *out,
                return out;
        }
 
+       bit_offset = format->key_u64s * 64;
        for (i = 0; i <= field; i++)
-               bit_offset += format->bits_per_field[i];
+               bit_offset -= format->bits_per_field[i];
 
-       byte -= DIV_ROUND_UP(bit_offset, 8);
-       bit_offset = round_up(bit_offset, 8) - bit_offset;
+       byte = bit_offset / 8;
+       bit_offset -= byte * 8;
 
        *eax_zeroed = false;
 
@@ -857,6 +835,12 @@ static u8 *compile_bkey_field(const struct bkey_format *format, u8 *out,
                /* movzx eax, WORD PTR [rsi + imm8] */
                I4(0x0f, 0xb7, 0x46, byte);
        } else if (bit_offset + bits <= 32) {
+               align = min(4 - DIV_ROUND_UP(bit_offset + bits, 8), byte & 3);
+               byte -= align;
+               bit_offset += align * 8;
+
+               BUG_ON(bit_offset + bits > 32);
+
                /* mov eax, [rsi + imm8] */
                I3(0x8b, 0x46, byte);
 
@@ -874,6 +858,12 @@ static u8 *compile_bkey_field(const struct bkey_format *format, u8 *out,
                        out += 4;
                }
        } else if (bit_offset + bits <= 64) {
+               align = min(8 - DIV_ROUND_UP(bit_offset + bits, 8), byte & 7);
+               byte -= align;
+               bit_offset += align * 8;
+
+               BUG_ON(bit_offset + bits > 64);
+
                /* mov rax, [rsi + imm8] */
                I4(0x48, 0x8b, 0x46, byte);
 
@@ -890,6 +880,12 @@ static u8 *compile_bkey_field(const struct bkey_format *format, u8 *out,
                        I4(0x48, 0xc1, 0xe8, shr);
                }
        } else {
+               align = min(4 - DIV_ROUND_UP(bit_offset + bits, 8), byte & 3);
+               byte -= align;
+               bit_offset += align * 8;
+
+               BUG_ON(bit_offset + bits > 96);
+
                /* mov rax, [rsi + byte] */
                I4(0x48, 0x8b, 0x46, byte);