xref: /linux/drivers/md/dm-vdo/indexer/hash-utils.h (revision 79790b6818e96c58fe2bffee1b418c16e64e7b80)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright 2023 Red Hat
4  */
5 
6 #ifndef UDS_HASH_UTILS_H
7 #define UDS_HASH_UTILS_H
8 
9 #include "numeric.h"
10 
11 #include "geometry.h"
12 #include "indexer.h"
13 
14 /* Utilities for extracting portions of a request name for various uses. */
15 
16 /* How various portions of a record name are apportioned. */
17 enum {
18 	VOLUME_INDEX_BYTES_OFFSET = 0,
19 	VOLUME_INDEX_BYTES_COUNT = 8,
20 	CHAPTER_INDEX_BYTES_OFFSET = 8,
21 	CHAPTER_INDEX_BYTES_COUNT = 6,
22 	SAMPLE_BYTES_OFFSET = 14,
23 	SAMPLE_BYTES_COUNT = 2,
24 };
25 
uds_extract_chapter_index_bytes(const struct uds_record_name * name)26 static inline u64 uds_extract_chapter_index_bytes(const struct uds_record_name *name)
27 {
28 	const u8 *chapter_bits = &name->name[CHAPTER_INDEX_BYTES_OFFSET];
29 	u64 bytes = (u64) get_unaligned_be16(chapter_bits) << 32;
30 
31 	bytes |= get_unaligned_be32(chapter_bits + 2);
32 	return bytes;
33 }
34 
uds_extract_volume_index_bytes(const struct uds_record_name * name)35 static inline u64 uds_extract_volume_index_bytes(const struct uds_record_name *name)
36 {
37 	return get_unaligned_be64(&name->name[VOLUME_INDEX_BYTES_OFFSET]);
38 }
39 
uds_extract_sampling_bytes(const struct uds_record_name * name)40 static inline u32 uds_extract_sampling_bytes(const struct uds_record_name *name)
41 {
42 	return get_unaligned_be16(&name->name[SAMPLE_BYTES_OFFSET]);
43 }
44 
45 /* Compute the chapter delta list for a given name. */
uds_hash_to_chapter_delta_list(const struct uds_record_name * name,const struct index_geometry * geometry)46 static inline u32 uds_hash_to_chapter_delta_list(const struct uds_record_name *name,
47 						 const struct index_geometry *geometry)
48 {
49 	return ((uds_extract_chapter_index_bytes(name) >> geometry->chapter_address_bits) &
50 		((1 << geometry->chapter_delta_list_bits) - 1));
51 }
52 
53 /* Compute the chapter delta address for a given name. */
uds_hash_to_chapter_delta_address(const struct uds_record_name * name,const struct index_geometry * geometry)54 static inline u32 uds_hash_to_chapter_delta_address(const struct uds_record_name *name,
55 						    const struct index_geometry *geometry)
56 {
57 	return uds_extract_chapter_index_bytes(name) & ((1 << geometry->chapter_address_bits) - 1);
58 }
59 
uds_name_to_hash_slot(const struct uds_record_name * name,unsigned int slot_count)60 static inline unsigned int uds_name_to_hash_slot(const struct uds_record_name *name,
61 						 unsigned int slot_count)
62 {
63 	return (unsigned int) (uds_extract_chapter_index_bytes(name) % slot_count);
64 }
65 
66 #endif /* UDS_HASH_UTILS_H */
67