LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_cksum.h (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwa @ Mon Jul 31 20:08:17 PDT 2023 Lines: 17 17 100.0 %
Date: 2023-07-31 20:08:17 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : #ifndef _XFS_CKSUM_H
       3             : #define _XFS_CKSUM_H 1
       4             : 
       5             : #define XFS_CRC_SEED    (~(uint32_t)0)
       6             : 
       7             : /*
       8             :  * Calculate the intermediate checksum for a buffer that has the CRC field
       9             :  * inside it.  The offset of the 32bit crc fields is passed as the
      10             :  * cksum_offset parameter. We do not modify the buffer during verification,
      11             :  * hence we have to split the CRC calculation across the cksum_offset.
      12             :  */
      13             : static inline uint32_t
      14   536208236 : xfs_start_cksum_safe(char *buffer, size_t length, unsigned long cksum_offset)
      15             : {
      16   536208236 :         uint32_t zero = 0;
      17   536208236 :         uint32_t crc;
      18             : 
      19             :         /* Calculate CRC up to the checksum. */
      20   536208236 :         crc = crc32c(XFS_CRC_SEED, buffer, cksum_offset);
      21             : 
      22             :         /* Skip checksum field */
      23   536205107 :         crc = crc32c(crc, &zero, sizeof(__u32));
      24             : 
      25             :         /* Calculate the rest of the CRC. */
      26  1072418843 :         return crc32c(crc, &buffer[cksum_offset + sizeof(__be32)],
      27   536211272 :                       length - (cksum_offset + sizeof(__be32)));
      28             : }
      29             : 
      30             : /*
      31             :  * Fast CRC method where the buffer is modified. Callers must have exclusive
      32             :  * access to the buffer while the calculation takes place.
      33             :  */
      34             : static inline uint32_t
      35             : xfs_start_cksum_update(char *buffer, size_t length, unsigned long cksum_offset)
      36             : {
      37             :         /* zero the CRC field */
      38   280759017 :         *(__le32 *)(buffer + cksum_offset) = 0;
      39             : 
      40             :         /* single pass CRC calculation for the entire buffer */
      41   280759017 :         return crc32c(XFS_CRC_SEED, buffer, length);
      42             : }
      43             : 
      44             : /*
      45             :  * Convert the intermediate checksum to the final ondisk format.
      46             :  *
      47             :  * The CRC32c calculation uses LE format even on BE machines, but returns the
      48             :  * result in host endian format. Hence we need to byte swap it back to LE format
      49             :  * so that it is consistent on disk.
      50             :  */
      51             : static inline __le32
      52             : xfs_end_cksum(uint32_t crc)
      53             : {
      54   459872787 :         return ~cpu_to_le32(crc);
      55             : }
      56             : 
      57             : /*
      58             :  * Helper to generate the checksum for a buffer.
      59             :  *
      60             :  * This modifies the buffer temporarily - callers must have exclusive
      61             :  * access to the buffer while the calculation takes place.
      62             :  */
      63             : static inline void
      64   102724750 : xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
      65             : {
      66   102724750 :         uint32_t crc = xfs_start_cksum_update(buffer, length, cksum_offset);
      67             : 
      68   102725942 :         *(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc);
      69   102725942 : }
      70             : 
      71             : /*
      72             :  * Helper to verify the checksum for a buffer.
      73             :  */
      74             : static inline int
      75   536205658 : xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset)
      76             : {
      77   536205658 :         uint32_t crc = xfs_start_cksum_safe(buffer, length, cksum_offset);
      78             : 
      79   536208336 :         return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc);
      80             : }
      81             : 
      82             : #endif /* _XFS_CKSUM_H */

Generated by: LCOV version 1.14