// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "buckets.h"
#include "disk_accounting.h"
#include "journal.h"
#include "replicas.h"
#include "super-io.h"

#include <linux/sort.h>

static int bch2_cpu_replicas_to_sb_replicas(struct bch_fs *,
					    struct bch_replicas_cpu *);

/* Some (buggy!) compilers don't allow memcmp to be passed as a pointer */
static int bch2_memcmp(const void *l, const void *r,  const void *priv)
{
	size_t size = (size_t) priv;
	return memcmp(l, r, size);
}

/* Replicas tracking - in memory: */

static void verify_replicas_entry(struct bch_replicas_entry_v1 *e)
{
#ifdef CONFIG_BCACHEFS_DEBUG
	BUG_ON(!e->nr_devs);
	BUG_ON(e->nr_required > 1 &&
	       e->nr_required >= e->nr_devs);

	for (unsigned i = 0; i + 1 < e->nr_devs; i++)
		BUG_ON(e->devs[i] >= e->devs[i + 1]);
#endif
}

void bch2_replicas_entry_sort(struct bch_replicas_entry_v1 *e)
{
	bubble_sort(e->devs, e->nr_devs, u8_cmp);
}

static void bch2_cpu_replicas_sort(struct bch_replicas_cpu *r)
{
	eytzinger0_sort_r(r->entries, r->nr, r->entry_size,
			  bch2_memcmp, NULL, (void *)(size_t)r->entry_size);
}

static void bch2_replicas_entry_v0_to_text(struct printbuf *out,
					   struct bch_replicas_entry_v0 *e)
{
	bch2_prt_data_type(out, e->data_type);

	prt_printf(out, ": %u [", e->nr_devs);
	for (unsigned i = 0; i < e->nr_devs; i++)
		prt_printf(out, i ? " %u" : "%u", e->devs[i]);
	prt_printf(out, "]");
}

void bch2_replicas_entry_to_text(struct printbuf *out,
				 struct bch_replicas_entry_v1 *e)
{
	bch2_prt_data_type(out, e->data_type);

	prt_printf(out, ": %u/%u [", e->nr_required, e->nr_devs);
	for (unsigned i = 0; i < e->nr_devs; i++)
		prt_printf(out, i ? " %u" : "%u", e->devs[i]);
	prt_printf(out, "]");
}

static int bch2_replicas_entry_sb_validate(struct bch_replicas_entry_v1 *r,
					   struct bch_sb *sb,
					   struct printbuf *err)
{
	if (!r->nr_devs) {
		prt_printf(err, "no devices in entry ");
		goto bad;
	}

	if (r->nr_required > 1 &&
	    r->nr_required >= r->nr_devs) {
		prt_printf(err, "bad nr_required in entry ");
		goto bad;
	}

	for (unsigned i = 0; i < r->nr_devs; i++)
		if (r->devs[i] != BCH_SB_MEMBER_INVALID &&
		    !bch2_member_exists(sb, r->devs[i])) {
			prt_printf(err, "invalid device %u in entry ", r->devs[i]);
			goto bad;
		}

	return 0;
bad:
	bch2_replicas_entry_to_text(err, r);
	return -BCH_ERR_invalid_replicas_entry;
}

int bch2_replicas_entry_validate(struct bch_replicas_entry_v1 *r,
				 struct bch_fs *c,
				 struct printbuf *err)
{
	if (!r->nr_devs) {
		prt_printf(err, "no devices in entry ");
		goto bad;
	}

	if (r->nr_required > 1 &&
	    r->nr_required >= r->nr_devs) {
		prt_printf(err, "bad nr_required in entry ");
		goto bad;
	}

	for (unsigned i = 0; i < r->nr_devs; i++)
		if (r->devs[i] != BCH_SB_MEMBER_INVALID &&
		    !bch2_dev_exists(c, r->devs[i])) {
			prt_printf(err, "invalid device %u in entry ", r->devs[i]);
			goto bad;
		}

	return 0;
bad:
	bch2_replicas_entry_to_text(err, r);
	return -BCH_ERR_invalid_replicas_entry;
}

void bch2_cpu_replicas_to_text(struct printbuf *out,
			       struct bch_replicas_cpu *r)
{
	struct bch_replicas_entry_v1 *e;
	bool first = true;

	for_each_cpu_replicas_entry(r, e) {
		if (!first)
			prt_printf(out, " ");
		first = false;

		bch2_replicas_entry_to_text(out, e);
	}
}

static void extent_to_replicas(struct bkey_s_c k,
			       struct bch_replicas_entry_v1 *r)
{
	struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
	const union bch_extent_entry *entry;
	struct extent_ptr_decoded p;

	r->nr_required	= 1;

	bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
		if (p.ptr.cached)
			continue;

		if (!p.has_ec)
			replicas_entry_add_dev(r, p.ptr.dev);
		else
			r->nr_required = 0;
	}
}

static void stripe_to_replicas(struct bkey_s_c k,
			       struct bch_replicas_entry_v1 *r)
{
	struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
	const struct bch_extent_ptr *ptr;

	r->nr_required	= s.v->nr_blocks - s.v->nr_redundant;

	for (ptr = s.v->ptrs;
	     ptr < s.v->ptrs + s.v->nr_blocks;
	     ptr++)
		replicas_entry_add_dev(r, ptr->dev);
}

void bch2_bkey_to_replicas(struct bch_replicas_entry_v1 *e,
			   struct bkey_s_c k)
{
	e->nr_devs = 0;

	switch (k.k->type) {
	case KEY_TYPE_btree_ptr:
	case KEY_TYPE_btree_ptr_v2:
		e->data_type = BCH_DATA_btree;
		extent_to_replicas(k, e);
		break;
	case KEY_TYPE_extent:
	case KEY_TYPE_reflink_v:
		e->data_type = BCH_DATA_user;
		extent_to_replicas(k, e);
		break;
	case KEY_TYPE_stripe:
		e->data_type = BCH_DATA_parity;
		stripe_to_replicas(k, e);
		break;
	}

	bch2_replicas_entry_sort(e);
}

void bch2_devlist_to_replicas(struct bch_replicas_entry_v1 *e,
			      enum bch_data_type data_type,
			      struct bch_devs_list devs)
{
	BUG_ON(!data_type ||
	       data_type == BCH_DATA_sb ||
	       data_type >= BCH_DATA_NR);

	e->data_type	= data_type;
	e->nr_devs	= 0;
	e->nr_required	= 1;

	darray_for_each(devs, i)
		replicas_entry_add_dev(e, *i);

	bch2_replicas_entry_sort(e);
}

static struct bch_replicas_cpu
cpu_replicas_add_entry(struct bch_fs *c,
		       struct bch_replicas_cpu *old,
		       struct bch_replicas_entry_v1 *new_entry)
{
	struct bch_replicas_cpu new = {
		.nr		= old->nr + 1,
		.entry_size	= max_t(unsigned, old->entry_size,
					replicas_entry_bytes(new_entry)),
	};

	new.entries = kcalloc(new.nr, new.entry_size, GFP_KERNEL);
	if (!new.entries)
		return new;

	for (unsigned i = 0; i < old->nr; i++)
		memcpy(cpu_replicas_entry(&new, i),
		       cpu_replicas_entry(old, i),
		       old->entry_size);

	memcpy(cpu_replicas_entry(&new, old->nr),
	       new_entry,
	       replicas_entry_bytes(new_entry));

	bch2_cpu_replicas_sort(&new);
	return new;
}

static inline int __replicas_entry_idx(struct bch_replicas_cpu *r,
				       struct bch_replicas_entry_v1 *search)
{
	int idx, entry_size = replicas_entry_bytes(search);

	if (unlikely(entry_size > r->entry_size))
		return -1;

#define entry_cmp(_l, _r)	memcmp(_l, _r, entry_size)
	idx = eytzinger0_find(r->entries, r->nr, r->entry_size,
			      entry_cmp, search);
#undef entry_cmp

	return idx < r->nr ? idx : -1;
}

int bch2_replicas_entry_idx(struct bch_fs *c,
			    struct bch_replicas_entry_v1 *search)
{
	bch2_replicas_entry_sort(search);

	return __replicas_entry_idx(&c->replicas, search);
}

static bool __replicas_has_entry(struct bch_replicas_cpu *r,
				 struct bch_replicas_entry_v1 *search)
{
	return __replicas_entry_idx(r, search) >= 0;
}

bool bch2_replicas_marked_locked(struct bch_fs *c,
			  struct bch_replicas_entry_v1 *search)
{
	verify_replicas_entry(search);

	return !search->nr_devs ||
		(__replicas_has_entry(&c->replicas, search) &&
		 (likely((!c->replicas_gc.entries)) ||
		  __replicas_has_entry(&c->replicas_gc, search)));
}

bool bch2_replicas_marked(struct bch_fs *c,
			  struct bch_replicas_entry_v1 *search)
{
	percpu_down_read(&c->mark_lock);
	bool ret = bch2_replicas_marked_locked(c, search);
	percpu_up_read(&c->mark_lock);

	return ret;
}

noinline
static int bch2_mark_replicas_slowpath(struct bch_fs *c,
				struct bch_replicas_entry_v1 *new_entry)
{
	struct bch_replicas_cpu new_r, new_gc;
	int ret = 0;

	verify_replicas_entry(new_entry);

	memset(&new_r, 0, sizeof(new_r));
	memset(&new_gc, 0, sizeof(new_gc));

	mutex_lock(&c->sb_lock);

	if (c->replicas_gc.entries &&
	    !__replicas_has_entry(&c->replicas_gc, new_entry)) {
		new_gc = cpu_replicas_add_entry(c, &c->replicas_gc, new_entry);
		if (!new_gc.entries) {
			ret = -BCH_ERR_ENOMEM_cpu_replicas;
			goto err;
		}
	}

	if (!__replicas_has_entry(&c->replicas, new_entry)) {
		new_r = cpu_replicas_add_entry(c, &c->replicas, new_entry);
		if (!new_r.entries) {
			ret = -BCH_ERR_ENOMEM_cpu_replicas;
			goto err;
		}

		ret = bch2_cpu_replicas_to_sb_replicas(c, &new_r);
		if (ret)
			goto err;
	}

	if (!new_r.entries &&
	    !new_gc.entries)
		goto out;

	/* allocations done, now commit: */

	if (new_r.entries)
		bch2_write_super(c);

	/* don't update in memory replicas until changes are persistent */
	percpu_down_write(&c->mark_lock);
	if (new_r.entries)
		swap(c->replicas, new_r);
	if (new_gc.entries)
		swap(new_gc, c->replicas_gc);
	percpu_up_write(&c->mark_lock);
out:
	mutex_unlock(&c->sb_lock);

	kfree(new_r.entries);
	kfree(new_gc.entries);

	return ret;
err:
	bch_err_msg(c, ret, "adding replicas entry");
	goto out;
}

int bch2_mark_replicas(struct bch_fs *c, struct bch_replicas_entry_v1 *r)
{
	return likely(bch2_replicas_marked(c, r))
		? 0 : bch2_mark_replicas_slowpath(c, r);
}

/*
 * Old replicas_gc mechanism: only used for journal replicas entries now, should
 * die at some point:
 */

int bch2_replicas_gc_end(struct bch_fs *c, int ret)
{
	lockdep_assert_held(&c->replicas_gc_lock);

	mutex_lock(&c->sb_lock);
	percpu_down_write(&c->mark_lock);

	ret =   ret ?:
		bch2_cpu_replicas_to_sb_replicas(c, &c->replicas_gc);
	if (!ret)
		swap(c->replicas, c->replicas_gc);

	kfree(c->replicas_gc.entries);
	c->replicas_gc.entries = NULL;

	percpu_up_write(&c->mark_lock);

	if (!ret)
		bch2_write_super(c);

	mutex_unlock(&c->sb_lock);

	return ret;
}

