X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fbuckets_waiting_for_journal.c;h=ec1b636ef78d075d1c2b6a9dd2b610a5ba8f274c;hb=b90031efaa4500b8ce5ffc55e9d1ed716196b814;hp=0f4ef9e5a431f4f84e80a347196a03f7d71a8946;hpb=c1f55a60c41ca5ab8ed7a0893c3d29f8006da82a;p=bcachefs-tools-debian diff --git a/libbcachefs/buckets_waiting_for_journal.c b/libbcachefs/buckets_waiting_for_journal.c index 0f4ef9e..ec1b636 100644 --- a/libbcachefs/buckets_waiting_for_journal.c +++ b/libbcachefs/buckets_waiting_for_journal.c @@ -2,28 +2,24 @@ #include "bcachefs.h" #include "buckets_waiting_for_journal.h" +#include #include -#include static inline struct bucket_hashed * bucket_hash(struct buckets_waiting_for_journal_table *t, unsigned hash_seed_idx, u64 dev_bucket) { - unsigned h = siphash_1u64(dev_bucket, &t->hash_seeds[hash_seed_idx]); - - EBUG_ON(!is_power_of_2(t->size)); - - return t->d + (h & (t->size - 1)); + 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 size) +static void bucket_table_init(struct buckets_waiting_for_journal_table *t, size_t bits) { unsigned i; - t->size = size; + 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]) * size); + memset(t->d, 0, sizeof(t->d[0]) << t->bits); } bool bch2_bucket_needs_journal_commit(struct buckets_waiting_for_journal *b, @@ -97,7 +93,7 @@ int bch2_set_bucket_needs_journal_commit(struct buckets_waiting_for_journal *b, .dev_bucket = (u64) dev << 56 | bucket, .journal_seq = journal_seq, }; - size_t i, new_size, nr_elements = 1, nr_rehashes = 0; + size_t i, size, new_bits, nr_elements = 1, nr_rehashes = 0; int ret = 0; mutex_lock(&b->lock); @@ -106,25 +102,26 @@ int bch2_set_bucket_needs_journal_commit(struct buckets_waiting_for_journal *b, goto out; t = b->t; - for (i = 0; i < t->size; i++) + size = 1UL << t->bits; + for (i = 0; i < size; i++) nr_elements += t->d[i].journal_seq > flushed_seq; - new_size = nr_elements < t->size / 3 ? t->size : t->size * 2; + new_bits = t->bits + (nr_elements * 3 > size); - n = kvmalloc(sizeof(*n) + sizeof(n->d[0]) * new_size, GFP_KERNEL); + n = kvmalloc(sizeof(*n) + (sizeof(n->d[0]) << new_bits), GFP_KERNEL); if (!n) { - ret = -ENOMEM; + ret = -BCH_ERR_ENOMEM_buckets_waiting_for_journal_set; goto out; } retry_rehash: nr_rehashes++; - bucket_table_init(n, new_size); + bucket_table_init(n, new_bits); tmp = new; BUG_ON(!bucket_table_insert(n, &tmp, flushed_seq)); - for (i = 0; i < t->size; i++) { + for (i = 0; i < 1UL << t->bits; i++) { if (t->d[i].journal_seq <= flushed_seq) continue; @@ -136,8 +133,8 @@ retry_rehash: b->t = n; kvfree(t); - pr_debug("took %zu rehashes, table at %zu/%zu elements", - nr_rehashes, nr_elements, b->t->size); + pr_debug("took %zu rehashes, table at %zu/%lu elements", + nr_rehashes, nr_elements, 1UL << b->t->bits); out: mutex_unlock(&b->lock); @@ -151,7 +148,7 @@ void bch2_fs_buckets_waiting_for_journal_exit(struct bch_fs *c) kvfree(b->t); } -#define INITIAL_TABLE_SIZE 8 +#define INITIAL_TABLE_BITS 3 int bch2_fs_buckets_waiting_for_journal_init(struct bch_fs *c) { @@ -159,10 +156,11 @@ int bch2_fs_buckets_waiting_for_journal_init(struct bch_fs *c) mutex_init(&b->lock); - b->t = kvmalloc(sizeof(*b->t) + sizeof(b->t->d[0]) * INITIAL_TABLE_SIZE, GFP_KERNEL); + b->t = kvmalloc(sizeof(*b->t) + + (sizeof(b->t->d[0]) << INITIAL_TABLE_BITS), GFP_KERNEL); if (!b->t) - return -ENOMEM; + return -BCH_ERR_ENOMEM_buckets_waiting_for_journal_init; - bucket_table_init(b->t, INITIAL_TABLE_SIZE); + bucket_table_init(b->t, INITIAL_TABLE_BITS); return 0; }