Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Christoph Hellwig and committed by
Ben Myers
bc02e869 1813dd64

+78
+1
fs/xfs/Kconfig
··· 2 2 tristate "XFS filesystem support" 3 3 depends on BLOCK 4 4 select EXPORTFS 5 + select LIBCRC32C 5 6 help 6 7 XFS is a high performance journaling filesystem which originated 7 8 on the SGI IRIX platform. It is completely multi-threaded, can
+6
fs/xfs/uuid.h
··· 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__ */
+63
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 */
+1
fs/xfs/xfs_linux.h
··· 44 44 #include <linux/kernel.h> 45 45 #include <linux/blkdev.h> 46 46 #include <linux/slab.h> 47 + #include <linux/crc32c.h> 47 48 #include <linux/module.h> 48 49 #include <linux/mutex.h> 49 50 #include <linux/file.h>
+7
fs/xfs/xfs_sb.h
··· 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 | \ ··· 502 501 { 503 502 return xfs_sb_version_hasmorebits(sbp) && 504 503 (sbp->sb_features2 & XFS_SB_VERSION2_PROJID32BIT); 504 + } 505 + 506 + static inline int xfs_sb_version_hascrc(xfs_sb_t *sbp) 507 + { 508 + return (xfs_sb_version_hasmorebits(sbp) && 509 + (sbp->sb_features2 & XFS_SB_VERSION2_CRCBIT)); 505 510 } 506 511 507 512 /*