// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "buckets_waiting_for_journal.h"
#include <linux/hash.h>
#include <linux/random.h>

static inline struct bucket_hashed *
bucket_hash(struct buckets_waiting_for_journal_table *t,
	    unsigned hash_seed_idx, u64 dev_bucket)
{
	return t->d + hash_64(dev_bucket ^ t->hash_seeds[hash_seed_idx], t->bits);
}

static void bucket_table_init(struct buckets_waiting_for_journal_table *t, size_t bits)
{
	unsigned i;

	t->bits = bits;
	for (i = 0; i < ARRAY_SIZE(t->hash_seeds); i++)
		get_random_bytes(&t->hash_seeds[i], sizeof(t->hash_seeds[i]));
	memset(t->d, 0, sizeof(t->d[0]) << t->bits);
}

bool bch2_bucket_needs_journal_commit(struct buckets_waiting_for_journal *b,
				      u64 flushed_seq,
				      unsigned dev, u64 bucket)
{
	struct buckets_waiting_for_journal_table *t;
	u64 dev_bucket = (u64) dev << 56 | bucket;
	bool ret = false;
	unsigned i;

	mutex_lock(&b->lock);
	t = b->t;

	for (i = 0; i < ARRAY_SIZE(t->hash_seeds); i++) {
		struct bucket_hashed *h = bucket_hash(t, i, dev_bucket);

		if (h->dev_bucket == dev_bucket) {
			ret = h->journal_seq > flushed_seq;
			break;
		}
	}

	mutex_unlock(&b->lock);

	return ret;
}

static bool bucket_table_insert(struct buckets_waiting_for_journal_table *t,
				struct bucket_hashed *new,
				u64 flushed_seq)
{
	struct bucket_hashed *last_evicted = NULL;
	unsigned tries, i;

	for (tries = 0; tries < 10; tries++) {
		struct bucket_hashed *old, *victim = NULL;

		for (i = 0; i < ARRAY_SIZE(t->hash_seeds); i++) {
			old = bucket_hash(t, i, new->dev_bucket);

			if (old->dev_bucket == new->dev_bucket ||
			    old->journal_seq <= flushed_seq) {
				*old = *new;
				return true;
			}

			if (last_evicted != old)
				victim = old;
		}

		/* hashed to same slot 3 times: */
		if (!victim)
			break;

		/* Failed to find an empty slot: */
		swap(*new, *victim);
		last_evicted = victim;
	}

	return false;
}

int bch2_set_bucket_needs_journal_commit(struct buckets_waiting_for_journal *b,
					 u64 flushed_seq,
					 unsigned dev, u64 bucket,
					 u64 journal_seq)
{
	struct buckets_waiting_for_journal_table *t, *n;
	struct bucket_hashed tmp, new = {
		.dev_bucket	= (u64) dev << 56 | bucket,
		.journal_seq	= journal_seq,
	};
	size_t i, size, new_bits, nr_elements = 1, nr_rehashes = 0;
	int ret = 0;

	mutex_lock(&b->lock);

	if (likely(bucket_table_insert(b->t, &new, flushed_seq)))
		goto out;

	t = b->t;
	size = 1UL << t->bits;
	for (i = 0; i < size; i++)
		nr_elements += t->d[i].journal_seq > flushed_seq;

	new_bits = t->bits + (nr_elements * 3 > size);

	n = kvmalloc(sizeof(*n) + (sizeof(n->d[0]) << new_bits), GFP_KERNEL);
	if (!n) {
		ret = -BCH_ERR_ENOMEM_buckets_waiting_for_journal_set;
		goto out;
	}

retry_rehash:
	nr_rehashes++;
	bucket_table_init(n, new_bits);

	tmp = new;
	BUG_ON(!bucket_table_insert(n, &tmp, flushed_seq));

	for (i = 0; i < 1UL << t->bits; i++) {
		if (t->d[i].journal_seq <= flushed_seq)
			continue;

		tmp = t->d[i];
		if (!bucket_table_insert(n, &tmp, flushed_seq))
			goto retry_rehash;
	}

	b->t = n;
	kvfree(t);

	pr_debug("took %zu rehashes, table at %zu/%lu elements",
		 nr_rehashes, nr_elements, 1UL << b->t->bits);
out:
	mutex_unlock(&b->lock);

	return ret;
}

void bch2_fs_buckets_waiting_for_journal_exit(struct bch_fs *c)
{
	struct buckets_waiting_for_journal *b = &c->buckets_waiting_for_journal;

	kvfree(b->t);
}

#define INITIAL_TABLE_BITS		3

int bch2_fs_buckets_waiting_for_journal_init(struct bch_fs *c)
{
	struct buckets_waiting_for_journal *b = &c->buckets_waiting_for_journal;

	mutex_init(&b->lock);

	b->t = kvmalloc(sizeof(*b->t) +
			(sizeof(b->t->d[0]) << INITIAL_TABLE_BITS), GFP_KERNEL);
	if (!b->t)
		return -BCH_ERR_ENOMEM_buckets_waiting_for_journal_init;

	bucket_table_init(b->t, INITIAL_TABLE_BITS);
	return 0;
}
