]>
Commit | Line | Data |
---|---|---|
bc02e869 CH |
1 | #ifndef _XFS_CKSUM_H |
2 | #define _XFS_CKSUM_H 1 | |
3 | ||
4 | #define XFS_CRC_SEED (~(__uint32_t)0) | |
5 | ||
6 | /* | |
7 | * Calculate the intermediate checksum for a buffer that has the CRC field | |
8 | * inside it. The offset of the 32bit crc fields is passed as the | |
9 | * cksum_offset parameter. | |
10 | */ | |
11 | static inline __uint32_t | |
12 | xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset) | |
13 | { | |
14 | __uint32_t zero = 0; | |
15 | __uint32_t crc; | |
16 | ||
17 | /* Calculate CRC up to the checksum. */ | |
18 | crc = crc32c(XFS_CRC_SEED, buffer, cksum_offset); | |
19 | ||
20 | /* Skip checksum field */ | |
21 | crc = crc32c(crc, &zero, sizeof(__u32)); | |
22 | ||
23 | /* Calculate the rest of the CRC. */ | |
24 | return crc32c(crc, &buffer[cksum_offset + sizeof(__be32)], | |
25 | length - (cksum_offset + sizeof(__be32))); | |
26 | } | |
27 | ||
28 | /* | |
29 | * Convert the intermediate checksum to the final ondisk format. | |
30 | * | |
31 | * The CRC32c calculation uses LE format even on BE machines, but returns the | |
32 | * result in host endian format. Hence we need to byte swap it back to LE format | |
33 | * so that it is consistent on disk. | |
34 | */ | |
35 | static inline __le32 | |
36 | xfs_end_cksum(__uint32_t crc) | |
37 | { | |
38 | return ~cpu_to_le32(crc); | |
39 | } | |
40 | ||
41 | /* | |
42 | * Helper to generate the checksum for a buffer. | |
43 | */ | |
44 | static inline void | |
45 | xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset) | |
46 | { | |
47 | __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset); | |
48 | ||
49 | *(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc); | |
50 | } | |
51 | ||
52 | /* | |
53 | * Helper to verify the checksum for a buffer. | |
54 | */ | |
55 | static inline int | |
56 | xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset) | |
57 | { | |
58 | __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset); | |
59 | ||
60 | return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc); | |
61 | } | |
62 | ||
63 | #endif /* _XFS_CKSUM_H */ |