// SPDX-License-Identifier: GPL-2.0
/*
 * Code for manipulating bucket marks for garbage collection.
 *
 * Copyright 2014 Datera, Inc.
 */

#include "bcachefs.h"
#include "alloc_background.h"
#include "backpointers.h"
#include "bset.h"
#include "btree_gc.h"
#include "btree_update.h"
#include "buckets.h"
#include "buckets_waiting_for_journal.h"
#include "disk_accounting.h"
#include "ec.h"
#include "error.h"
#include "inode.h"
#include "movinggc.h"
#include "recovery.h"
#include "reflink.h"
#include "replicas.h"
#include "subvolume.h"
#include "trace.h"

#include <linux/preempt.h>

void bch2_dev_usage_read_fast(struct bch_dev *ca, struct bch_dev_usage *usage)
{
	memset(usage, 0, sizeof(*usage));
	acc_u64s_percpu((u64 *) usage, (u64 __percpu *) ca->usage, dev_usage_u64s());
}

static u64 reserve_factor(u64 r)
{
	return r + (round_up(r, (1 << RESERVE_FACTOR)) >> RESERVE_FACTOR);
}

static struct bch_fs_usage_short
__bch2_fs_usage_read_short(struct bch_fs *c)
{
	struct bch_fs_usage_short ret;
	u64 data, reserved;

	ret.capacity = c->capacity -
		percpu_u64_get(&c->usage->hidden);

	data		= percpu_u64_get(&c->usage->data) +
		percpu_u64_get(&c->usage->btree);
	reserved	= percpu_u64_get(&c->usage->reserved) +
		percpu_u64_get(c->online_reserved);

	ret.used	= min(ret.capacity, data + reserve_factor(reserved));
	ret.free	= ret.capacity - ret.used;

	ret.nr_inodes	= percpu_u64_get(&c->usage->nr_inodes);

	return ret;
}

struct bch_fs_usage_short
bch2_fs_usage_read_short(struct bch_fs *c)
{
	struct bch_fs_usage_short ret;

	percpu_down_read(&c->mark_lock);
	ret = __bch2_fs_usage_read_short(c);
	percpu_up_read(&c->mark_lock);

	return ret;
}

void bch2_dev_usage_to_text(struct printbuf *out,
			    struct bch_dev *ca,
			    struct bch_dev_usage *usage)
{
	prt_printf(out, "\tbuckets\rsectors\rfragmented\r\n");

	for (unsigned i = 0; i < BCH_DATA_NR; i++) {
		bch2_prt_data_type(out, i);
		prt_printf(out, "\t%llu\r%llu\r%llu\r\n",
			   usage->d[i].buckets,
			   usage->d[i].sectors,
			   usage->d[i].fragmented);
	}

	prt_printf(out, "capacity\t%llu\r\n", ca->mi.nbuckets);
}

