BCH_FEATURE_EC = 4,
BCH_FEATURE_JOURNAL_SEQ_BLACKLIST_V3 = 5,
BCH_FEATURE_REFLINK = 6,
+ BCH_FEATURE_NEW_SIPHASH = 7,
BCH_FEATURE_NR,
};
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() \
#include "error.h"
#include "extents.h"
#include "inode.h"
-#include "io.h"
-#include "keylist.h"
+#include "str_hash.h"
#include <linux/random.h>
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));
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, \
#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 {
};
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];
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;
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;
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;
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: