bch2_val_to_text(out, c, k);
 }
 
-void bch2_bkey_swab(const struct bkey_format *f,
-                   struct bkey_packed *k)
+void bch2_bkey_swab_val(struct bkey_s k)
 {
-       const struct bkey_ops *ops = &bch2_bkey_ops[k->type];
-
-       bch2_bkey_swab_key(f, k);
+       const struct bkey_ops *ops = &bch2_bkey_ops[k.k->type];
 
        if (ops->swab)
-               ops->swab(f, k);
+               ops->swab(k);
 }
 
 bool bch2_bkey_normalize(struct bch_fs *c, struct bkey_s k)
 
        void            (*key_debugcheck)(struct bch_fs *, struct bkey_s_c);
        void            (*val_to_text)(struct printbuf *, struct bch_fs *,
                                       struct bkey_s_c);
-       void            (*swab)(const struct bkey_format *, struct bkey_packed *);
+       void            (*swab)(struct bkey_s);
        bool            (*key_normalize)(struct bch_fs *, struct bkey_s);
        enum merge_result (*key_merge)(struct bch_fs *,
                                       struct bkey_s, struct bkey_s);
 void bch2_bkey_val_to_text(struct printbuf *, struct bch_fs *,
                           struct bkey_s_c);
 
-void bch2_bkey_swab(const struct bkey_format *, struct bkey_packed *);
+void bch2_bkey_swab_val(struct bkey_s);
 
 bool bch2_bkey_normalize(struct bch_fs *, struct bkey_s);
 
 
 
        for (k = i->start;
             k != vstruct_last(i);) {
-               struct bkey_s_c u;
+               struct bkey_s u;
                struct bkey tmp;
                const char *invalid;
 
                }
 
                if (BSET_BIG_ENDIAN(i) != CPU_BIG_ENDIAN)
-                       bch2_bkey_swab(&b->format, k);
+                       bch2_bkey_swab_key(&b->format, k);
 
                if (!write &&
                    version < bcachefs_metadata_version_bkey_renumber)
                        bch2_bkey_renumber(btree_node_type(b), k, write);
 
-               u = bkey_disassemble(b, k, &tmp);
+               u = __bkey_disassemble(b, k, &tmp);
 
-               invalid = __bch2_bkey_invalid(c, u, btree_node_type(b)) ?:
-                       bch2_bkey_in_btree_node(b, u) ?:
-                       (write ? bch2_bkey_val_invalid(c, u) : NULL);
+               if (BSET_BIG_ENDIAN(i) != CPU_BIG_ENDIAN)
+                       bch2_bkey_swab_val(u);
+
+               invalid = __bch2_bkey_invalid(c, u.s_c, btree_node_type(b)) ?:
+                       bch2_bkey_in_btree_node(b, u.s_c) ?:
+                       (write ? bch2_bkey_val_invalid(c, u.s_c) : NULL);
                if (invalid) {
                        char buf[160];
 
-                       bch2_bkey_val_to_text(&PBUF(buf), c, u);
+                       bch2_bkey_val_to_text(&PBUF(buf), c, u.s_c);
                        btree_err(BTREE_ERR_FIXABLE, c, b, i,
                                  "invalid bkey:\n%s\n%s", invalid, buf);
 
 
 #define bch2_bkey_ops_stripe (struct bkey_ops) {       \
        .key_invalid    = bch2_stripe_invalid,          \
        .val_to_text    = bch2_stripe_to_text,          \
+       .swab           = bch2_ptr_swab,                \
 }
 
 static inline unsigned stripe_csums_per_device(const struct bch_stripe *s)
 
        return NULL;
 }
 
-void bch2_ptr_swab(const struct bkey_format *f, struct bkey_packed *k)
+void bch2_ptr_swab(struct bkey_s k)
 {
+       struct bkey_ptrs ptrs = bch2_bkey_ptrs(k);
        union bch_extent_entry *entry;
-       u64 *d = (u64 *) bkeyp_val(f, k);
-       unsigned i;
+       u64 *d;
 
-       for (i = 0; i < bkeyp_val_u64s(f, k); i++)
-               d[i] = swab64(d[i]);
+       for (d =  (u64 *) ptrs.start;
+            d != (u64 *) ptrs.end;
+            d++)
+               *d = swab64(*d);
 
-       for (entry = (union bch_extent_entry *) d;
-            entry < (union bch_extent_entry *) (d + bkeyp_val_u64s(f, k));
+       for (entry = ptrs.start;
+            entry < ptrs.end;
             entry = extent_entry_next(entry)) {
                switch (extent_entry_type(entry)) {
                case BCH_EXTENT_ENTRY_ptr:
 
                            struct bkey_s_c);
 const char *bch2_bkey_ptrs_invalid(const struct bch_fs *, struct bkey_s_c);
 
-void bch2_ptr_swab(const struct bkey_format *, struct bkey_packed *);
+void bch2_ptr_swab(struct bkey_s);
 
 /* Generic extent code: */
 
 
                return 0;
        }
 
-       if (JSET_BIG_ENDIAN(jset) != CPU_BIG_ENDIAN)
-               bch2_bkey_swab(NULL, bkey_to_packed(k));
+       if (JSET_BIG_ENDIAN(jset) != CPU_BIG_ENDIAN) {
+               bch2_bkey_swab_key(NULL, bkey_to_packed(k));
+               bch2_bkey_swab_val(bkey_i_to_s(k));
+       }
 
        if (!write &&
            version < bcachefs_metadata_version_bkey_renumber)
 
 #define bch2_bkey_ops_reflink_v (struct bkey_ops) {            \
        .key_invalid    = bch2_reflink_v_invalid,               \
        .val_to_text    = bch2_reflink_v_to_text,               \
+       .swab           = bch2_ptr_swab,                        \
 }
 
 s64 bch2_remap_range(struct bch_fs *, struct bpos, struct bpos,