static int bch2_check_fix_ptr(struct btree_trans *trans,
			      struct bkey_s_c k,
			      struct extent_ptr_decoded p,
			      const union bch_extent_entry *entry,
			      bool *do_update)
{
	struct bch_fs *c = trans->c;
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev);
	if (!ca) {
		if (fsck_err(trans, ptr_to_invalid_device,
			     "pointer to missing device %u\n"
			     "while marking %s",
			     p.ptr.dev,
			     (printbuf_reset(&buf),
			      bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
			*do_update = true;
		return 0;
	}

	struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
	if (!g) {
		if (fsck_err(trans, ptr_to_invalid_device,
			     "pointer to invalid bucket on device %u\n"
			     "while marking %s",
			     p.ptr.dev,
			     (printbuf_reset(&buf),
			      bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
			*do_update = true;
		goto out;
	}

	enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry);

	if (fsck_err_on(!g->gen_valid,
			trans, ptr_to_missing_alloc_key,
			"bucket %u:%zu data type %s ptr gen %u missing in alloc btree\n"
			"while marking %s",
			p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
			bch2_data_type_str(ptr_data_type(k.k, &p.ptr)),
			p.ptr.gen,
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
		if (!p.ptr.cached) {
			g->gen_valid		= true;
			g->gen			= p.ptr.gen;
		} else {
			*do_update = true;
		}
	}

	if (fsck_err_on(gen_cmp(p.ptr.gen, g->gen) > 0,
			trans, ptr_gen_newer_than_bucket_gen,
			"bucket %u:%zu data type %s ptr gen in the future: %u > %u\n"
			"while marking %s",
			p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
			bch2_data_type_str(ptr_data_type(k.k, &p.ptr)),
			p.ptr.gen, g->gen,
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
		if (!p.ptr.cached &&
		    (g->data_type != BCH_DATA_btree ||
		     data_type == BCH_DATA_btree)) {
			g->gen_valid		= true;
			g->gen			= p.ptr.gen;
			g->data_type		= 0;
			g->stripe_sectors	= 0;
			g->dirty_sectors	= 0;
			g->cached_sectors	= 0;
		} else {
			*do_update = true;
		}
	}

	if (fsck_err_on(gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX,
			trans, ptr_gen_newer_than_bucket_gen,
			"bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
			"while marking %s",
			p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr), g->gen,
			bch2_data_type_str(ptr_data_type(k.k, &p.ptr)),
			p.ptr.gen,
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
		*do_update = true;

	if (fsck_err_on(!p.ptr.cached && gen_cmp(p.ptr.gen, g->gen) < 0,
			trans, stale_dirty_ptr,
			"bucket %u:%zu data type %s stale dirty ptr: %u < %u\n"
			"while marking %s",
			p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr),
			bch2_data_type_str(ptr_data_type(k.k, &p.ptr)),
			p.ptr.gen, g->gen,
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
		*do_update = true;

	if (data_type != BCH_DATA_btree && p.ptr.gen != g->gen)
		goto out;

	if (fsck_err_on(bucket_data_type_mismatch(g->data_type, data_type),
			trans, ptr_bucket_data_type_mismatch,
			"bucket %u:%zu gen %u different types of data in same bucket: %s, %s\n"
			"while marking %s",
			p.ptr.dev, PTR_BUCKET_NR(ca, &p.ptr), g->gen,
			bch2_data_type_str(g->data_type),
			bch2_data_type_str(data_type),
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
		if (data_type == BCH_DATA_btree) {
			g->gen_valid		= true;
			g->gen			= p.ptr.gen;
			g->data_type		= data_type;
			g->stripe_sectors	= 0;
			g->dirty_sectors	= 0;
			g->cached_sectors	= 0;
		} else {
			*do_update = true;
		}
	}

	if (p.has_ec) {
		struct gc_stripe *m = genradix_ptr(&c->gc_stripes, p.ec.idx);

		if (fsck_err_on(!m || !m->alive,
				trans, ptr_to_missing_stripe,
				"pointer to nonexistent stripe %llu\n"
				"while marking %s",
				(u64) p.ec.idx,
				(printbuf_reset(&buf),
				 bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
			*do_update = true;

		if (fsck_err_on(m && m->alive && !bch2_ptr_matches_stripe_m(m, p),
				trans, ptr_to_incorrect_stripe,
				"pointer does not match stripe %llu\n"
				"while marking %s",
				(u64) p.ec.idx,
				(printbuf_reset(&buf),
				 bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
			*do_update = true;
	}
out:
fsck_err:
	bch2_dev_put(ca);
	printbuf_exit(&buf);
	return ret;
}

int bch2_check_fix_ptrs(struct btree_trans *trans,
			enum btree_id btree, unsigned level, struct bkey_s_c k,
			enum btree_iter_update_trigger_flags flags)
{
	struct bch_fs *c = trans->c;
	struct bkey_ptrs_c ptrs_c = bch2_bkey_ptrs_c(k);
	const union bch_extent_entry *entry_c;
	struct extent_ptr_decoded p = { 0 };
	bool do_update = false;
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	percpu_down_read(&c->mark_lock);

	bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) {
		ret = bch2_check_fix_ptr(trans, k, p, entry_c, &do_update);
		if (ret)
			goto err;
	}

	if (do_update) {
		if (flags & BTREE_TRIGGER_is_root) {
			bch_err(c, "cannot update btree roots yet");
			ret = -EINVAL;
			goto err;
		}

		struct bkey_i *new = bch2_bkey_make_mut_noupdate(trans, k);
		ret = PTR_ERR_OR_ZERO(new);
		if (ret)
			goto err;

		rcu_read_lock();
		bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, !bch2_dev_rcu(c, ptr->dev));
		rcu_read_unlock();

		if (level) {
			/*
			 * We don't want to drop btree node pointers - if the
			 * btree node isn't there anymore, the read path will
			 * sort it out:
			 */
			struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
			rcu_read_lock();
			bkey_for_each_ptr(ptrs, ptr) {
				struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
				struct bucket *g = PTR_GC_BUCKET(ca, ptr);

				ptr->gen = g->gen;
			}
			rcu_read_unlock();
		} else {
			struct bkey_ptrs ptrs;
			union bch_extent_entry *entry;

			rcu_read_lock();
restart_drop_ptrs:
			ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
			bkey_for_each_ptr_decode(bkey_i_to_s(new).k, ptrs, p, entry) {
				struct bch_dev *ca = bch2_dev_rcu(c, p.ptr.dev);
				struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr);
				enum bch_data_type data_type = bch2_bkey_ptr_data_type(bkey_i_to_s_c(new), p, entry);

				if ((p.ptr.cached &&
				     (!g->gen_valid || gen_cmp(p.ptr.gen, g->gen) > 0)) ||
				    (!p.ptr.cached &&
				     gen_cmp(p.ptr.gen, g->gen) < 0) ||
				    gen_cmp(g->gen, p.ptr.gen) > BUCKET_GC_GEN_MAX ||
				    (g->data_type &&
				     g->data_type != data_type)) {
					bch2_bkey_drop_ptr(bkey_i_to_s(new), &entry->ptr);
					goto restart_drop_ptrs;
				}
			}
			rcu_read_unlock();
again:
			ptrs = bch2_bkey_ptrs(bkey_i_to_s(new));
			bkey_extent_entry_for_each(ptrs, entry) {
				if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_stripe_ptr) {
					struct gc_stripe *m = genradix_ptr(&c->gc_stripes,
									entry->stripe_ptr.idx);
					union bch_extent_entry *next_ptr;

					bkey_extent_entry_for_each_from(ptrs, next_ptr, entry)
						if (extent_entry_type(next_ptr) == BCH_EXTENT_ENTRY_ptr)
							goto found;
					next_ptr = NULL;
found:
					if (!next_ptr) {
						bch_err(c, "aieee, found stripe ptr with no data ptr");
						continue;
					}

					if (!m || !m->alive ||
					    !__bch2_ptr_matches_stripe(&m->ptrs[entry->stripe_ptr.block],
								       &next_ptr->ptr,
								       m->sectors)) {
						bch2_bkey_extent_entry_drop(new, entry);
						goto again;
					}
				}
			}
		}

		if (0) {
			printbuf_reset(&buf);
			bch2_bkey_val_to_text(&buf, c, k);
			bch_info(c, "updated %s", buf.buf);

			printbuf_reset(&buf);
			bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(new));
			bch_info(c, "new key %s", buf.buf);
		}

		percpu_up_read(&c->mark_lock);
		struct btree_iter iter;
		bch2_trans_node_iter_init(trans, &iter, btree, new->k.p, 0, level,
					  BTREE_ITER_intent|BTREE_ITER_all_snapshots);
		ret =   bch2_btree_iter_traverse(&iter) ?:
			bch2_trans_update(trans, &iter, new,
					  BTREE_UPDATE_internal_snapshot_node|
					  BTREE_TRIGGER_norun);
		bch2_trans_iter_exit(trans, &iter);
		percpu_down_read(&c->mark_lock);

		if (ret)
			goto err;

		if (level)
			bch2_btree_node_update_key_early(trans, btree, level - 1, k, new);
	}
err:
	percpu_up_read(&c->mark_lock);
	printbuf_exit(&buf);
	return ret;
}

int bch2_bucket_ref_update(struct btree_trans *trans, struct bch_dev *ca,
			   struct bkey_s_c k,
			   const struct bch_extent_ptr *ptr,
			   s64 sectors, enum bch_data_type ptr_data_type,
			   u8 b_gen, u8 bucket_data_type,
			   u32 *bucket_sectors)
{
	struct bch_fs *c = trans->c;
	size_t bucket_nr = PTR_BUCKET_NR(ca, ptr);
	struct printbuf buf = PRINTBUF;
	bool inserting = sectors > 0;
	int ret = 0;

	BUG_ON(!sectors);

	if (gen_after(ptr->gen, b_gen)) {
		bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
			      ptr_gen_newer_than_bucket_gen,
			"bucket %u:%zu gen %u data type %s: ptr gen %u newer than bucket gen\n"
			"while marking %s",
			ptr->dev, bucket_nr, b_gen,
			bch2_data_type_str(bucket_data_type ?: ptr_data_type),
			ptr->gen,
			(bch2_bkey_val_to_text(&buf, c, k), buf.buf));
		if (inserting)
			goto err;
		goto out;
	}

	if (gen_cmp(b_gen, ptr->gen) > BUCKET_GC_GEN_MAX) {
		bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
			      ptr_too_stale,
			"bucket %u:%zu gen %u data type %s: ptr gen %u too stale\n"
			"while marking %s",
			ptr->dev, bucket_nr, b_gen,
			bch2_data_type_str(bucket_data_type ?: ptr_data_type),
			ptr->gen,
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf));
		if (inserting)
			goto err;
		goto out;
	}

	if (b_gen != ptr->gen && ptr->cached) {
		ret = 1;
		goto out;
	}

	if (b_gen != ptr->gen) {
		bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
			      stale_dirty_ptr,
			"bucket %u:%zu gen %u (mem gen %u) data type %s: stale dirty ptr (gen %u)\n"
			"while marking %s",
			ptr->dev, bucket_nr, b_gen,
			bucket_gen_get(ca, bucket_nr),
			bch2_data_type_str(bucket_data_type ?: ptr_data_type),
			ptr->gen,
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf));
		if (inserting)
			goto err;
		goto out;
	}

	if (bucket_data_type_mismatch(bucket_data_type, ptr_data_type)) {
		bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
			      ptr_bucket_data_type_mismatch,
			"bucket %u:%zu gen %u different types of data in same bucket: %s, %s\n"
			"while marking %s",
			ptr->dev, bucket_nr, b_gen,
			bch2_data_type_str(bucket_data_type),
			bch2_data_type_str(ptr_data_type),
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf));
		if (inserting)
			goto err;
		goto out;
	}

	if ((u64) *bucket_sectors + sectors > U32_MAX) {
		bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
			      bucket_sector_count_overflow,
			"bucket %u:%zu gen %u data type %s sector count overflow: %u + %lli > U32_MAX\n"
			"while marking %s",
			ptr->dev, bucket_nr, b_gen,
			bch2_data_type_str(bucket_data_type ?: ptr_data_type),
			*bucket_sectors, sectors,
			(printbuf_reset(&buf),
			 bch2_bkey_val_to_text(&buf, c, k), buf.buf));
		if (inserting)
			goto err;
		sectors = -*bucket_sectors;
	}

	*bucket_sectors += sectors;
out:
	printbuf_exit(&buf);
	return ret;
err:
	bch2_dump_trans_updates(trans);
	ret = -EIO;
	goto out;
}

void bch2_trans_account_disk_usage_change(struct btree_trans *trans)
{
	struct bch_fs *c = trans->c;
	u64 disk_res_sectors = trans->disk_res ? trans->disk_res->sectors : 0;
	static int warned_disk_usage = 0;
	bool warn = false;

	percpu_down_read(&c->mark_lock);
	struct bch_fs_usage_base *src = &trans->fs_usage_delta;

	s64 added = src->btree + src->data + src->reserved;

	/*
	 * Not allowed to reduce sectors_available except by getting a
	 * reservation:
	 */
	s64 should_not_have_added = added - (s64) disk_res_sectors;
	if (unlikely(should_not_have_added > 0)) {
		u64 old, new;

		old = atomic64_read(&c->sectors_available);
		do {
			new = max_t(s64, 0, old - should_not_have_added);
		} while (!atomic64_try_cmpxchg(&c->sectors_available,
					       &old, new));

		added -= should_not_have_added;
		warn = true;
	}

	if (added > 0) {
		trans->disk_res->sectors -= added;
		this_cpu_sub(*c->online_reserved, added);
	}

	preempt_disable();
	struct bch_fs_usage_base *dst = this_cpu_ptr(c->usage);
	acc_u64s((u64 *) dst, (u64 *) src, sizeof(*src) / sizeof(u64));
	preempt_enable();
	percpu_up_read(&c->mark_lock);

	if (unlikely(warn) && !xchg(&warned_disk_usage, 1))
		bch2_trans_inconsistent(trans,
					"disk usage increased %lli more than %llu sectors reserved)",
					should_not_have_added, disk_res_sectors);
}

/* KEY_TYPE_extent: */

static int __mark_pointer(struct btree_trans *trans, struct bch_dev *ca,
			  struct bkey_s_c k,
			  const struct extent_ptr_decoded *p,
			  s64 sectors, enum bch_data_type ptr_data_type,
			  struct bch_alloc_v4 *a)
{
	u32 *dst_sectors = p->has_ec	? &a->stripe_sectors :
		!p->ptr.cached		? &a->dirty_sectors :
					  &a->cached_sectors;
	int ret = bch2_bucket_ref_update(trans, ca, k, &p->ptr, sectors, ptr_data_type,
					 a->gen, a->data_type, dst_sectors);

	if (ret)
		return ret;

	alloc_data_type_set(a, ptr_data_type);
	return 0;
}

static int bch2_trigger_pointer(struct btree_trans *trans,
			enum btree_id btree_id, unsigned level,
			struct bkey_s_c k, struct extent_ptr_decoded p,
			const union bch_extent_entry *entry,
			s64 *sectors,
			enum btree_iter_update_trigger_flags flags)
{
	bool insert = !(flags & BTREE_TRIGGER_overwrite);
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	struct bch_fs *c = trans->c;
	struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev);
	if (unlikely(!ca)) {
		if (insert)
			ret = -EIO;
		goto err;
	}

	struct bpos bucket;
	struct bch_backpointer bp;
	bch2_extent_ptr_to_bp(trans->c, ca, btree_id, level, k, p, entry, &bucket, &bp);
	*sectors = insert ? bp.bucket_len : -((s64) bp.bucket_len);

	if (flags & BTREE_TRIGGER_transactional) {
		struct bkey_i_alloc_v4 *a = bch2_trans_start_alloc_update(trans, bucket, 0);
		ret = PTR_ERR_OR_ZERO(a) ?:
			__mark_pointer(trans, ca, k, &p, *sectors, bp.data_type, &a->v);
		if (ret)
			goto err;

		if (!p.ptr.cached) {
			ret = bch2_bucket_backpointer_mod(trans, ca, bucket, bp, k, insert);
			if (ret)
				goto err;
		}
	}

	if (flags & BTREE_TRIGGER_gc) {
		percpu_down_read(&c->mark_lock);
		struct bucket *g = gc_bucket(ca, bucket.offset);
		if (bch2_fs_inconsistent_on(!g, c, "reference to invalid bucket on device %u\n  %s",
					    p.ptr.dev,
					    (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
			ret = -EIO;
			goto err_unlock;
		}

		bucket_lock(g);
		struct bch_alloc_v4 old = bucket_m_to_alloc(*g), new = old;
		ret = __mark_pointer(trans, ca, k, &p, *sectors, bp.data_type, &new);
		alloc_to_bucket(g, new);
		bucket_unlock(g);
err_unlock:
		percpu_up_read(&c->mark_lock);

		if (!ret)
			ret = bch2_alloc_key_to_dev_counters(trans, ca, &old, &new, flags);
	}
err:
	bch2_dev_put(ca);
	printbuf_exit(&buf);
	return ret;
}

static int bch2_trigger_stripe_ptr(struct btree_trans *trans,
				struct bkey_s_c k,
				struct extent_ptr_decoded p,
				enum bch_data_type data_type,
				s64 sectors,
				enum btree_iter_update_trigger_flags flags)
{
	if (flags & BTREE_TRIGGER_transactional) {
		struct btree_iter iter;
		struct bkey_i_stripe *s = bch2_bkey_get_mut_typed(trans, &iter,
				BTREE_ID_stripes, POS(0, p.ec.idx),
				BTREE_ITER_with_updates, stripe);
		int ret = PTR_ERR_OR_ZERO(s);
		if (unlikely(ret)) {
			bch2_trans_inconsistent_on(bch2_err_matches(ret, ENOENT), trans,
				"pointer to nonexistent stripe %llu",
				(u64) p.ec.idx);
			goto err;
		}

		if (!bch2_ptr_matches_stripe(&s->v, p)) {
			bch2_trans_inconsistent(trans,
				"stripe pointer doesn't match stripe %llu",
				(u64) p.ec.idx);
			ret = -EIO;
			goto err;
		}

		stripe_blockcount_set(&s->v, p.ec.block,
			stripe_blockcount_get(&s->v, p.ec.block) +
			sectors);

		struct disk_accounting_pos acc = {
			.type = BCH_DISK_ACCOUNTING_replicas,
		};
		bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i));
		acc.replicas.data_type = data_type;
		ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, false);
err:
		bch2_trans_iter_exit(trans, &iter);
		return ret;
	}

	if (flags & BTREE_TRIGGER_gc) {
		struct bch_fs *c = trans->c;

		struct gc_stripe *m = genradix_ptr_alloc(&c->gc_stripes, p.ec.idx, GFP_KERNEL);
		if (!m) {
			bch_err(c, "error allocating memory for gc_stripes, idx %llu",
				(u64) p.ec.idx);
			return -BCH_ERR_ENOMEM_mark_stripe_ptr;
		}

		mutex_lock(&c->ec_stripes_heap_lock);

		if (!m || !m->alive) {
			mutex_unlock(&c->ec_stripes_heap_lock);
			struct printbuf buf = PRINTBUF;
			bch2_bkey_val_to_text(&buf, c, k);
			bch_err_ratelimited(c, "pointer to nonexistent stripe %llu\n  while marking %s",
					    (u64) p.ec.idx, buf.buf);
			printbuf_exit(&buf);
			bch2_inconsistent_error(c);
			return -EIO;
		}

		m->block_sectors[p.ec.block] += sectors;

		struct disk_accounting_pos acc = {
			.type = BCH_DISK_ACCOUNTING_replicas,
		};
		memcpy(&acc.replicas, &m->r.e, replicas_entry_bytes(&m->r.e));
		mutex_unlock(&c->ec_stripes_heap_lock);

		acc.replicas.data_type = data_type;
		int ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, true);
		if (ret)
			return ret;
	}

	return 0;
}

