x(disk_accounting_inum,         BCH_VERSION(1, 11))             \
        x(rebalance_work_acct_fix,      BCH_VERSION(1, 12))             \
        x(inode_has_child_snapshots,    BCH_VERSION(1, 13))             \
-       x(backpointer_bucket_gen,       BCH_VERSION(1, 14))
+       x(backpointer_bucket_gen,       BCH_VERSION(1, 14))             \
+       x(disk_accounting_big_endian,   BCH_VERSION(1, 15))
 
 enum bcachefs_metadata_version {
        bcachefs_metadata_version_min = 9,
 
        percpu_memset(c->usage, 0, sizeof(*c->usage));
        percpu_up_write(&c->mark_lock);
 
-       int ret = for_each_btree_key(trans, iter,
-                               BTREE_ID_accounting, POS_MIN,
+       struct btree_iter iter;
+       bch2_trans_iter_init(trans, &iter, BTREE_ID_accounting, POS_MIN,
+                            BTREE_ITER_prefetch|BTREE_ITER_all_snapshots);
+       iter.flags &= ~BTREE_ITER_with_journal;
+       int ret = for_each_btree_key_continue(trans, iter,
                                BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, ({
                        struct bkey u;
                        struct bkey_s_c k = bch2_btree_path_peek_slot_exact(btree_iter_path(trans, &iter), &u);
                        struct disk_accounting_pos acc_k;
                        bpos_to_disk_accounting_pos(&acc_k, k.k->p);
 
-                       if (!bch2_accounting_is_mem(acc_k))
+                       if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR)
+                               break;
+
+                       if (!bch2_accounting_is_mem(acc_k)) {
+                               struct disk_accounting_pos next = { .type = acc_k.type + 1 };
+                               bch2_btree_iter_set_pos(&iter, disk_accounting_pos_to_bpos(&next));
                                continue;
+                       }
 
                        accounting_read_key(trans, k);
                }));
                        bpos_to_disk_accounting_pos(&acc_k, k.k->p);
 
                        if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR)
-                               continue;
+                               break;
 
-                       if (acc_k.type == BCH_DISK_ACCOUNTING_inum)
+                       if (!bch2_accounting_is_mem(acc_k)) {
+                               struct disk_accounting_pos next = { .type = acc_k.type + 1 };
+                               bch2_btree_iter_set_pos(&iter, disk_accounting_pos_to_bpos(&next));
                                continue;
+                       }
 
                        bch2_accounting_mem_read(c, k.k->p, v, nr);
 
 
 
 static inline void bpos_to_disk_accounting_pos(struct disk_accounting_pos *acc, struct bpos p)
 {
-       acc->_pad = p;
+       BUILD_BUG_ON(sizeof(*acc) != sizeof(p));
+
 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-       bch2_bpos_swab(&acc->_pad);
+       acc->_pad = p;
+#else
+       memcpy_swab(acc, &p, sizeof(p));
 #endif
 }
 
-static inline struct bpos disk_accounting_pos_to_bpos(struct disk_accounting_pos *k)
+static inline struct bpos disk_accounting_pos_to_bpos(struct disk_accounting_pos *acc)
 {
-       struct bpos ret = k->_pad;
-
+       struct bpos p;
 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-       bch2_bpos_swab(&ret);
+       p = acc->_pad;
+#else
+       memcpy_swab(&p, acc, sizeof(p));
 #endif
-       return ret;
+       return p;
 }
 
 int bch2_disk_accounting_mod(struct btree_trans *, struct disk_accounting_pos *,
 
        x(backpointer_bucket_gen,                               \
          BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers),\
          BCH_FSCK_ERR_backpointer_to_missing_ptr,              \
-         BCH_FSCK_ERR_ptr_to_missing_backpointer)
+         BCH_FSCK_ERR_ptr_to_missing_backpointer)              \
+       x(disk_accounting_big_endian,                           \
+         BIT_ULL(BCH_RECOVERY_PASS_check_allocations),         \
+         BCH_FSCK_ERR_accounting_mismatch,                     \
+         BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0,       \
+         BCH_FSCK_ERR_accounting_key_junk_at_end)
 
 #define DOWNGRADE_TABLE()                                      \
        x(bucket_stripe_sectors,                                \
          BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers),\
          BCH_FSCK_ERR_backpointer_bucket_offset_wrong,         \
          BCH_FSCK_ERR_backpointer_to_missing_ptr,              \
-         BCH_FSCK_ERR_ptr_to_missing_backpointer)
+         BCH_FSCK_ERR_ptr_to_missing_backpointer)              \
+       x(disk_accounting_big_endian,                           \
+         BIT_ULL(BCH_RECOVERY_PASS_check_allocations),         \
+         BCH_FSCK_ERR_accounting_mismatch,                     \
+         BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0,       \
+         BCH_FSCK_ERR_accounting_key_junk_at_end)
 
 struct upgrade_downgrade_entry {
        u64             recovery_passes;
 
        return (addr[bit / 64] & cpu_to_le64(BIT_ULL(bit % 64))) != 0;
 }
 
+static inline void memcpy_swab(void *_dst, void *_src, size_t len)
+{
+       u8 *dst = _dst + len;
+       u8 *src = _src;
+
+       while (len--)
+               *--dst = *src++;
+}
+
 #endif /* _BCACHEFS_UTIL_H */