bcachefs: Don't use sha256 for siphash str hash key
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 4 Oct 2019 19:58:43 +0000 (15:58 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:28 +0000 (17:08 -0400)
With the refactoring that's coming to add fuse support, we want
bch2_hash_info_init() to be cheaper so we don't have to rely on anything
cached besides the inode in the btree.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs_format.h
fs/bcachefs/inode.c
fs/bcachefs/opts.h
fs/bcachefs/str_hash.h

index 4bc3f8d3e7f4710ad03724e13ceb3c8879a4a445..eb6d712e78448b499228338451cdce55a7f26093 100644 (file)
@@ -1318,6 +1318,7 @@ enum bch_sb_features {
        BCH_FEATURE_EC                  = 4,
        BCH_FEATURE_JOURNAL_SEQ_BLACKLIST_V3 = 5,
        BCH_FEATURE_REFLINK             = 6,
+       BCH_FEATURE_NEW_SIPHASH         = 7,
        BCH_FEATURE_NR,
 };
 
@@ -1344,11 +1345,19 @@ enum bch_csum_opts {
        BCH_CSUM_OPT_NR                 = 3,
 };
 
-enum bch_str_hash_opts {
+enum bch_str_hash_type {
        BCH_STR_HASH_CRC32C             = 0,
        BCH_STR_HASH_CRC64              = 1,
-       BCH_STR_HASH_SIPHASH            = 2,
-       BCH_STR_HASH_NR                 = 3,
+       BCH_STR_HASH_SIPHASH_OLD        = 2,
+       BCH_STR_HASH_SIPHASH            = 3,
+       BCH_STR_HASH_NR                 = 4,
+};
+
+enum bch_str_hash_opts {
+       BCH_STR_HASH_OPT_CRC32C         = 0,
+       BCH_STR_HASH_OPT_CRC64          = 1,
+       BCH_STR_HASH_OPT_SIPHASH        = 2,
+       BCH_STR_HASH_OPT_NR             = 3,
 };
 
 #define BCH_COMPRESSION_TYPES()                \
index fc38cfb9e939e478448b40ca32118dbcdbdf4b51..3dc46faaebbcf72492b33726f0068837db91e15f 100644 (file)
@@ -6,8 +6,7 @@
 #include "error.h"
 #include "extents.h"
 #include "inode.h"
-#include "io.h"
-#include "keylist.h"
+#include "str_hash.h"
 
 #include <linux/random.h>
 
@@ -303,11 +302,13 @@ void bch2_inode_init(struct bch_fs *c, struct bch_inode_unpacked *inode_u,
                     struct bch_inode_unpacked *parent)
 {
        s64 now = bch2_current_time(c);
+       enum bch_str_hash_type str_hash =
+               bch2_str_hash_opt_to_type(c, c->opts.str_hash);
 
        memset(inode_u, 0, sizeof(*inode_u));
 
        /* ick */
-       inode_u->bi_flags |= c->opts.str_hash << INODE_STR_HASH_OFFSET;
+       inode_u->bi_flags |= str_hash << INODE_STR_HASH_OFFSET;
        get_random_bytes(&inode_u->bi_hash_seed,
                         sizeof(inode_u->bi_hash_seed));
 
index d9325d4bc02441228f38732710fc3b27c4ebce3a..a6f1d3ec7b9012a5d483e20f5fb0fc682a7d2aa9 100644 (file)
@@ -127,7 +127,7 @@ enum opt_type {
        x(str_hash,                     u8,                             \
          OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME,                             \
          OPT_STR(bch2_str_hash_types),                                 \
-         BCH_SB_STR_HASH_TYPE,         BCH_STR_HASH_SIPHASH,           \
+         BCH_SB_STR_HASH_TYPE,         BCH_STR_HASH_OPT_SIPHASH,       \
          NULL,         "Hash function for directory entries and xattrs")\
        x(foreground_target,            u16,                            \
          OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME|OPT_INODE,                   \
index a81fc3596fc1016bea0dbde95fae9243bd857729..7be4a8e50eaaac513f62697f46db12889b7d7767 100644 (file)
 #include <crypto/hash.h>
 #include <crypto/sha2.h>
 
+static inline enum bch_str_hash_type
+bch2_str_hash_opt_to_type(struct bch_fs *c, enum bch_str_hash_opts opt)
+{
+       switch (opt) {
+       case BCH_STR_HASH_OPT_CRC32C:
+               return BCH_STR_HASH_CRC32C;
+       case BCH_STR_HASH_OPT_CRC64:
+               return BCH_STR_HASH_CRC64;
+       case BCH_STR_HASH_OPT_SIPHASH:
+               return c->sb.features & (1ULL << BCH_FEATURE_NEW_SIPHASH)
+                       ? BCH_STR_HASH_SIPHASH
+                       : BCH_STR_HASH_SIPHASH_OLD;
+       default:
+            BUG();
+       }
+}
+
 struct bch_hash_info {
        u8                      type;
        union {
@@ -23,21 +40,16 @@ struct bch_hash_info {
 };
 
 static inline struct bch_hash_info
-bch2_hash_info_init(struct bch_fs *c,
-                  const struct bch_inode_unpacked *bi)
+bch2_hash_info_init(struct bch_fs *c, const struct bch_inode_unpacked *bi)
 {
        /* XXX ick */
        struct bch_hash_info info = {
                .type = (bi->bi_flags >> INODE_STR_HASH_OFFSET) &
-                       ~(~0U << INODE_STR_HASH_BITS)
+                       ~(~0U << INODE_STR_HASH_BITS),
+               .crc_key = bi->bi_hash_seed,
        };
 
-       switch (info.type) {
-       case BCH_STR_HASH_CRC32C:
-       case BCH_STR_HASH_CRC64:
-               info.crc_key = bi->bi_hash_seed;
-               break;
-       case BCH_STR_HASH_SIPHASH: {
+       if (unlikely(info.type == BCH_STR_HASH_SIPHASH_OLD)) {
                SHASH_DESC_ON_STACK(desc, c->sha256);
                u8 digest[SHA256_DIGEST_SIZE];
 
@@ -46,10 +58,6 @@ bch2_hash_info_init(struct bch_fs *c,
                crypto_shash_digest(desc, (void *) &bi->bi_hash_seed,
                                    sizeof(bi->bi_hash_seed), digest);
                memcpy(&info.siphash_key, digest, sizeof(info.siphash_key));
-               break;
-       }
-       default:
-               BUG();
        }
 
        return info;
@@ -73,6 +81,7 @@ static inline void bch2_str_hash_init(struct bch_str_hash_ctx *ctx,
        case BCH_STR_HASH_CRC64:
                ctx->crc64 = crc64_be(~0, &info->crc_key, sizeof(info->crc_key));
                break;
+       case BCH_STR_HASH_SIPHASH_OLD:
        case BCH_STR_HASH_SIPHASH:
                SipHash24_Init(&ctx->siphash, &info->siphash_key);
                break;
@@ -92,6 +101,7 @@ static inline void bch2_str_hash_update(struct bch_str_hash_ctx *ctx,
        case BCH_STR_HASH_CRC64:
                ctx->crc64 = crc64_be(ctx->crc64, data, len);
                break;
+       case BCH_STR_HASH_SIPHASH_OLD:
        case BCH_STR_HASH_SIPHASH:
                SipHash24_Update(&ctx->siphash, data, len);
                break;
@@ -108,6 +118,7 @@ static inline u64 bch2_str_hash_end(struct bch_str_hash_ctx *ctx,
                return ctx->crc32c;
        case BCH_STR_HASH_CRC64:
                return ctx->crc64 >> 1;
+       case BCH_STR_HASH_SIPHASH_OLD:
        case BCH_STR_HASH_SIPHASH:
                return SipHash24_End(&ctx->siphash) >> 1;
        default: