summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_cksum.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-13 17:49:53 -0600
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-13 17:49:53 -0600
commitdc1cc85133120e49c223f36aa77d398b8abac727 (patch)
tree3c9a823d83144867d13a6ba7b1b0e09fd3ccace8 /fs/xfs/libxfs/xfs_cksum.h
parentcec997093bbff881c3da49084dfba4f76361e96a (diff)
parent645f9857213476407d8ed1b59619fdff7128d3e6 (diff)
Merge tag 'xfs-for-linus-3.17-rc1' of git://oss.sgi.com/xfs/xfs
Pull xfs update from Dave Chinner: "This update contains: - conversion of the XFS core to pass negative error numbers - restructing of core XFS code that is shared with userspace to fs/xfs/libxfs - introduction of sysfs interface for XFS - bulkstat refactoring - demand driven speculative preallocation removal - XFS now always requires 64 bit sectors to be configured - metadata verifier changes to ensure CRCs are calculated during log recovery - various minor code cleanups - miscellaneous bug fixes The diffstat is kind of noisy because of the restructuring of the code to make kernel/userspace code sharing simpler, along with the XFS wide change to use the standard negative error return convention (at last!)" * tag 'xfs-for-linus-3.17-rc1' of git://oss.sgi.com/xfs/xfs: (45 commits) xfs: fix coccinelle warnings xfs: flush both inodes in xfs_swap_extents xfs: fix swapext ilock deadlock xfs: kill xfs_vnode.h xfs: kill VN_MAPPED xfs: kill VN_CACHED xfs: kill VN_DIRTY() xfs: dquot recovery needs verifiers xfs: quotacheck leaves dquot buffers without verifiers xfs: ensure verifiers are attached to recovered buffers xfs: catch buffers written without verifiers attached xfs: avoid false quotacheck after unclean shutdown xfs: fix rounding error of fiemap length parameter xfs: introduce xfs_bulkstat_ag_ichunk xfs: require 64-bit sector_t xfs: fix uflags detection at xfs_fs_rm_xquota xfs: remove XFS_IS_OQUOTA_ON macros xfs: tidy up xfs_set_inode32 xfs: allow inode allocations in post-growfs disk space xfs: mark xfs_qm_quotacheck as static ...
Diffstat (limited to 'fs/xfs/libxfs/xfs_cksum.h')
-rw-r--r--fs/xfs/libxfs/xfs_cksum.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_cksum.h b/fs/xfs/libxfs/xfs_cksum.h
new file mode 100644
index 000000000000..fad1676ad8cd
--- /dev/null
+++ b/fs/xfs/libxfs/xfs_cksum.h
@@ -0,0 +1,63 @@
+#ifndef _XFS_CKSUM_H
+#define _XFS_CKSUM_H 1
+
+#define XFS_CRC_SEED (~(__uint32_t)0)
+
+/*
+ * Calculate the intermediate checksum for a buffer that has the CRC field
+ * inside it. The offset of the 32bit crc fields is passed as the
+ * cksum_offset parameter.
+ */
+static inline __uint32_t
+xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset)
+{
+ __uint32_t zero = 0;
+ __uint32_t crc;
+
+ /* Calculate CRC up to the checksum. */
+ crc = crc32c(XFS_CRC_SEED, buffer, cksum_offset);
+
+ /* Skip checksum field */
+ crc = crc32c(crc, &zero, sizeof(__u32));
+
+ /* Calculate the rest of the CRC. */
+ return crc32c(crc, &buffer[cksum_offset + sizeof(__be32)],
+ length - (cksum_offset + sizeof(__be32)));
+}
+
+/*
+ * Convert the intermediate checksum to the final ondisk format.
+ *
+ * The CRC32c calculation uses LE format even on BE machines, but returns the
+ * result in host endian format. Hence we need to byte swap it back to LE format
+ * so that it is consistent on disk.
+ */
+static inline __le32
+xfs_end_cksum(__uint32_t crc)
+{
+ return ~cpu_to_le32(crc);
+}
+
+/*
+ * Helper to generate the checksum for a buffer.
+ */
+static inline void
+xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
+{
+ __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
+
+ *(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc);
+}
+
+/*
+ * Helper to verify the checksum for a buffer.
+ */
+static inline int
+xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset)
+{
+ __uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
+
+ return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc);
+}
+
+#endif /* _XFS_CKSUM_H */