int bch2_replicas_gc_start(struct bch_fs *c, unsigned typemask)
{
	struct bch_replicas_entry_v1 *e;
	unsigned i = 0;

	lockdep_assert_held(&c->replicas_gc_lock);

	mutex_lock(&c->sb_lock);
	BUG_ON(c->replicas_gc.entries);

	c->replicas_gc.nr		= 0;
	c->replicas_gc.entry_size	= 0;

	for_each_cpu_replicas_entry(&c->replicas, e) {
		/* Preserve unknown data types */
		if (e->data_type >= BCH_DATA_NR ||
		    !((1 << e->data_type) & typemask)) {
			c->replicas_gc.nr++;
			c->replicas_gc.entry_size =
				max_t(unsigned, c->replicas_gc.entry_size,
				      replicas_entry_bytes(e));
		}
	}

	c->replicas_gc.entries = kcalloc(c->replicas_gc.nr,
					 c->replicas_gc.entry_size,
					 GFP_KERNEL);
	if (!c->replicas_gc.entries) {
		mutex_unlock(&c->sb_lock);
		bch_err(c, "error allocating c->replicas_gc");
		return -BCH_ERR_ENOMEM_replicas_gc;
	}

	for_each_cpu_replicas_entry(&c->replicas, e)
		if (e->data_type >= BCH_DATA_NR ||
		    !((1 << e->data_type) & typemask))
			memcpy(cpu_replicas_entry(&c->replicas_gc, i++),
			       e, c->replicas_gc.entry_size);

	bch2_cpu_replicas_sort(&c->replicas_gc);
	mutex_unlock(&c->sb_lock);

	return 0;
}

/*
 * New much simpler mechanism for clearing out unneeded replicas entries - drop
 * replicas entries that have 0 sectors used.
 *
 * However, we don't track sector counts for journal usage, so this doesn't drop
 * any BCH_DATA_journal entries; the old bch2_replicas_gc_(start|end) mechanism
 * is retained for that.
 */
int bch2_replicas_gc2(struct bch_fs *c)
{
	struct bch_replicas_cpu new = { 0 };
	unsigned nr;
	int ret = 0;

	bch2_accounting_mem_gc(c);
retry:
	nr		= READ_ONCE(c->replicas.nr);
	new.entry_size	= READ_ONCE(c->replicas.entry_size);
	new.entries	= kcalloc(nr, new.entry_size, GFP_KERNEL);
	if (!new.entries) {
		bch_err(c, "error allocating c->replicas_gc");
		return -BCH_ERR_ENOMEM_replicas_gc;
	}

	mutex_lock(&c->sb_lock);
	percpu_down_write(&c->mark_lock);

	if (nr			!= c->replicas.nr ||
	    new.entry_size	!= c->replicas.entry_size) {
		percpu_up_write(&c->mark_lock);
		mutex_unlock(&c->sb_lock);
		kfree(new.entries);
		goto retry;
	}

	for (unsigned i = 0; i < c->replicas.nr; i++) {
		struct bch_replicas_entry_v1 *e =
			cpu_replicas_entry(&c->replicas, i);

		struct disk_accounting_pos k = {
			.type = BCH_DISK_ACCOUNTING_replicas,
		};

		unsafe_memcpy(&k.replicas, e, replicas_entry_bytes(e),
			      "embedded variable length struct");

		struct bpos p = disk_accounting_pos_to_bpos(&k);

		struct bch_accounting_mem *acc = &c->accounting;
		bool kill = eytzinger0_find(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
					    accounting_pos_cmp, &p) >= acc->k.nr;

		if (e->data_type == BCH_DATA_journal || !kill)
			memcpy(cpu_replicas_entry(&new, new.nr++),
			       e, new.entry_size);
	}

	bch2_cpu_replicas_sort(&new);

	ret = bch2_cpu_replicas_to_sb_replicas(c, &new);

	if (!ret)
		swap(c->replicas, new);

	kfree(new.entries);

	percpu_up_write(&c->mark_lock);

	if (!ret)
		bch2_write_super(c);

	mutex_unlock(&c->sb_lock);

	return ret;
}

/* Replicas tracking - superblock: */

static int
__bch2_sb_replicas_to_cpu_replicas(struct bch_sb_field_replicas *sb_r,
				   struct bch_replicas_cpu *cpu_r)
{
	struct bch_replicas_entry_v1 *e, *dst;
	unsigned nr = 0, entry_size = 0, idx = 0;

	for_each_replicas_entry(sb_r, e) {
		entry_size = max_t(unsigned, entry_size,
				   replicas_entry_bytes(e));
		nr++;
	}

	cpu_r->entries = kcalloc(nr, entry_size, GFP_KERNEL);
	if (!cpu_r->entries)
		return -BCH_ERR_ENOMEM_cpu_replicas;

	cpu_r->nr		= nr;
	cpu_r->entry_size	= entry_size;

	for_each_replicas_entry(sb_r, e) {
		dst = cpu_replicas_entry(cpu_r, idx++);
		memcpy(dst, e, replicas_entry_bytes(e));
		bch2_replicas_entry_sort(dst);
	}

	return 0;
}

static int
__bch2_sb_replicas_v0_to_cpu_replicas(struct bch_sb_field_replicas_v0 *sb_r,
				      struct bch_replicas_cpu *cpu_r)
{
	struct bch_replicas_entry_v0 *e;
	unsigned nr = 0, entry_size = 0, idx = 0;

	for_each_replicas_entry(sb_r, e) {
		entry_size = max_t(unsigned, entry_size,
				   replicas_entry_bytes(e));
		nr++;
	}

	entry_size += sizeof(struct bch_replicas_entry_v1) -
		sizeof(struct bch_replicas_entry_v0);

	cpu_r->entries = kcalloc(nr, entry_size, GFP_KERNEL);
	if (!cpu_r->entries)
		return -BCH_ERR_ENOMEM_cpu_replicas;

	cpu_r->nr		= nr;
	cpu_r->entry_size	= entry_size;

	for_each_replicas_entry(sb_r, e) {
		struct bch_replicas_entry_v1 *dst =
			cpu_replicas_entry(cpu_r, idx++);

		dst->data_type	= e->data_type;
		dst->nr_devs	= e->nr_devs;
		dst->nr_required = 1;
		memcpy(dst->devs, e->devs, e->nr_devs);
		bch2_replicas_entry_sort(dst);
	}

	return 0;
}

int bch2_sb_replicas_to_cpu_replicas(struct bch_fs *c)
{
	struct bch_sb_field_replicas *sb_v1;
	struct bch_sb_field_replicas_v0 *sb_v0;
	struct bch_replicas_cpu new_r = { 0, 0, NULL };
	int ret = 0;

	if ((sb_v1 = bch2_sb_field_get(c->disk_sb.sb, replicas)))
		ret = __bch2_sb_replicas_to_cpu_replicas(sb_v1, &new_r);
	else if ((sb_v0 = bch2_sb_field_get(c->disk_sb.sb, replicas_v0)))
		ret = __bch2_sb_replicas_v0_to_cpu_replicas(sb_v0, &new_r);
	if (ret)
		return ret;

	bch2_cpu_replicas_sort(&new_r);

	percpu_down_write(&c->mark_lock);
	swap(c->replicas, new_r);
	percpu_up_write(&c->mark_lock);

	kfree(new_r.entries);

	return 0;
}

static int bch2_cpu_replicas_to_sb_replicas_v0(struct bch_fs *c,
					       struct bch_replicas_cpu *r)
{
	struct bch_sb_field_replicas_v0 *sb_r;
	struct bch_replicas_entry_v0 *dst;
	struct bch_replicas_entry_v1 *src;
	size_t bytes;

	bytes = sizeof(struct bch_sb_field_replicas);

	for_each_cpu_replicas_entry(r, src)
		bytes += replicas_entry_bytes(src) - 1;

	sb_r = bch2_sb_field_resize(&c->disk_sb, replicas_v0,
			DIV_ROUND_UP(bytes, sizeof(u64)));
	if (!sb_r)
		return -BCH_ERR_ENOSPC_sb_replicas;

	bch2_sb_field_delete(&c->disk_sb, BCH_SB_FIELD_replicas);
	sb_r = bch2_sb_field_get(c->disk_sb.sb, replicas_v0);

	memset(&sb_r->entries, 0,
	       vstruct_end(&sb_r->field) -
	       (void *) &sb_r->entries);

	dst = sb_r->entries;
	for_each_cpu_replicas_entry(r, src) {
		dst->data_type	= src->data_type;
		dst->nr_devs	= src->nr_devs;
		memcpy(dst->devs, src->devs, src->nr_devs);

		dst = replicas_entry_next(dst);

		BUG_ON((void *) dst > vstruct_end(&sb_r->field));
	}

	return 0;
}

static int bch2_cpu_replicas_to_sb_replicas(struct bch_fs *c,
					    struct bch_replicas_cpu *r)
{
	struct bch_sb_field_replicas *sb_r;
	struct bch_replicas_entry_v1 *dst, *src;
	bool need_v1 = false;
	size_t bytes;