static int __trigger_extent(struct btree_trans *trans,
			    enum btree_id btree_id, unsigned level,
			    struct bkey_s_c k,
			    enum btree_iter_update_trigger_flags flags)
{
	bool gc = flags & BTREE_TRIGGER_gc;
	struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
	const union bch_extent_entry *entry;
	struct extent_ptr_decoded p;
	enum bch_data_type data_type = bkey_is_btree_ptr(k.k)
		? BCH_DATA_btree
		: BCH_DATA_user;
	s64 replicas_sectors = 0;
	int ret = 0;

	struct disk_accounting_pos acc_replicas_key = {
		.type			= BCH_DISK_ACCOUNTING_replicas,
		.replicas.data_type	= data_type,
		.replicas.nr_devs	= 0,
		.replicas.nr_required	= 1,
	};

	struct disk_accounting_pos acct_compression_key = {
		.type			= BCH_DISK_ACCOUNTING_compression,
	};
	u64 compression_acct[3] = { 1, 0, 0 };

	bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
		s64 disk_sectors = 0;
		ret = bch2_trigger_pointer(trans, btree_id, level, k, p, entry, &disk_sectors, flags);
		if (ret < 0)
			return ret;

		bool stale = ret > 0;

		if (p.ptr.cached && stale)
			continue;

