// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "bcachefs_ioctl.h"
#include "btree_cache.h"
#include "btree_journal_iter.h"
#include "btree_update.h"
#include "btree_write_buffer.h"
#include "buckets.h"
#include "compress.h"
#include "disk_accounting.h"
#include "error.h"
#include "journal_io.h"
#include "replicas.h"

/*
 * Notes on disk accounting:
 *
 * We have two parallel sets of counters to be concerned with, and both must be
 * kept in sync.
 *
 *  - Persistent/on disk accounting, stored in the accounting btree and updated
 *    via btree write buffer updates that treat new accounting keys as deltas to
 *    apply to existing values. But reading from a write buffer btree is
 *    expensive, so we also have
 *
 *  - In memory accounting, where accounting is stored as an array of percpu
 *    counters, indexed by an eytzinger array of disk acounting keys/bpos (which
 *    are the same thing, excepting byte swabbing on big endian).
 *
 *    Cheap to read, but non persistent.
 *
 * Disk accounting updates are generated by transactional triggers; these run as
 * keys enter and leave the btree, and can compare old and new versions of keys;
 * the output of these triggers are deltas to the various counters.
 *
 * Disk accounting updates are done as btree write buffer updates, where the
 * counters in the disk accounting key are deltas that will be applied to the
 * counter in the btree when the key is flushed by the write buffer (or journal
 * replay).
 *
 * To do a disk accounting update:
 * - initialize a disk_accounting_pos, to specify which counter is being update
 * - initialize counter deltas, as an array of 1-3 s64s
 * - call bch2_disk_accounting_mod()
 *
 * This queues up the accounting update to be done at transaction commit time.
 * Underneath, it's a normal btree write buffer update.
 *
 * The transaction commit path is responsible for propagating updates to the in
 * memory counters, with bch2_accounting_mem_mod().
 *
 * The commit path also assigns every disk accounting update a unique version
 * number, based on the journal sequence number and offset within that journal
 * buffer; this is used by journal replay to determine which updates have been
 * done.
 *
 * The transaction commit path also ensures that replicas entry accounting
 * updates are properly marked in the superblock (so that we know whether we can
 * mount without data being unavailable); it will update the superblock if
 * bch2_accounting_mem_mod() tells it to.
 */

static const char * const disk_accounting_type_strs[] = {
#define x(t, n, ...) [n] = #t,
	BCH_DISK_ACCOUNTING_TYPES()
#undef x
	NULL
};

static inline void accounting_key_init(struct bkey_i *k, struct disk_accounting_pos *pos,
				       s64 *d, unsigned nr)
{
	struct bkey_i_accounting *acc = bkey_accounting_init(k);

	acc->k.p = disk_accounting_pos_to_bpos(pos);
	set_bkey_val_u64s(&acc->k, sizeof(struct bch_accounting) / sizeof(u64) + nr);

	memcpy_u64s_small(acc->v.d, d, nr);
}

int bch2_disk_accounting_mod(struct btree_trans *trans,
			     struct disk_accounting_pos *k,
			     s64 *d, unsigned nr, bool gc)
{
	/* Normalize: */
	switch (k->type) {
	case BCH_DISK_ACCOUNTING_replicas:
		bubble_sort(k->replicas.devs, k->replicas.nr_devs, u8_cmp);
		break;
	}

	BUG_ON(nr > BCH_ACCOUNTING_MAX_COUNTERS);

	struct { __BKEY_PADDED(k, BCH_ACCOUNTING_MAX_COUNTERS); } k_i;

	accounting_key_init(&k_i.k, k, d, nr);

	return likely(!gc)
		? bch2_trans_update_buffered(trans, BTREE_ID_accounting, &k_i.k)
		: bch2_accounting_mem_add(trans, bkey_i_to_s_c_accounting(&k_i.k), true);
}

int bch2_mod_dev_cached_sectors(struct btree_trans *trans,
				unsigned dev, s64 sectors,
				bool gc)
{
	struct disk_accounting_pos acc = {
		.type = BCH_DISK_ACCOUNTING_replicas,
	};

	bch2_replicas_entry_cached(&acc.replicas, dev);

	return bch2_disk_accounting_mod(trans, &acc, &sectors, 1, gc);
}

