Commit bc02e8693d875c2a9b0037cfd37fe0b726d26403
Committed by
Ben Myers
1 parent
1813dd6405
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
xfs: add CRC infrastructure
- add a mount feature bit for CRC enabled filesystems - add some helpers for generating and verifying the CRCs - add a copy_uuid helper The checksumming helpers are loosely based on similar ones in sctp, all other bits come from Dave Chinner. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Showing 5 changed files with 78 additions and 0 deletions Side-by-side Diff
fs/xfs/Kconfig
fs/xfs/uuid.h
... | ... | @@ -26,5 +26,11 @@ |
26 | 26 | extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2); |
27 | 27 | extern void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]); |
28 | 28 | |
29 | +static inline void | |
30 | +uuid_copy(uuid_t *dst, uuid_t *src) | |
31 | +{ | |
32 | + memcpy(dst, src, sizeof(uuid_t)); | |
33 | +} | |
34 | + | |
29 | 35 | #endif /* __XFS_SUPPORT_UUID_H__ */ |
fs/xfs/xfs_cksum.h
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 */ |
fs/xfs/xfs_linux.h
fs/xfs/xfs_sb.h
... | ... | @@ -81,6 +81,7 @@ |
81 | 81 | #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ |
82 | 82 | #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ |
83 | 83 | #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */ |
84 | +#define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */ | |
84 | 85 | |
85 | 86 | #define XFS_SB_VERSION2_OKREALFBITS \ |
86 | 87 | (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ |
... | ... | @@ -501,6 +502,12 @@ |
501 | 502 | { |
502 | 503 | return xfs_sb_version_hasmorebits(sbp) && |
503 | 504 | (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT); |
505 | +} | |
506 | + | |
507 | +static inline int xfs_sb_version_hascrc(xfs_sb_t *sbp) | |
508 | +{ | |
509 | + return (xfs_sb_version_hasmorebits(sbp) && | |
510 | + (sbp->sb_features2 & XFS_SB_VERSION2_CRCBIT)); | |
504 | 511 | } |
505 | 512 | |
506 | 513 | /* |