		if (p.ptr.cached) {
			ret = bch2_mod_dev_cached_sectors(trans, p.ptr.dev, disk_sectors, gc);
			if (ret)
				return ret;
		} else if (!p.has_ec) {
			replicas_sectors       += disk_sectors;
			acc_replicas_key.replicas.devs[acc_replicas_key.replicas.nr_devs++] = p.ptr.dev;
		} else {
			ret = bch2_trigger_stripe_ptr(trans, k, p, data_type, disk_sectors, flags);
			if (ret)
				return ret;

			/*
			 * There may be other dirty pointers in this extent, but
			 * if so they're not required for mounting if we have an
			 * erasure coded pointer in this extent:
			 */
			acc_replicas_key.replicas.nr_required = 0;
		}

		if (acct_compression_key.compression.type &&
		    acct_compression_key.compression.type != p.crc.compression_type) {
			if (flags & BTREE_TRIGGER_overwrite)
				bch2_u64s_neg(compression_acct, ARRAY_SIZE(compression_acct));

			ret = bch2_disk_accounting_mod(trans, &acct_compression_key, compression_acct,
						       ARRAY_SIZE(compression_acct), gc);
			if (ret)
				return ret;

			compression_acct[0] = 1;
			compression_acct[1] = 0;
			compression_acct[2] = 0;
		}