static inline bool is_zero(char *start, char *end)
{
	BUG_ON(start > end);

	for (; start < end; start++)
		if (*start)
			return false;
	return true;
}

#define field_end(p, member)	(((void *) (&p.member)) + sizeof(p.member))

int bch2_accounting_validate(struct bch_fs *c, struct bkey_s_c k,
			     enum bch_validate_flags flags)
{
	struct disk_accounting_pos acc_k;
	bpos_to_disk_accounting_pos(&acc_k, k.k->p);
	void *end = &acc_k + 1;
	int ret = 0;

	switch (acc_k.type) {
	case BCH_DISK_ACCOUNTING_nr_inodes:
		end = field_end(acc_k, nr_inodes);
		break;
	case BCH_DISK_ACCOUNTING_persistent_reserved:
		end = field_end(acc_k, persistent_reserved);
		break;
	case BCH_DISK_ACCOUNTING_replicas:
		bkey_fsck_err_on(!acc_k.replicas.nr_devs,
				 c, accounting_key_replicas_nr_devs_0,
				 "accounting key replicas entry with nr_devs=0");

		bkey_fsck_err_on(acc_k.replicas.nr_required > acc_k.replicas.nr_devs ||
				 (acc_k.replicas.nr_required > 1 &&
				  acc_k.replicas.nr_required == acc_k.replicas.nr_devs),
				 c, accounting_key_replicas_nr_required_bad,
				 "accounting key replicas entry with bad nr_required");

		for (unsigned i = 0; i + 1 < acc_k.replicas.nr_devs; i++)
			bkey_fsck_err_on(acc_k.replicas.devs[i] >= acc_k.replicas.devs[i + 1],
					 c, accounting_key_replicas_devs_unsorted,
					 "accounting key replicas entry with unsorted devs");

		end = (void *) &acc_k.replicas + replicas_entry_bytes(&acc_k.replicas);
		break;
	case BCH_DISK_ACCOUNTING_dev_data_type:
		end = field_end(acc_k, dev_data_type);
		break;
	case BCH_DISK_ACCOUNTING_compression:
		end = field_end(acc_k, compression);
		break;
	case BCH_DISK_ACCOUNTING_snapshot:
		end = field_end(acc_k, snapshot);
		break;
	case BCH_DISK_ACCOUNTING_btree:
		end = field_end(acc_k, btree);
		break;
	case BCH_DISK_ACCOUNTING_rebalance_work:
		end = field_end(acc_k, rebalance_work);
		break;
	}

	bkey_fsck_err_on(!is_zero(end, (void *) (&acc_k + 1)),
			 c, accounting_key_junk_at_end,
			 "junk at end of accounting key");
fsck_err:
	return ret;
}

void bch2_accounting_key_to_text(struct printbuf *out, struct disk_accounting_pos *k)
{
	if (k->type >= BCH_DISK_ACCOUNTING_TYPE_NR) {
		prt_printf(out, "unknown type %u", k->type);
		return;
	}

	prt_str(out, disk_accounting_type_strs[k->type]);
	prt_str(out, " ");

	switch (k->type) {
	case BCH_DISK_ACCOUNTING_nr_inodes:
		break;
	case BCH_DISK_ACCOUNTING_persistent_reserved:
		prt_printf(out, "replicas=%u", k->persistent_reserved.nr_replicas);
		break;
	case BCH_DISK_ACCOUNTING_replicas:
		bch2_replicas_entry_to_text(out, &k->replicas);
		break;
	case BCH_DISK_ACCOUNTING_dev_data_type:
		prt_printf(out, "dev=%u data_type=", k->dev_data_type.dev);
		bch2_prt_data_type(out, k->dev_data_type.data_type);
		break;
	case BCH_DISK_ACCOUNTING_compression:
		bch2_prt_compression_type(out, k->compression.type);
		break;
	case BCH_DISK_ACCOUNTING_snapshot:
		prt_printf(out, "id=%u", k->snapshot.id);
		break;
	case BCH_DISK_ACCOUNTING_btree:
		prt_printf(out, "btree=%s", bch2_btree_id_str(k->btree.id));
		break;
	}
}

