Skip to content

Commit 5f7c79b

Browse files
yangdongshengkawasaki
authored andcommitted
dm-pcache: add pcache_internal.h
Consolidate common PCACHE helpers into a new header so that subsequent patches can include them without repeating boiler-plate. - Logging macros with unified prefix and location info. - Common constants (KB/MB helpers, metadata replica count, CRC seed). - On-disk metadata header definition and CRC helper. - Sequence-number comparison that handles wrap-around. - pcache_meta_find_latest() to pick the newest valid metadata copy. Signed-off-by: Dongsheng Yang <[email protected]>
1 parent e311dd9 commit 5f7c79b

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
#ifndef _PCACHE_INTERNAL_H
3+
#define _PCACHE_INTERNAL_H
4+
5+
#include <linux/delay.h>
6+
#include <linux/crc32c.h>
7+
8+
#define pcache_err(fmt, ...) \
9+
pr_err("dm-pcache: %s:%u " fmt, __func__, __LINE__, ##__VA_ARGS__)
10+
#define pcache_info(fmt, ...) \
11+
pr_info("dm-pcache: %s:%u " fmt, __func__, __LINE__, ##__VA_ARGS__)
12+
#define pcache_debug(fmt, ...) \
13+
pr_debug("dm-pcache: %s:%u " fmt, __func__, __LINE__, ##__VA_ARGS__)
14+
15+
#define PCACHE_KB (1024ULL)
16+
#define PCACHE_MB (1024 * PCACHE_KB)
17+
18+
/* Maximum number of metadata indices */
19+
#define PCACHE_META_INDEX_MAX 2
20+
21+
#define PCACHE_CRC_SEED 0x3B15A
22+
/*
23+
* struct pcache_meta_header - PCACHE metadata header structure
24+
* @crc: CRC checksum for validating metadata integrity.
25+
* @seq: Sequence number to track metadata updates.
26+
* @version: Metadata version.
27+
* @res: Reserved space for future use.
28+
*/
29+
struct pcache_meta_header {
30+
__u32 crc;
31+
__u8 seq;
32+
__u8 version;
33+
__u16 res;
34+
};
35+
36+
/*
37+
* pcache_meta_crc - Calculate CRC for the given metadata header.
38+
* @header: Pointer to the metadata header.
39+
* @meta_size: Size of the metadata structure.
40+
*
41+
* Returns the CRC checksum calculated by excluding the CRC field itself.
42+
*/
43+
static inline u32 pcache_meta_crc(struct pcache_meta_header *header, u32 meta_size)
44+
{
45+
return crc32c(PCACHE_CRC_SEED, (void *)header + 4, meta_size - 4);
46+
}
47+
48+
/*
49+
* pcache_meta_seq_after - Check if a sequence number is more recent, accounting for overflow.
50+
* @seq1: First sequence number.
51+
* @seq2: Second sequence number.
52+
*
53+
* Determines if @seq1 is more recent than @seq2 by calculating the signed
54+
* difference between them. This approach allows handling sequence number
55+
* overflow correctly because the difference wraps naturally, and any value
56+
* greater than zero indicates that @seq1 is "after" @seq2. This method
57+
* assumes 8-bit unsigned sequence numbers, where the difference wraps
58+
* around if seq1 overflows past seq2.
59+
*
60+
* Returns:
61+
* - true if @seq1 is more recent than @seq2, indicating it comes "after"
62+
* - false otherwise.
63+
*/
64+
static inline bool pcache_meta_seq_after(u8 seq1, u8 seq2)
65+
{
66+
return (s8)(seq1 - seq2) > 0;
67+
}
68+
69+
/*
70+
* pcache_meta_find_latest - Find the latest valid metadata.
71+
* @header: Pointer to the metadata header.
72+
* @meta_size: Size of each metadata block.
73+
*
74+
* Finds the latest valid metadata by checking sequence numbers. If a
75+
* valid entry with the highest sequence number is found, its pointer
76+
* is returned. Returns NULL if no valid metadata is found.
77+
*/
78+
static inline void __must_check *pcache_meta_find_latest(struct pcache_meta_header *header,
79+
u32 meta_size, u32 meta_max_size,
80+
void *meta_ret)
81+
{
82+
struct pcache_meta_header *meta, *latest = NULL;
83+
u32 i, seq_latest = 0;
84+
void *meta_addr;
85+
86+
meta = meta_ret;
87+
88+
for (i = 0; i < PCACHE_META_INDEX_MAX; i++) {
89+
meta_addr = (void *)header + (i * meta_max_size);
90+
if (copy_mc_to_kernel(meta, meta_addr, meta_size)) {
91+
pcache_err("hardware memory error when copy meta");
92+
return ERR_PTR(-EIO);
93+
}
94+
95+
/* Skip if CRC check fails, which means corrupted */
96+
if (meta->crc != pcache_meta_crc(meta, meta_size))
97+
continue;
98+
99+
/* Update latest if a more recent sequence is found */
100+
if (!latest || pcache_meta_seq_after(meta->seq, seq_latest)) {
101+
seq_latest = meta->seq;
102+
latest = (void *)header + (i * meta_max_size);
103+
}
104+
}
105+
106+
if (!latest)
107+
return NULL;
108+
109+
if (copy_mc_to_kernel(meta_ret, latest, meta_size)) {
110+
pcache_err("hardware memory error");
111+
return ERR_PTR(-EIO);
112+
}
113+
114+
return latest;
115+
}
116+
117+
#endif /* _PCACHE_INTERNAL_H */

0 commit comments

Comments
 (0)