summaryrefslogtreecommitdiff
path: root/src/common/crc32c_intel_fast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/crc32c_intel_fast.c')
-rw-r--r--src/common/crc32c_intel_fast.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/common/crc32c_intel_fast.c b/src/common/crc32c_intel_fast.c
index b446fc1ecc5..49305088aff 100644
--- a/src/common/crc32c_intel_fast.c
+++ b/src/common/crc32c_intel_fast.c
@@ -1,5 +1,6 @@
#include <inttypes.h>
#include "acconfig.h"
+#include "common/crc32c_intel_baseline.h"
extern unsigned int crc32_iscsi_00(unsigned char const *buffer, int len, unsigned int crc);
@@ -7,7 +8,22 @@ extern unsigned int crc32_iscsi_00(unsigned char const *buffer, int len, unsigne
uint32_t ceph_crc32c_intel_fast(uint32_t crc, unsigned char const *buffer, unsigned len)
{
- return crc32_iscsi_00(buffer, len, crc);
+ uint32_t v;
+ unsigned left;
+
+ /*
+ * the crc32_iscsi_00 method reads past buffer+len (because it
+ * reads full words) which makes valgrind unhappy. don't do
+ * that.
+ */
+ if (len < 16)
+ return ceph_crc32c_intel_baseline(crc, buffer, len);
+ left = ((unsigned long)buffer + len) & 7;
+ len -= left;
+ v = crc32_iscsi_00(buffer, len, crc);
+ if (left)
+ v = ceph_crc32c_intel_baseline(v, buffer + len, left);
+ return v;
}
int ceph_crc32c_intel_fast_exists(void)