		acct_compression_key.compression.type = p.crc.compression_type;
		if (p.crc.compression_type) {
			compression_acct[1] += p.crc.uncompressed_size;
			compression_acct[2] += p.crc.compressed_size;
		}
	}

	if (acc_replicas_key.replicas.nr_devs) {
		ret = bch2_disk_accounting_mod(trans, &acc_replicas_key, &replicas_sectors, 1, gc);
		if (ret)
			return ret;
	}

	if (acc_replicas_key.replicas.nr_devs && !level && k.k->p.snapshot) {
		struct disk_accounting_pos acc_snapshot_key = {
			.type			= BCH_DISK_ACCOUNTING_snapshot,
			.snapshot.id		= k.k->p.snapshot,
		};
		ret = bch2_disk_accounting_mod(trans, &acc_snapshot_key, &replicas_sectors, 1, gc);
		if (ret)
			return ret;
	}

	if (acct_compression_key.compression.type) {
		if (flags & BTREE_TRIGGER_overwrite)
			bch2_u64s_neg(compression_acct, ARRAY_SIZE(compression_acct));

		ret = bch2_disk_accounting_mod(trans, &acct_compression_key, compression_acct,
					       ARRAY_SIZE(compression_acct), gc);
		if (ret)
			return ret;
	}

	if (level) {
		struct disk_accounting_pos acc_btree_key = {
			.type		= BCH_DISK_ACCOUNTING_btree,
			.btree.id	= btree_id,
		};
		ret = bch2_disk_accounting_mod(trans, &acc_btree_key, &replicas_sectors, 1, gc);
		if (ret)
			return ret;
	} else {
		bool insert = !(flags & BTREE_TRIGGER_overwrite);
		struct disk_accounting_pos acc_inum_key = {
			.type		= BCH_DISK_ACCOUNTING_inum,
			.inum.inum	= k.k->p.inode,
		};
		s64 v[3] = {
			insert ? 1 : -1,
			insert ? k.k->size : -((s64) k.k->size),
			replicas_sectors,
		};
		ret = bch2_disk_accounting_mod(trans, &acc_inum_key, v, ARRAY_SIZE(v), gc);
		if (ret)
			return ret;
	}

	if (bch2_bkey_rebalance_opts(k)) {
		struct disk_accounting_pos acc = {
			.type		= BCH_DISK_ACCOUNTING_rebalance_work,
		};
		ret = bch2_disk_accounting_mod(trans, &acc, &replicas_sectors, 1, gc);
		if (ret)
			return ret;
	}

	return 0;
}