void bch2_accounting_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
{
	struct bkey_s_c_accounting acc = bkey_s_c_to_accounting(k);
	struct disk_accounting_pos acc_k;
	bpos_to_disk_accounting_pos(&acc_k, k.k->p);

	bch2_accounting_key_to_text(out, &acc_k);

	for (unsigned i = 0; i < bch2_accounting_counters(k.k); i++)
		prt_printf(out, " %lli", acc.v->d[i]);
}

void bch2_accounting_swab(struct bkey_s k)
{
	for (u64 *p = (u64 *) k.v;
	     p < (u64 *) bkey_val_end(k);
	     p++)
		*p = swab64(*p);
}

static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p)
{
	struct disk_accounting_pos acc_k;
	bpos_to_disk_accounting_pos(&acc_k, p);

	switch (acc_k.type) {
	case BCH_DISK_ACCOUNTING_replicas:
		unsafe_memcpy(r, &acc_k.replicas,
			      replicas_entry_bytes(&acc_k.replicas),
			      "variable length struct");
		return true;
	default:
		return false;
	}
}

static int bch2_accounting_update_sb_one(struct bch_fs *c, struct bpos p)
{
	struct bch_replicas_padded r;
	return accounting_to_replicas(&r.e, p)
		? bch2_mark_replicas(c, &r.e)
		: 0;
}

/*
 * Ensure accounting keys being updated are present in the superblock, when
 * applicable (i.e. replicas updates)
 */
int bch2_accounting_update_sb(struct btree_trans *trans)
{
	for (struct jset_entry *i = trans->journal_entries;
	     i != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
	     i = vstruct_next(i))
		if (jset_entry_is_key(i) && i->start->k.type == KEY_TYPE_accounting) {
			int ret = bch2_accounting_update_sb_one(trans->c, i->start->k.p);
			if (ret)
				return ret;
		}

	return 0;
}

static int __bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a)
{
	struct bch_accounting_mem *acc = &c->accounting;

	/* raced with another insert, already present: */
	if (eytzinger0_find(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
			    accounting_pos_cmp, &a.k->p) < acc->k.nr)
		return 0;

	struct accounting_mem_entry n = {
		.pos		= a.k->p,
		.version	= a.k->version,
		.nr_counters	= bch2_accounting_counters(a.k),
		.v[0]		= __alloc_percpu_gfp(n.nr_counters * sizeof(u64),
						     sizeof(u64), GFP_KERNEL),
	};

	if (!n.v[0])
		goto err;

	if (acc->gc_running) {
		n.v[1] = __alloc_percpu_gfp(n.nr_counters * sizeof(u64),
					    sizeof(u64), GFP_KERNEL);
		if (!n.v[1])
			goto err;
	}

	if (darray_push(&acc->k, n))
		goto err;

	eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
			accounting_pos_cmp, NULL);
	return 0;
err:
	free_percpu(n.v[1]);
	free_percpu(n.v[0]);
	return -BCH_ERR_ENOMEM_disk_accounting;
}

int bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a, bool gc)
{
	struct bch_replicas_padded r;

	if (accounting_to_replicas(&r.e, a.k->p) &&
	    !bch2_replicas_marked_locked(c, &r.e))
		return -BCH_ERR_btree_insert_need_mark_replicas;

	percpu_up_read(&c->mark_lock);
	percpu_down_write(&c->mark_lock);
	int ret = __bch2_accounting_mem_insert(c, a);
	percpu_up_write(&c->mark_lock);
	percpu_down_read(&c->mark_lock);
	return ret;
}

static bool accounting_mem_entry_is_zero(struct accounting_mem_entry *e)
{
	for (unsigned i = 0; i < e->nr_counters; i++)
		if (percpu_u64_get(e->v[0] + i) ||
		    (e->v[1] &&
		     percpu_u64_get(e->v[1] + i)))
			return false;
	return true;
}

void bch2_accounting_mem_gc(struct bch_fs *c)
{
	struct bch_accounting_mem *acc = &c->accounting;

	percpu_down_write(&c->mark_lock);
	struct accounting_mem_entry *dst = acc->k.data;

	darray_for_each(acc->k, src) {
		if (accounting_mem_entry_is_zero(src)) {
			free_percpu(src->v[0]);
			free_percpu(src->v[1]);
		} else {
			*dst++ = *src;
		}
	}

	acc->k.nr = dst - acc->k.data;
	eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
			accounting_pos_cmp, NULL);
	percpu_up_write(&c->mark_lock);
}

/*
 * Read out accounting keys for replicas entries, as an array of
 * bch_replicas_usage entries.
 *
 * Note: this may be deprecated/removed at smoe point in the future and replaced
 * with something more general, it exists to support the ioctl used by the
 * 'bcachefs fs usage' command.
 */
int bch2_fs_replicas_usage_read(struct bch_fs *c, darray_char *usage)
{
	struct bch_accounting_mem *acc = &c->accounting;
	int ret = 0;

	darray_init(usage);

	percpu_down_read(&c->mark_lock);
	darray_for_each(acc->k, i) {
		struct {
			struct bch_replicas_usage r;
			u8 pad[BCH_BKEY_PTRS_MAX];
		} u;

		if (!accounting_to_replicas(&u.r.r, i->pos))
			continue;

		u64 sectors;
		bch2_accounting_mem_read_counters(acc, i - acc->k.data, &sectors, 1, false);
		u.r.sectors = sectors;

		ret = darray_make_room(usage, replicas_usage_bytes(&u.r));
		if (ret)
			break;

		memcpy(&darray_top(*usage), &u.r, replicas_usage_bytes(&u.r));
		usage->nr += replicas_usage_bytes(&u.r);
	}
	percpu_up_read(&c->mark_lock);

	if (ret)
		darray_exit(usage);
	return ret;
}

int bch2_fs_accounting_read(struct bch_fs *c, darray_char *out_buf, unsigned accounting_types_mask)
{

	struct bch_accounting_mem *acc = &c->accounting;
	int ret = 0;

	darray_init(out_buf);

	percpu_down_read(&c->mark_lock);
	darray_for_each(acc->k, i) {
		struct disk_accounting_pos a_p;
		bpos_to_disk_accounting_pos(&a_p, i->pos);

		if (!(accounting_types_mask & BIT(a_p.type)))
			continue;

		ret = darray_make_room(out_buf, sizeof(struct bkey_i_accounting) +
				       sizeof(u64) * i->nr_counters);
		if (ret)
			break;

		struct bkey_i_accounting *a_out =
			bkey_accounting_init((void *) &darray_top(*out_buf));
		set_bkey_val_u64s(&a_out->k, i->nr_counters);
		a_out->k.p = i->pos;
		bch2_accounting_mem_read_counters(acc, i - acc->k.data,
						  a_out->v.d, i->nr_counters, false);

		if (!bch2_accounting_key_is_zero(accounting_i_to_s_c(a_out)))
			out_buf->nr += bkey_bytes(&a_out->k);
	}

	percpu_up_read(&c->mark_lock);

	if (ret)
		darray_exit(out_buf);
	return ret;
}

void bch2_fs_accounting_to_text(struct printbuf *out, struct bch_fs *c)
{
	struct bch_accounting_mem *acc = &c->accounting;

	percpu_down_read(&c->mark_lock);
	out->atomic++;

	eytzinger0_for_each(i, acc->k.nr) {
		struct disk_accounting_pos acc_k;
		bpos_to_disk_accounting_pos(&acc_k, acc->k.data[i].pos);

		bch2_accounting_key_to_text(out, &acc_k);

		u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
		bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false);

		prt_str(out, ":");
		for (unsigned j = 0; j < acc->k.data[i].nr_counters; j++)
			prt_printf(out, " %llu", v[j]);
		prt_newline(out);
	}

	--out->atomic;
	percpu_up_read(&c->mark_lock);
}

static void bch2_accounting_free_counters(struct bch_accounting_mem *acc, bool gc)
{
	darray_for_each(acc->k, e) {
		free_percpu(e->v[gc]);
		e->v[gc] = NULL;
	}
}

int bch2_gc_accounting_start(struct bch_fs *c)
{
	struct bch_accounting_mem *acc = &c->accounting;
	int ret = 0;

	percpu_down_write(&c->mark_lock);
	darray_for_each(acc->k, e) {
		e->v[1] = __alloc_percpu_gfp(e->nr_counters * sizeof(u64),
					     sizeof(u64), GFP_KERNEL);
		if (!e->v[1]) {
			bch2_accounting_free_counters(acc, true);
			ret = -BCH_ERR_ENOMEM_disk_accounting;
			break;
		}
	}

	acc->gc_running = !ret;
	percpu_up_write(&c->mark_lock);

	return ret;
}

int bch2_gc_accounting_done(struct bch_fs *c)
{
	struct bch_accounting_mem *acc = &c->accounting;
	struct btree_trans *trans = bch2_trans_get(c);
	struct printbuf buf = PRINTBUF;
	struct bpos pos = POS_MIN;
	int ret = 0;

	percpu_down_write(&c->mark_lock);
	while (1) {
		unsigned idx = eytzinger0_find_ge(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
						  accounting_pos_cmp, &pos);

		if (idx >= acc->k.nr)
			break;

		struct accounting_mem_entry *e = acc->k.data + idx;
		pos = bpos_successor(e->pos);

		struct disk_accounting_pos acc_k;
		bpos_to_disk_accounting_pos(&acc_k, e->pos);

		if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR)
			continue;

		u64 src_v[BCH_ACCOUNTING_MAX_COUNTERS];
		u64 dst_v[BCH_ACCOUNTING_MAX_COUNTERS];

		unsigned nr = e->nr_counters;
		bch2_accounting_mem_read_counters(acc, idx, dst_v, nr, false);
		bch2_accounting_mem_read_counters(acc, idx, src_v, nr, true);

		if (memcmp(dst_v, src_v, nr * sizeof(u64))) {
			printbuf_reset(&buf);
			prt_str(&buf, "accounting mismatch for ");
			bch2_accounting_key_to_text(&buf, &acc_k);

			prt_str(&buf, ": got");
			for (unsigned j = 0; j < nr; j++)
				prt_printf(&buf, " %llu", dst_v[j]);

			prt_str(&buf, " should be");
			for (unsigned j = 0; j < nr; j++)
				prt_printf(&buf, " %llu", src_v[j]);

			for (unsigned j = 0; j < nr; j++)
				src_v[j] -= dst_v[j];

			if (fsck_err(trans, accounting_mismatch, "%s", buf.buf)) {
				percpu_up_write(&c->mark_lock);
				ret = commit_do(trans, NULL, NULL, 0,
						bch2_disk_accounting_mod(trans, &acc_k, src_v, nr, false));
				percpu_down_write(&c->mark_lock);
				if (ret)
					goto err;

				if (!test_bit(BCH_FS_may_go_rw, &c->flags)) {
					memset(&trans->fs_usage_delta, 0, sizeof(trans->fs_usage_delta));
					struct { __BKEY_PADDED(k, BCH_ACCOUNTING_MAX_COUNTERS); } k_i;

					accounting_key_init(&k_i.k, &acc_k, src_v, nr);
					bch2_accounting_mem_mod_locked(trans, bkey_i_to_s_c_accounting(&k_i.k), false, false);

					preempt_disable();
					struct bch_fs_usage_base *dst = this_cpu_ptr(c->usage);
					struct bch_fs_usage_base *src = &trans->fs_usage_delta;
					acc_u64s((u64 *) dst, (u64 *) src, sizeof(*src) / sizeof(u64));
					preempt_enable();
				}
			}
		}
	}
err:
fsck_err:
	percpu_up_write(&c->mark_lock);
	printbuf_exit(&buf);
	bch2_trans_put(trans);
	bch_err_fn(c, ret);
	return ret;
}

static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k)
{
	struct bch_fs *c = trans->c;
	struct printbuf buf = PRINTBUF;

	if (k.k->type != KEY_TYPE_accounting)
		return 0;

	percpu_down_read(&c->mark_lock);
	int ret = bch2_accounting_mem_mod_locked(trans, bkey_s_c_to_accounting(k), false, true);
	percpu_up_read(&c->mark_lock);

	if (bch2_accounting_key_is_zero(bkey_s_c_to_accounting(k)) &&
	    ret == -BCH_ERR_btree_insert_need_mark_replicas)
		ret = 0;

	struct disk_accounting_pos acc;
	bpos_to_disk_accounting_pos(&acc, k.k->p);

	if (fsck_err_on(ret == -BCH_ERR_btree_insert_need_mark_replicas,
			trans, accounting_replicas_not_marked,
			"accounting not marked in superblock replicas\n  %s",
			(bch2_accounting_key_to_text(&buf, &acc),
			 buf.buf)))
		ret = bch2_accounting_update_sb_one(c, k.k->p);
fsck_err:
	printbuf_exit(&buf);
	return ret;
}

/*
 * At startup time, initialize the in memory accounting from the btree (and
 * journal)
 */
int bch2_accounting_read(struct bch_fs *c)
{
	struct bch_accounting_mem *acc = &c->accounting;
	struct btree_trans *trans = bch2_trans_get(c);

	int ret = for_each_btree_key(trans, iter,
				BTREE_ID_accounting, POS_MIN,
				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);
			accounting_read_key(trans, k);
		}));
	if (ret)
		goto err;

	struct journal_keys *keys = &c->journal_keys;
	struct journal_key *dst = keys->data;
	move_gap(keys, keys->nr);

	darray_for_each(*keys, i) {
		if (i->k->k.type == KEY_TYPE_accounting) {
			struct bkey_s_c k = bkey_i_to_s_c(i->k);
			unsigned idx = eytzinger0_find(acc->k.data, acc->k.nr,
						sizeof(acc->k.data[0]),
						accounting_pos_cmp, &k.k->p);

			bool applied = idx < acc->k.nr &&
				bversion_cmp(acc->k.data[idx].version, k.k->version) >= 0;

			if (applied)
				continue;

			if (i + 1 < &darray_top(*keys) &&
			    i[1].k->k.type == KEY_TYPE_accounting &&
			    !journal_key_cmp(i, i + 1)) {
				BUG_ON(bversion_cmp(i[0].k->k.version, i[1].k->k.version) >= 0);

				i[1].journal_seq = i[0].journal_seq;

				bch2_accounting_accumulate(bkey_i_to_accounting(i[1].k),
							   bkey_s_c_to_accounting(k));
				continue;
			}

			ret = accounting_read_key(trans, k);
			if (ret)
				goto err;
		}

		*dst++ = *i;
	}
	keys->gap = keys->nr = dst - keys->data;

	percpu_down_read(&c->mark_lock);
	preempt_disable();
	struct bch_fs_usage_base *usage = this_cpu_ptr(c->usage);

	for (unsigned i = 0; i < acc->k.nr; i++) {
		struct disk_accounting_pos k;
		bpos_to_disk_accounting_pos(&k, acc->k.data[i].pos);

		u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
		bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false);

		switch (k.type) {
		case BCH_DISK_ACCOUNTING_persistent_reserved:
			usage->reserved += v[0] * k.persistent_reserved.nr_replicas;
			break;
		case BCH_DISK_ACCOUNTING_replicas:
			fs_usage_data_type_to_base(usage, k.replicas.data_type, v[0]);
			break;
		case BCH_DISK_ACCOUNTING_dev_data_type:
			rcu_read_lock();
			struct bch_dev *ca = bch2_dev_rcu(c, k.dev_data_type.dev);
			if (ca) {
				struct bch_dev_usage_type __percpu *d = &ca->usage->d[k.dev_data_type.data_type];
				percpu_u64_set(&d->buckets,	v[0]);
				percpu_u64_set(&d->sectors,	v[1]);
				percpu_u64_set(&d->fragmented,	v[2]);

				if (k.dev_data_type.data_type == BCH_DATA_sb ||
				    k.dev_data_type.data_type == BCH_DATA_journal)
					usage->hidden += v[0] * ca->mi.bucket_size;
			}
			rcu_read_unlock();
			break;
		}
	}
	preempt_enable();
	percpu_up_read(&c->mark_lock);
err:
	bch2_trans_put(trans);
	bch_err_fn(c, ret);
	return ret;
}

int bch2_dev_usage_remove(struct bch_fs *c, unsigned dev)
{
	return bch2_trans_run(c,
		bch2_btree_write_buffer_flush_sync(trans) ?:
		for_each_btree_key_commit(trans, iter, BTREE_ID_accounting, POS_MIN,
				BTREE_ITER_all_snapshots, k, NULL, NULL, 0, ({
			struct disk_accounting_pos acc;
			bpos_to_disk_accounting_pos(&acc, k.k->p);

			acc.type == BCH_DISK_ACCOUNTING_dev_data_type &&
			acc.dev_data_type.dev == dev
				? bch2_btree_bit_mod_buffered(trans, BTREE_ID_accounting, k.k->p, 0)
				: 0;
		})) ?:
		bch2_btree_write_buffer_flush_sync(trans));
}

