]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/buckets_waiting_for_journal.c
Move c_src dirs back to toplevel
[bcachefs-tools-debian] / libbcachefs / buckets_waiting_for_journal.c
index 0f4ef9e5a431f4f84e80a347196a03f7d71a8946..ec1b636ef78d075d1c2b6a9dd2b610a5ba8f274c 100644 (file)
@@ -2,28 +2,24 @@
 
 #include "bcachefs.h"
 #include "buckets_waiting_for_journal.h"
+#include <linux/hash.h>
 #include <linux/random.h>
-#include <linux/siphash.h>
 
 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;
 }