	bytes = sizeof(struct bch_sb_field_replicas);

	for_each_cpu_replicas_entry(r, src) {
		bytes += replicas_entry_bytes(src);
		if (src->nr_required != 1)
			need_v1 = true;
	}

	if (!need_v1)
		return bch2_cpu_replicas_to_sb_replicas_v0(c, r);

	sb_r = bch2_sb_field_resize(&c->disk_sb, replicas,
			DIV_ROUND_UP(bytes, sizeof(u64)));
	if (!sb_r)
		return -BCH_ERR_ENOSPC_sb_replicas;

	bch2_sb_field_delete(&c->disk_sb, BCH_SB_FIELD_replicas_v0);
	sb_r = bch2_sb_field_get(c->disk_sb.sb, replicas);

	memset(&sb_r->entries, 0,
	       vstruct_end(&sb_r->field) -
	       (void *) &sb_r->entries);

	dst = sb_r->entries;
	for_each_cpu_replicas_entry(r, src) {
		memcpy(dst, src, replicas_entry_bytes(src));

		dst = replicas_entry_next(dst);

		BUG_ON((void *) dst > vstruct_end(&sb_r->field));
	}

	return 0;
}

static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
				      struct bch_sb *sb,
				      struct printbuf *err)
{
	unsigned i;

	sort_r(cpu_r->entries,
	       cpu_r->nr,
	       cpu_r->entry_size,
	       bch2_memcmp, NULL,
	       (void *)(size_t)cpu_r->entry_size);

	for (i = 0; i < cpu_r->nr; i++) {
		struct bch_replicas_entry_v1 *e =
			cpu_replicas_entry(cpu_r, i);

		int ret = bch2_replicas_entry_sb_validate(e, sb, err);
		if (ret)
			return ret;

		if (i + 1 < cpu_r->nr) {
			struct bch_replicas_entry_v1 *n =
				cpu_replicas_entry(cpu_r, i + 1);

			BUG_ON(memcmp(e, n, cpu_r->entry_size) > 0);

			if (!memcmp(e, n, cpu_r->entry_size)) {
				prt_printf(err, "duplicate replicas entry ");
				bch2_replicas_entry_to_text(err, e);
				return -BCH_ERR_invalid_sb_replicas;
			}
		}
	}

	return 0;
}

static int bch2_sb_replicas_validate(struct bch_sb *sb, struct bch_sb_field *f,
				     enum bch_validate_flags flags, struct printbuf *err)
{
	struct bch_sb_field_replicas *sb_r = field_to_type(f, replicas);
	struct bch_replicas_cpu cpu_r;
	int ret;

	ret = __bch2_sb_replicas_to_cpu_replicas(sb_r, &cpu_r);
	if (ret)
		return ret;

	ret = bch2_cpu_replicas_validate(&cpu_r, sb, err);
	kfree(cpu_r.entries);
	return ret;
}

static void bch2_sb_replicas_to_text(struct printbuf *out,
				     struct bch_sb *sb,
				     struct bch_sb_field *f)
{
	struct bch_sb_field_replicas *r = field_to_type(f, replicas);
	struct bch_replicas_entry_v1 *e;
	bool first = true;

	for_each_replicas_entry(r, e) {
		if (!first)
			prt_printf(out, " ");
		first = false;

		bch2_replicas_entry_to_text(out, e);
	}
	prt_newline(out);
}

const struct bch_sb_field_ops bch_sb_field_ops_replicas = {
	.validate	= bch2_sb_replicas_validate,
	.to_text	= bch2_sb_replicas_to_text,
};

static int bch2_sb_replicas_v0_validate(struct bch_sb *sb, struct bch_sb_field *f,
					enum bch_validate_flags flags, struct printbuf *err)
{
	struct bch_sb_field_replicas_v0 *sb_r = field_to_type(f, replicas_v0);
	struct bch_replicas_cpu cpu_r;
	int ret;

	ret = __bch2_sb_replicas_v0_to_cpu_replicas(sb_r, &cpu_r);
	if (ret)
		return ret;

	ret = bch2_cpu_replicas_validate(&cpu_r, sb, err);
	kfree(cpu_r.entries);
	return ret;
}