int bch2_trigger_extent(struct btree_trans *trans,
			enum btree_id btree, unsigned level,
			struct bkey_s_c old, struct bkey_s new,
			enum btree_iter_update_trigger_flags flags)
{
	struct bkey_ptrs_c new_ptrs = bch2_bkey_ptrs_c(new.s_c);
	struct bkey_ptrs_c old_ptrs = bch2_bkey_ptrs_c(old);
	unsigned new_ptrs_bytes = (void *) new_ptrs.end - (void *) new_ptrs.start;
	unsigned old_ptrs_bytes = (void *) old_ptrs.end - (void *) old_ptrs.start;

	if (unlikely(flags & BTREE_TRIGGER_check_repair))
		return bch2_check_fix_ptrs(trans, btree, level, new.s_c, flags);

	/* if pointers aren't changing - nothing to do: */
	if (new_ptrs_bytes == old_ptrs_bytes &&
	    !memcmp(new_ptrs.start,
		    old_ptrs.start,
		    new_ptrs_bytes))
		return 0;

	if (flags & BTREE_TRIGGER_transactional) {
		struct bch_fs *c = trans->c;
		int mod = (int) bch2_bkey_needs_rebalance(c, new.s_c) -
			  (int) bch2_bkey_needs_rebalance(c, old);

		if (mod) {
			int ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_rebalance_work,
							      new.k->p, mod > 0);
			if (ret)
				return ret;
		}
	}

	if (flags & (BTREE_TRIGGER_transactional|BTREE_TRIGGER_gc))
		return trigger_run_overwrite_then_insert(__trigger_extent, trans, btree, level, old, new, flags);

	return 0;
}

/* KEY_TYPE_reservation */

static int __trigger_reservation(struct btree_trans *trans,
			enum btree_id btree_id, unsigned level, struct bkey_s_c k,
			enum btree_iter_update_trigger_flags flags)
{
	if (flags & (BTREE_TRIGGER_transactional|BTREE_TRIGGER_gc)) {
		s64 sectors = k.k->size;

		if (flags & BTREE_TRIGGER_overwrite)
			sectors = -sectors;

		struct disk_accounting_pos acc = {
			.type = BCH_DISK_ACCOUNTING_persistent_reserved,
			.persistent_reserved.nr_replicas = bkey_s_c_to_reservation(k).v->nr_replicas,
		};

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

	return 0;
}

int bch2_trigger_reservation(struct btree_trans *trans,
			  enum btree_id btree_id, unsigned level,
			  struct bkey_s_c old, struct bkey_s new,
			  enum btree_iter_update_trigger_flags flags)
{
	return trigger_run_overwrite_then_insert(__trigger_reservation, trans, btree_id, level, old, new, flags);
}

/* Mark superblocks: */

static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
				    struct bch_dev *ca, u64 b,
				    enum bch_data_type type,
				    unsigned sectors)
{
	struct btree_iter iter;
	int ret = 0;

	struct bkey_i_alloc_v4 *a =
		bch2_trans_start_alloc_update_noupdate(trans, &iter, POS(ca->dev_idx, b));
	if (IS_ERR(a))
		return PTR_ERR(a);

	if (a->v.data_type && type && a->v.data_type != type) {
		bch2_fsck_err(trans, FSCK_CAN_IGNORE|FSCK_NEED_FSCK,
			      bucket_metadata_type_mismatch,
			"bucket %llu:%llu gen %u different types of data in same bucket: %s, %s\n"
			"while marking %s",
			iter.pos.inode, iter.pos.offset, a->v.gen,
			bch2_data_type_str(a->v.data_type),
			bch2_data_type_str(type),
			bch2_data_type_str(type));
		ret = -EIO;
		goto err;
	}

	if (a->v.data_type	!= type ||
	    a->v.dirty_sectors	!= sectors) {
		a->v.data_type		= type;
		a->v.dirty_sectors	= sectors;
		ret = bch2_trans_update(trans, &iter, &a->k_i, 0);
	}
err:
	bch2_trans_iter_exit(trans, &iter);
	return ret;
}

