root/fs/xfs/libxfs/xfs_cksum.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. xfs_start_cksum_safe
  2. xfs_start_cksum_update
  3. xfs_end_cksum
  4. xfs_update_cksum
  5. xfs_verify_cksum

   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 xfs_start_cksum_safe(char *buffer, size_t length, unsigned long cksum_offset)
  15 {
  16         uint32_t zero = 0;
  17         uint32_t crc;
  18 
  19         /* Calculate CRC up to the checksum. */
  20         crc = crc32c(XFS_CRC_SEED, buffer, cksum_offset);
  21 
  22         /* Skip checksum field */
  23         crc = crc32c(crc, &zero, sizeof(__u32));
  24 
  25         /* Calculate the rest of the CRC. */
  26         return crc32c(crc, &buffer[cksum_offset + sizeof(__be32)],
  27                       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         *(__le32 *)(buffer + cksum_offset) = 0;
  39 
  40         /* single pass CRC calculation for the entire buffer */
  41         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         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 xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
  65 {
  66         uint32_t crc = xfs_start_cksum_update(buffer, length, cksum_offset);
  67 
  68         *(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc);
  69 }
  70 
  71 /*
  72  * Helper to verify the checksum for a buffer.
  73  */
  74 static inline int
  75 xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset)
  76 {
  77         uint32_t crc = xfs_start_cksum_safe(buffer, length, cksum_offset);
  78 
  79         return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc);
  80 }
  81 
  82 #endif /* _XFS_CKSUM_H */

/* [<][>][^][v][top][bottom][index][help] */