static void bch2_sb_replicas_v0_to_text(struct printbuf *out,
					struct bch_sb *sb,
					struct bch_sb_field *f)
{
	struct bch_sb_field_replicas_v0 *sb_r = field_to_type(f, replicas_v0);
	struct bch_replicas_entry_v0 *e;
	bool first = true;

	for_each_replicas_entry(sb_r, e) {
		if (!first)
			prt_printf(out, " ");
		first = false;

		bch2_replicas_entry_v0_to_text(out, e);
	}
	prt_newline(out);
}

const struct bch_sb_field_ops bch_sb_field_ops_replicas_v0 = {
	.validate	= bch2_sb_replicas_v0_validate,
	.to_text	= bch2_sb_replicas_v0_to_text,
};

/* Query replicas: */

bool bch2_have_enough_devs(struct bch_fs *c, struct bch_devs_mask devs,
			   unsigned flags, bool print)
{
	struct bch_replicas_entry_v1 *e;
	bool ret = true;

	percpu_down_read(&c->mark_lock);
	for_each_cpu_replicas_entry(&c->replicas, e) {
		unsigned nr_online = 0, nr_failed = 0, dflags = 0;
		bool metadata = e->data_type < BCH_DATA_user;

		if (e->data_type == BCH_DATA_cached)
			continue;

		rcu_read_lock();
		for (unsigned i = 0; i < e->nr_devs; i++) {
			if (e->devs[i] == BCH_SB_MEMBER_INVALID) {
				nr_failed++;
				continue;
			}

			nr_online += test_bit(e->devs[i], devs.d);

			struct bch_dev *ca = bch2_dev_rcu_noerror(c, e->devs[i]);
			nr_failed += !ca || ca->mi.state == BCH_MEMBER_STATE_failed;
		}
		rcu_read_unlock();

		if (nr_online + nr_failed == e->nr_devs)
			continue;

		if (nr_online < e->nr_required)
			dflags |= metadata
				? BCH_FORCE_IF_METADATA_LOST
				: BCH_FORCE_IF_DATA_LOST;

		if (nr_online < e->nr_devs)
			dflags |= metadata
				? BCH_FORCE_IF_METADATA_DEGRADED
				: BCH_FORCE_IF_DATA_DEGRADED;

		if (dflags & ~flags) {
			if (print) {
				struct printbuf buf = PRINTBUF;

				bch2_replicas_entry_to_text(&buf, e);
				bch_err(c, "insufficient devices online (%u) for replicas entry %s",
					nr_online, buf.buf);
				printbuf_exit(&buf);
			}
			ret = false;
			break;
		}

	}
	percpu_up_read(&c->mark_lock);

	return ret;
}

unsigned bch2_sb_dev_has_data(struct bch_sb *sb, unsigned dev)
{
	struct bch_sb_field_replicas *replicas;
	struct bch_sb_field_replicas_v0 *replicas_v0;
	unsigned data_has = 0;

	replicas = bch2_sb_field_get(sb, replicas);
	replicas_v0 = bch2_sb_field_get(sb, replicas_v0);

	if (replicas) {
		struct bch_replicas_entry_v1 *r;

		for_each_replicas_entry(replicas, r) {
			if (r->data_type >= sizeof(data_has) * 8)
				continue;

			for (unsigned i = 0; i < r->nr_devs; i++)
				if (r->devs[i] == dev)
					data_has |= 1 << r->data_type;
		}

	} else if (replicas_v0) {
		struct bch_replicas_entry_v0 *r;

		for_each_replicas_entry_v0(replicas_v0, r) {
			if (r->data_type >= sizeof(data_has) * 8)
				continue;

			for (unsigned i = 0; i < r->nr_devs; i++)
				if (r->devs[i] == dev)
					data_has |= 1 << r->data_type;
		}
	}


	return data_has;
}

unsigned bch2_dev_has_data(struct bch_fs *c, struct bch_dev *ca)
{
	mutex_lock(&c->sb_lock);
	unsigned ret = bch2_sb_dev_has_data(c->disk_sb.sb, ca->dev_idx);
	mutex_unlock(&c->sb_lock);

	return ret;
}

void bch2_fs_replicas_exit(struct bch_fs *c)
{
	kfree(c->replicas.entries);
	kfree(c->replicas_gc.entries);
}