static int bch2_mark_metadata_bucket(struct btree_trans *trans, struct bch_dev *ca,
			u64 b, enum bch_data_type data_type, unsigned sectors,
			enum btree_iter_update_trigger_flags flags)
{
	struct bch_fs *c = trans->c;
	int ret = 0;

	percpu_down_read(&c->mark_lock);
	struct bucket *g = gc_bucket(ca, b);
	if (bch2_fs_inconsistent_on(!g, c, "reference to invalid bucket on device %u when marking metadata type %s",
				    ca->dev_idx, bch2_data_type_str(data_type)))
		goto err_unlock;

	bucket_lock(g);
	struct bch_alloc_v4 old = bucket_m_to_alloc(*g);

	if (bch2_fs_inconsistent_on(g->data_type &&
			g->data_type != data_type, c,
			"different types of data in same bucket: %s, %s",
			bch2_data_type_str(g->data_type),
			bch2_data_type_str(data_type)))
		goto err;

	if (bch2_fs_inconsistent_on((u64) g->dirty_sectors + sectors > ca->mi.bucket_size, c,
			"bucket %u:%llu gen %u data type %s sector count overflow: %u + %u > bucket size",
			ca->dev_idx, b, g->gen,
			bch2_data_type_str(g->data_type ?: data_type),
			g->dirty_sectors, sectors))
		goto err;

	g->data_type = data_type;
	g->dirty_sectors += sectors;
	struct bch_alloc_v4 new = bucket_m_to_alloc(*g);
	bucket_unlock(g);
	percpu_up_read(&c->mark_lock);
	ret = bch2_alloc_key_to_dev_counters(trans, ca, &old, &new, flags);
	return ret;
err:
	bucket_unlock(g);
err_unlock:
	percpu_up_read(&c->mark_lock);
	return -EIO;
}

int bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
			struct bch_dev *ca, u64 b,
			enum bch_data_type type, unsigned sectors,
			enum btree_iter_update_trigger_flags flags)
{
	BUG_ON(type != BCH_DATA_free &&
	       type != BCH_DATA_sb &&
	       type != BCH_DATA_journal);

	/*
	 * Backup superblock might be past the end of our normal usable space:
	 */
	if (b >= ca->mi.nbuckets)
		return 0;

	if (flags & BTREE_TRIGGER_gc)
		return bch2_mark_metadata_bucket(trans, ca, b, type, sectors, flags);
	else if (flags & BTREE_TRIGGER_transactional)
		return commit_do(trans, NULL, NULL, 0,
				 __bch2_trans_mark_metadata_bucket(trans, ca, b, type, sectors));
	else
		BUG();
}

static int bch2_trans_mark_metadata_sectors(struct btree_trans *trans,
			struct bch_dev *ca, u64 start, u64 end,
			enum bch_data_type type, u64 *bucket, unsigned *bucket_sectors,
			enum btree_iter_update_trigger_flags flags)
{
	do {
		u64 b = sector_to_bucket(ca, start);
		unsigned sectors =
			min_t(u64, bucket_to_sector(ca, b + 1), end) - start;

		if (b != *bucket && *bucket_sectors) {
			int ret = bch2_trans_mark_metadata_bucket(trans, ca, *bucket,
							type, *bucket_sectors, flags);
			if (ret)
				return ret;

			*bucket_sectors = 0;
		}

		*bucket		= b;
		*bucket_sectors	+= sectors;
		start += sectors;
	} while (start < end);

	return 0;
}

static int __bch2_trans_mark_dev_sb(struct btree_trans *trans, struct bch_dev *ca,
			enum btree_iter_update_trigger_flags flags)
{
	struct bch_fs *c = trans->c;

	mutex_lock(&c->sb_lock);
	struct bch_sb_layout layout = ca->disk_sb.sb->layout;
	mutex_unlock(&c->sb_lock);

	u64 bucket = 0;
	unsigned i, bucket_sectors = 0;
	int ret;

	for (i = 0; i < layout.nr_superblocks; i++) {
		u64 offset = le64_to_cpu(layout.sb_offset[i]);

		if (offset == BCH_SB_SECTOR) {
			ret = bch2_trans_mark_metadata_sectors(trans, ca,
						0, BCH_SB_SECTOR,
						BCH_DATA_sb, &bucket, &bucket_sectors, flags);
			if (ret)
				return ret;
		}

		ret = bch2_trans_mark_metadata_sectors(trans, ca, offset,
				      offset + (1 << layout.sb_max_size_bits),
				      BCH_DATA_sb, &bucket, &bucket_sectors, flags);
		if (ret)
			return ret;
	}

	if (bucket_sectors) {
		ret = bch2_trans_mark_metadata_bucket(trans, ca,
				bucket, BCH_DATA_sb, bucket_sectors, flags);
		if (ret)
			return ret;
	}

	for (i = 0; i < ca->journal.nr; i++) {
		ret = bch2_trans_mark_metadata_bucket(trans, ca,
				ca->journal.buckets[i],
				BCH_DATA_journal, ca->mi.bucket_size, flags);
		if (ret)
			return ret;
	}

	return 0;
}

int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca,
			enum btree_iter_update_trigger_flags flags)
{
	int ret = bch2_trans_run(c,
		__bch2_trans_mark_dev_sb(trans, ca, flags));
	bch_err_fn(c, ret);
	return ret;
}

int bch2_trans_mark_dev_sbs_flags(struct bch_fs *c,
			enum btree_iter_update_trigger_flags flags)
{
	for_each_online_member(c, ca) {
		int ret = bch2_trans_mark_dev_sb(c, ca, flags);
		if (ret) {
			percpu_ref_put(&ca->io_ref);
			return ret;
		}
	}

	return 0;
}

int bch2_trans_mark_dev_sbs(struct bch_fs *c)
{
	return bch2_trans_mark_dev_sbs_flags(c, BTREE_TRIGGER_transactional);
}

/* Disk reservations: */

#define SECTORS_CACHE	1024

int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
			      u64 sectors, int flags)
{
	struct bch_fs_pcpu *pcpu;
	u64 old, get;
	s64 sectors_available;
	int ret;

	percpu_down_read(&c->mark_lock);
	preempt_disable();
	pcpu = this_cpu_ptr(c->pcpu);

	if (sectors <= pcpu->sectors_available)
		goto out;

	old = atomic64_read(&c->sectors_available);
	do {
		get = min((u64) sectors + SECTORS_CACHE, old);

		if (get < sectors) {
			preempt_enable();
			goto recalculate;
		}
	} while (!atomic64_try_cmpxchg(&c->sectors_available,
				       &old, old - get));

	pcpu->sectors_available		+= get;

out:
	pcpu->sectors_available		-= sectors;
	this_cpu_add(*c->online_reserved, sectors);
	res->sectors			+= sectors;

	preempt_enable();
	percpu_up_read(&c->mark_lock);
	return 0;

recalculate:
	mutex_lock(&c->sectors_available_lock);

	percpu_u64_set(&c->pcpu->sectors_available, 0);
	sectors_available = avail_factor(__bch2_fs_usage_read_short(c).free);

	if (sectors <= sectors_available ||
	    (flags & BCH_DISK_RESERVATION_NOFAIL)) {
		atomic64_set(&c->sectors_available,
			     max_t(s64, 0, sectors_available - sectors));
		this_cpu_add(*c->online_reserved, sectors);
		res->sectors			+= sectors;
		ret = 0;
	} else {
		atomic64_set(&c->sectors_available, sectors_available);
		ret = -BCH_ERR_ENOSPC_disk_reservation;
	}

	mutex_unlock(&c->sectors_available_lock);
	percpu_up_read(&c->mark_lock);

	return ret;
}

/* Startup/shutdown: */

void bch2_buckets_nouse_free(struct bch_fs *c)
{
	for_each_member_device(c, ca) {
		kvfree_rcu_mightsleep(ca->buckets_nouse);
		ca->buckets_nouse = NULL;
	}
}

int bch2_buckets_nouse_alloc(struct bch_fs *c)
{
	for_each_member_device(c, ca) {
		BUG_ON(ca->buckets_nouse);

		ca->buckets_nouse = kvmalloc(BITS_TO_LONGS(ca->mi.nbuckets) *
					    sizeof(unsigned long),
					    GFP_KERNEL|__GFP_ZERO);
		if (!ca->buckets_nouse) {
			bch2_dev_put(ca);
			return -BCH_ERR_ENOMEM_buckets_nouse;
		}
	}

	return 0;
}

static void bucket_gens_free_rcu(struct rcu_head *rcu)
{
	struct bucket_gens *buckets =
		container_of(rcu, struct bucket_gens, rcu);

	kvfree(buckets);
}

int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
{
	struct bucket_gens *bucket_gens = NULL, *old_bucket_gens = NULL;
	bool resize = ca->bucket_gens != NULL;
	int ret;

	BUG_ON(resize && ca->buckets_nouse);

	if (!(bucket_gens	= kvmalloc(sizeof(struct bucket_gens) + nbuckets,
					   GFP_KERNEL|__GFP_ZERO))) {
		ret = -BCH_ERR_ENOMEM_bucket_gens;
		goto err;
	}

	bucket_gens->first_bucket = ca->mi.first_bucket;
	bucket_gens->nbuckets	= nbuckets;
	bucket_gens->nbuckets_minus_first =
		bucket_gens->nbuckets - bucket_gens->first_bucket;

	if (resize) {
		down_write(&ca->bucket_lock);
		percpu_down_write(&c->mark_lock);
	}

	old_bucket_gens = rcu_dereference_protected(ca->bucket_gens, 1);

	if (resize) {
		size_t n = min(bucket_gens->nbuckets, old_bucket_gens->nbuckets);

		memcpy(bucket_gens->b,
		       old_bucket_gens->b,
		       n);
	}

	rcu_assign_pointer(ca->bucket_gens, bucket_gens);
	bucket_gens	= old_bucket_gens;

	nbuckets = ca->mi.nbuckets;

	if (resize) {
		percpu_up_write(&c->mark_lock);
		up_write(&ca->bucket_lock);
	}

	ret = 0;
err:
	if (bucket_gens)
		call_rcu(&bucket_gens->rcu, bucket_gens_free_rcu);

	return ret;
}

void bch2_dev_buckets_free(struct bch_dev *ca)
{
	kvfree(ca->buckets_nouse);
	kvfree(rcu_dereference_protected(ca->bucket_gens, 1));
	free_percpu(ca->usage);
}

int bch2_dev_buckets_alloc(struct bch_fs *c, struct bch_dev *ca)
{
	ca->usage = alloc_percpu(struct bch_dev_usage);
	if (!ca->usage)
		return -BCH_ERR_ENOMEM_usage_init;

	return bch2_dev_buckets_resize(c, ca, ca->mi.nbuckets);
}