int bch2_dev_usage_init(struct bch_dev *ca, bool gc)
{
	struct bch_fs *c = ca->fs;
	struct disk_accounting_pos acc = {
		.type = BCH_DISK_ACCOUNTING_dev_data_type,
		.dev_data_type.dev = ca->dev_idx,
		.dev_data_type.data_type = BCH_DATA_free,
	};
	u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 };

	int ret = bch2_trans_do(c, NULL, NULL, 0,
			bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc));
	bch_err_fn(c, ret);
	return ret;
}

void bch2_verify_accounting_clean(struct bch_fs *c)
{
	bool mismatch = false;
	struct bch_fs_usage_base base = {}, base_inmem = {};

	bch2_trans_run(c,
		for_each_btree_key(trans, iter,
				   BTREE_ID_accounting, POS_MIN,
				   BTREE_ITER_all_snapshots, k, ({
			u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
			struct bkey_s_c_accounting a = bkey_s_c_to_accounting(k);
			unsigned nr = bch2_accounting_counters(k.k);

			struct disk_accounting_pos acc_k;
			bpos_to_disk_accounting_pos(&acc_k, k.k->p);

			if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR)
				continue;

			if (acc_k.type == BCH_DISK_ACCOUNTING_inum)
				continue;

			bch2_accounting_mem_read(c, k.k->p, v, nr);

			if (memcmp(a.v->d, v, nr * sizeof(u64))) {
				struct printbuf buf = PRINTBUF;

				bch2_bkey_val_to_text(&buf, c, k);
				prt_str(&buf, " !=");
				for (unsigned j = 0; j < nr; j++)
					prt_printf(&buf, " %llu", v[j]);

				pr_err("%s", buf.buf);
				printbuf_exit(&buf);
				mismatch = true;
			}

			switch (acc_k.type) {
			case BCH_DISK_ACCOUNTING_persistent_reserved:
				base.reserved += acc_k.persistent_reserved.nr_replicas * a.v->d[0];
				break;
			case BCH_DISK_ACCOUNTING_replicas:
				fs_usage_data_type_to_base(&base, acc_k.replicas.data_type, a.v->d[0]);
				break;
			case BCH_DISK_ACCOUNTING_dev_data_type: {
				rcu_read_lock();
				struct bch_dev *ca = bch2_dev_rcu(c, acc_k.dev_data_type.dev);
				if (!ca) {
					rcu_read_unlock();
					continue;
				}

				v[0] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].buckets);
				v[1] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].sectors);
				v[2] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].fragmented);
				rcu_read_unlock();

				if (memcmp(a.v->d, v, 3 * sizeof(u64))) {
					struct printbuf buf = PRINTBUF;

					bch2_bkey_val_to_text(&buf, c, k);
					prt_str(&buf, " in mem");
					for (unsigned j = 0; j < nr; j++)
						prt_printf(&buf, " %llu", v[j]);

					pr_err("dev accounting mismatch: %s", buf.buf);
					printbuf_exit(&buf);
					mismatch = true;
				}
			}
			}

			0;
		})));

	acc_u64s_percpu(&base_inmem.hidden, &c->usage->hidden, sizeof(base_inmem) / sizeof(u64));

#define check(x)										\
	if (base.x != base_inmem.x) {								\
		pr_err("fs_usage_base.%s mismatch: %llu != %llu", #x, base.x, base_inmem.x);	\
		mismatch = true;								\
	}

	//check(hidden);
	check(btree);
	check(data);
	check(cached);
	check(reserved);
	check(nr_inodes);

	WARN_ON(mismatch);
}

void bch2_accounting_gc_free(struct bch_fs *c)
{
	lockdep_assert_held(&c->mark_lock);

	struct bch_accounting_mem *acc = &c->accounting;

	bch2_accounting_free_counters(acc, true);
	acc->gc_running = false;
}

void bch2_fs_accounting_exit(struct bch_fs *c)
{
	struct bch_accounting_mem *acc = &c->accounting;

	bch2_accounting_free_counters(acc, false);
	darray_exit(&acc->k);
}
