diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/transam/twophase.c | 24 | ||||
-rw-r--r-- | src/backend/access/transam/xlog.c | 50 | ||||
-rw-r--r-- | src/backend/access/transam/xlogreader.c | 12 | ||||
-rw-r--r-- | src/backend/replication/logical/snapbuild.c | 28 | ||||
-rw-r--r-- | src/backend/replication/slot.c | 20 | ||||
-rw-r--r-- | src/backend/utils/adt/tsgistidx.c | 6 | ||||
-rw-r--r-- | src/backend/utils/adt/tsquery.c | 12 | ||||
-rw-r--r-- | src/backend/utils/cache/relmapper.c | 16 | ||||
-rw-r--r-- | src/bin/pg_controldata/pg_controldata.c | 12 | ||||
-rw-r--r-- | src/bin/pg_resetxlog/pg_resetxlog.c | 30 | ||||
-rw-r--r-- | src/include/access/xlog_internal.h | 2 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/utils/pg_crc.h | 93 | ||||
-rw-r--r-- | src/include/utils/pg_crc_tables.h | 77 |
14 files changed, 260 insertions, 124 deletions
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index d5409a64210..c4069c39a20 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -847,9 +847,9 @@ TwoPhaseGetDummyProc(TransactionId xid) * 6. TwoPhaseRecordOnDisk * 7. ... * 8. TwoPhaseRecordOnDisk (end sentinel, rmid == TWOPHASE_RM_END_ID) - * 9. CRC32 + * 9. checksum (CRC-32C) * - * Each segment except the final CRC32 is MAXALIGN'd. + * Each segment except the final checksum is MAXALIGN'd. */ /* @@ -1056,11 +1056,11 @@ EndPrepare(GlobalTransaction gxact) path))); /* Write data to file, and calculate CRC as we pass over it */ - INIT_CRC32(statefile_crc); + INIT_CRC32C(statefile_crc); for (record = records.head; record != NULL; record = record->next) { - COMP_CRC32(statefile_crc, record->data, record->len); + COMP_CRC32C(statefile_crc, record->data, record->len); if ((write(fd, record->data, record->len)) != record->len) { CloseTransientFile(fd); @@ -1070,7 +1070,7 @@ EndPrepare(GlobalTransaction gxact) } } - FIN_CRC32(statefile_crc); + FIN_CRC32C(statefile_crc); /* * Write a deliberately bogus CRC to the state file; this is just paranoia @@ -1289,13 +1289,13 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings) return NULL; } - INIT_CRC32(calc_crc); - COMP_CRC32(calc_crc, buf, crc_offset); - FIN_CRC32(calc_crc); + INIT_CRC32C(calc_crc); + COMP_CRC32C(calc_crc, buf, crc_offset); + FIN_CRC32C(calc_crc); file_crc = *((pg_crc32 *) (buf + crc_offset)); - if (!EQ_CRC32(calc_crc, file_crc)) + if (!EQ_CRC32C(calc_crc, file_crc)) { pfree(buf); return NULL; @@ -1540,9 +1540,9 @@ RecreateTwoPhaseFile(TransactionId xid, void *content, int len) int fd; /* Recompute CRC */ - INIT_CRC32(statefile_crc); - COMP_CRC32(statefile_crc, content, len); - FIN_CRC32(statefile_crc); + INIT_CRC32C(statefile_crc); + COMP_CRC32C(statefile_crc, content, len); + FIN_CRC32C(statefile_crc); TwoPhaseFilePath(path, xid); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 3c9aeaec1e7..3160db72458 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1059,9 +1059,9 @@ begin:; * the whole record in the order: rdata, then backup blocks, then record * header. */ - INIT_CRC32(rdata_crc); + INIT_CRC32C(rdata_crc); for (rdt = rdata; rdt != NULL; rdt = rdt->next) - COMP_CRC32(rdata_crc, rdt->data, rdt->len); + COMP_CRC32C(rdata_crc, rdt->data, rdt->len); /* * Construct record header (prev-link is filled in later, after reserving @@ -1076,7 +1076,7 @@ begin:; rechdr->xl_info = info; rechdr->xl_rmid = rmid; rechdr->xl_prev = InvalidXLogRecPtr; - COMP_CRC32(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev)); + COMP_CRC32C(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev)); hdr_rdt.next = rdata; hdr_rdt.data = (char *) rechdr; @@ -1193,8 +1193,8 @@ begin:; * Now that xl_prev has been filled in, finish CRC calculation of the * record header. */ - COMP_CRC32(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr)); - FIN_CRC32(rdata_crc); + COMP_CRC32C(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr)); + FIN_CRC32C(rdata_crc); rechdr->xl_crc = rdata_crc; /* @@ -4344,11 +4344,11 @@ WriteControlFile(void) ControlFile->float8ByVal = FLOAT8PASSBYVAL; /* Contents are protected with a CRC */ - INIT_CRC32(ControlFile->crc); - COMP_CRC32(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(ControlFile->crc); + INIT_CRC32C(ControlFile->crc); + COMP_CRC32C(ControlFile->crc, + (char *) ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(ControlFile->crc); /* * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the @@ -4444,13 +4444,13 @@ ReadControlFile(void) errhint("It looks like you need to initdb."))); /* Now check the CRC. */ - INIT_CRC32(crc); - COMP_CRC32(crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, + (char *) ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(crc); - if (!EQ_CRC32(crc, ControlFile->crc)) + if (!EQ_CRC32C(crc, ControlFile->crc)) ereport(FATAL, (errmsg("incorrect checksum in control file"))); @@ -4593,11 +4593,11 @@ UpdateControlFile(void) { int fd; - INIT_CRC32(ControlFile->crc); - COMP_CRC32(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(ControlFile->crc); + INIT_CRC32C(ControlFile->crc); + COMP_CRC32C(ControlFile->crc, + (char *) ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(ControlFile->crc); fd = BasicOpenFile(XLOG_CONTROL_FILE, O_RDWR | PG_BINARY, @@ -4975,10 +4975,10 @@ BootStrapXLOG(void) record->xl_rmid = RM_XLOG_ID; memcpy(XLogRecGetData(record), &checkPoint, sizeof(checkPoint)); - INIT_CRC32(crc); - COMP_CRC32(crc, &checkPoint, sizeof(checkPoint)); - COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, &checkPoint, sizeof(checkPoint)); + COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc)); + FIN_CRC32C(crc); record->xl_crc = crc; /* Create first XLOG segment file */ diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index f06daa2638f..da7ed92941c 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -684,8 +684,8 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr) return false; } remaining -= SizeOfXLogRecord + len; - INIT_CRC32(crc); - COMP_CRC32(crc, XLogRecGetData(record), len); + INIT_CRC32C(crc); + COMP_CRC32C(crc, XLogRecGetData(record), len); /* Add in the backup blocks, if any */ blk = (char *) XLogRecGetData(record) + len; @@ -722,7 +722,7 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr) return false; } remaining -= blen; - COMP_CRC32(crc, blk, blen); + COMP_CRC32C(crc, blk, blen); blk += blen; } @@ -736,10 +736,10 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr) } /* Finally include the record header */ - COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc)); - FIN_CRC32(crc); + COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc)); + FIN_CRC32C(crc); - if (!EQ_CRC32(record->xl_crc, crc)) + if (!EQ_CRC32C(record->xl_crc, crc)) { report_invalid_record(state, "incorrect resource manager data checksum in record at %X/%X", diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index 5e59c6b819b..71c5fe2490a 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -1517,9 +1517,9 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) ondisk->magic = SNAPBUILD_MAGIC; ondisk->version = SNAPBUILD_VERSION; ondisk->length = needed_length; - INIT_CRC32(ondisk->checksum); - COMP_CRC32(ondisk->checksum, - ((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize, + INIT_CRC32C(ondisk->checksum); + COMP_CRC32C(ondisk->checksum, + ((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize, SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize); ondisk_c += sizeof(SnapBuildOnDisk); @@ -1531,20 +1531,20 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) ondisk->builder.running.xip = NULL; ondisk->builder.committed.xip = NULL; - COMP_CRC32(ondisk->checksum, - &ondisk->builder, - sizeof(SnapBuild)); + COMP_CRC32C(ondisk->checksum, + &ondisk->builder, + sizeof(SnapBuild)); /* copy running xacts */ sz = sizeof(TransactionId) * builder->running.xcnt_space; memcpy(ondisk_c, builder->running.xip, sz); - COMP_CRC32(ondisk->checksum, ondisk_c, sz); + COMP_CRC32C(ondisk->checksum, ondisk_c, sz); ondisk_c += sz; /* copy committed xacts */ sz = sizeof(TransactionId) * builder->committed.xcnt; memcpy(ondisk_c, builder->committed.xip, sz); - COMP_CRC32(ondisk->checksum, ondisk_c, sz); + COMP_CRC32C(ondisk->checksum, ondisk_c, sz); ondisk_c += sz; /* we have valid data now, open tempfile and write it there */ @@ -1672,8 +1672,8 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) (errmsg("snapbuild state file \"%s\" has unsupported version %u instead of %u", path, ondisk.version, SNAPBUILD_VERSION))); - INIT_CRC32(checksum); - COMP_CRC32(checksum, + INIT_CRC32C(checksum); + COMP_CRC32C(checksum, ((char *) &ondisk) + SnapBuildOnDiskNotChecksummedSize, SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize); @@ -1687,7 +1687,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) errmsg("could not read file \"%s\", read %d of %d: %m", path, readBytes, (int) sizeof(SnapBuild)))); } - COMP_CRC32(checksum, &ondisk.builder, sizeof(SnapBuild)); + COMP_CRC32C(checksum, &ondisk.builder, sizeof(SnapBuild)); /* restore running xacts information */ sz = sizeof(TransactionId) * ondisk.builder.running.xcnt_space; @@ -1701,7 +1701,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) errmsg("could not read file \"%s\", read %d of %d: %m", path, readBytes, (int) sz))); } - COMP_CRC32(checksum, ondisk.builder.running.xip, sz); + COMP_CRC32C(checksum, ondisk.builder.running.xip, sz); /* restore committed xacts information */ sz = sizeof(TransactionId) * ondisk.builder.committed.xcnt; @@ -1715,12 +1715,12 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) errmsg("could not read file \"%s\", read %d of %d: %m", path, readBytes, (int) sz))); } - COMP_CRC32(checksum, ondisk.builder.committed.xip, sz); + COMP_CRC32C(checksum, ondisk.builder.committed.xip, sz); CloseTransientFile(fd); /* verify checksum of what we've read */ - if (!EQ_CRC32(checksum, ondisk.checksum)) + if (!EQ_CRC32C(checksum, ondisk.checksum)) ereport(ERROR, (errcode_for_file_access(), errmsg("snapbuild state file %s: checksum mismatch, is %u, should be %u", diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index f355f13d293..2c3ea555d09 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -993,7 +993,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) } cp.magic = SLOT_MAGIC; - INIT_CRC32(cp.checksum); + INIT_CRC32C(cp.checksum); cp.version = 1; cp.length = ReplicationSlotOnDiskDynamicSize; @@ -1003,9 +1003,9 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) SpinLockRelease(&slot->mutex); - COMP_CRC32(cp.checksum, - (char *) (&cp) + ReplicationSlotOnDiskConstantSize, - ReplicationSlotOnDiskDynamicSize); + COMP_CRC32C(cp.checksum, + (char *) (&cp) + ReplicationSlotOnDiskConstantSize, + ReplicationSlotOnDiskDynamicSize); if ((write(fd, &cp, sizeof(cp))) != sizeof(cp)) { @@ -1181,13 +1181,13 @@ RestoreSlotFromDisk(const char *name) CloseTransientFile(fd); - /* now verify the CRC32 */ - INIT_CRC32(checksum); - COMP_CRC32(checksum, - (char *) &cp + ReplicationSlotOnDiskConstantSize, - ReplicationSlotOnDiskDynamicSize); + /* now verify the CRC */ + INIT_CRC32C(checksum); + COMP_CRC32C(checksum, + (char *) &cp + ReplicationSlotOnDiskConstantSize, + ReplicationSlotOnDiskDynamicSize); - if (!EQ_CRC32(checksum, cp.checksum)) + if (!EQ_CRC32C(checksum, cp.checksum)) ereport(PANIC, (errmsg("replication slot file %s: checksum mismatch, is %u, should be %u", path, checksum, cp.checksum))); diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c index 80039189c3f..e9cff4ffb69 100644 --- a/src/backend/utils/adt/tsgistidx.c +++ b/src/backend/utils/adt/tsgistidx.c @@ -201,9 +201,9 @@ gtsvector_compress(PG_FUNCTION_ARGS) { pg_crc32 c; - INIT_CRC32(c); - COMP_CRC32(c, words + ptr->pos, ptr->len); - FIN_CRC32(c); + INIT_LEGACY_CRC32(c); + COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len); + FIN_LEGACY_CRC32(c); *arr = *(int32 *) &c; arr++; diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index c8011a8ea92..5226bae2d17 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -280,9 +280,9 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool errmsg("word is too long in tsquery: \"%s\"", state->buffer))); - INIT_CRC32(valcrc); - COMP_CRC32(valcrc, strval, lenval); - FIN_CRC32(valcrc); + INIT_LEGACY_CRC32(valcrc); + COMP_LEGACY_CRC32(valcrc, strval, lenval); + FIN_LEGACY_CRC32(valcrc); pushValue_internal(state, valcrc, state->curop - state->op, lenval, weight, prefix); /* append the value string to state.op, enlarging buffer if needed first */ @@ -883,9 +883,9 @@ tsqueryrecv(PG_FUNCTION_ARGS) /* Looks valid. */ - INIT_CRC32(valcrc); - COMP_CRC32(valcrc, val, val_len); - FIN_CRC32(valcrc); + INIT_LEGACY_CRC32(valcrc); + COMP_LEGACY_CRC32(valcrc, val, val_len); + FIN_LEGACY_CRC32(valcrc); item->qoperand.weight = weight; item->qoperand.prefix = (prefix) ? true : false; diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c index 95a2689fd42..b6b13308773 100644 --- a/src/backend/utils/cache/relmapper.c +++ b/src/backend/utils/cache/relmapper.c @@ -84,7 +84,7 @@ typedef struct RelMapFile int32 magic; /* always RELMAPPER_FILEMAGIC */ int32 num_mappings; /* number of valid RelMapping entries */ RelMapping mappings[MAX_MAPPINGS]; - int32 crc; /* CRC of all above */ + pg_crc32 crc; /* CRC of all above */ int32 pad; /* to make the struct size be 512 exactly */ } RelMapFile; @@ -673,11 +673,11 @@ load_relmap_file(bool shared) mapfilename))); /* verify the CRC */ - INIT_CRC32(crc); - COMP_CRC32(crc, (char *) map, offsetof(RelMapFile, crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc)); + FIN_CRC32C(crc); - if (!EQ_CRC32(crc, map->crc)) + if (!EQ_CRC32C(crc, map->crc)) ereport(FATAL, (errmsg("relation mapping file \"%s\" contains incorrect checksum", mapfilename))); @@ -719,9 +719,9 @@ write_relmap_file(bool shared, RelMapFile *newmap, if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS) elog(ERROR, "attempt to write bogus relation mapping"); - INIT_CRC32(newmap->crc); - COMP_CRC32(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc)); - FIN_CRC32(newmap->crc); + INIT_CRC32C(newmap->crc); + COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc)); + FIN_CRC32C(newmap->crc); /* * Open the target file. We prefer to do this before entering the diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index 32cc100fa25..b2e0793eb8f 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -178,13 +178,13 @@ main(int argc, char *argv[]) close(fd); /* Check the CRC. */ - INIT_CRC32(crc); - COMP_CRC32(crc, - (char *) &ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, + (char *) &ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(crc); - if (!EQ_CRC32(crc, ControlFile.crc)) + if (!EQ_CRC32C(crc, ControlFile.crc)) printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n" "Either the file is corrupt, or it has a different layout than this program\n" "is expecting. The results below are untrustworthy.\n\n")); diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c index f4c1eafc67c..e224e67ad62 100644 --- a/src/bin/pg_resetxlog/pg_resetxlog.c +++ b/src/bin/pg_resetxlog/pg_resetxlog.c @@ -456,13 +456,13 @@ ReadControlFile(void) ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION) { /* Check the CRC. */ - INIT_CRC32(crc); - COMP_CRC32(crc, - buffer, - offsetof(ControlFileData, crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, + buffer, + offsetof(ControlFileData, crc)); + FIN_CRC32C(crc); - if (EQ_CRC32(crc, ((ControlFileData *) buffer)->crc)) + if (EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc)) { /* Valid data... */ memcpy(&ControlFile, buffer, sizeof(ControlFile)); @@ -747,11 +747,11 @@ RewriteControlFile(void) ControlFile.xlog_seg_size = XLogSegSize; /* Contents are protected with a CRC */ - INIT_CRC32(ControlFile.crc); - COMP_CRC32(ControlFile.crc, - (char *) &ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(ControlFile.crc); + INIT_CRC32C(ControlFile.crc); + COMP_CRC32C(ControlFile.crc, + (char *) &ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(ControlFile.crc); /* * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the @@ -1032,10 +1032,10 @@ WriteEmptyXLOG(void) memcpy(XLogRecGetData(record), &ControlFile.checkPointCopy, sizeof(CheckPoint)); - INIT_CRC32(crc); - COMP_CRC32(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint)); - COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint)); + COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc)); + FIN_CRC32C(crc); record->xl_crc = crc; /* Write the first page */ diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 27b98995557..eaa1f9540e2 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -55,7 +55,7 @@ typedef struct BkpBlock /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD07F /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD080 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 69ef30a3596..2c059c88c18 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201410071 +#define CATALOG_VERSION_NO 201411041 #endif diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h index f43f4aad9dd..f871cba53f2 100644 --- a/src/include/utils/pg_crc.h +++ b/src/include/utils/pg_crc.h @@ -7,9 +7,22 @@ * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from * http://www.ross.net/crc/ or several other net sites. * - * We use a normal (not "reflected", in Williams' terms) CRC, using initial - * all-ones register contents and a final bit inversion. + * We have three slightly different variants of a 32-bit CRC calculation: + * CRC-32C (Castagnoli polynomial), CRC-32 (Ethernet polynomial), and a legacy + * CRC-32 version that uses the lookup table in a funny way. They all consist + * of four macros: * + * INIT_<variant>(crc) + * Initialize a CRC accumulator + * + * COMP_<variant>(crc, data, len) + * Accumulate some (more) bytes into a CRC + * + * FIN_<variant>(crc) + * Finish a CRC calculation + * + * EQ_<variant>(c1, c2) + * Check for equality of two CRCs. * * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California @@ -28,29 +41,81 @@ typedef uint32 pg_crc32; -/* Initialize a CRC accumulator */ -#define INIT_CRC32(crc) ((crc) = 0xFFFFFFFF) +/* + * CRC calculation using the CRC-32C (Castagnoli) polynomial. + * + * We use all-ones as the initial register contents and final bit inversion. + * This is the same algorithm used e.g. in iSCSI. See RFC 3385 for more + * details on the choice of polynomial. + */ +#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF) +#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) +#define COMP_CRC32C(crc, data, len) \ + COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table) +#define EQ_CRC32C(c1, c2) ((c1) == (c2)) -/* Finish a CRC calculation */ -#define FIN_CRC32(crc) ((crc) ^= 0xFFFFFFFF) +/* + * CRC-32, the same used e.g. in Ethernet. + * + * This is currently only used in ltree and hstore contrib modules. It uses + * the same lookup table as the legacy algorithm below. New code should + * use the Castagnoli version instead. + */ +#define INIT_TRADITIONAL_CRC32(crc) ((crc) = 0xFFFFFFFF) +#define FIN_TRADITIONAL_CRC32(crc) ((crc) ^= 0xFFFFFFFF) +#define COMP_TRADITIONAL_CRC32(crc, data, len) \ + COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32_table) +#define EQ_TRADITIONAL_CRC32(c1, c2) ((c1) == (c2)) -/* Accumulate some (more) bytes into a CRC */ -#define COMP_CRC32(crc, data, len) \ -do { \ +/* + * The CRC algorithm used for WAL et al in pre-9.5 versions. + * + * This closely resembles the normal CRC-32 algorithm, but is subtly + * different. Using Williams' terms, we use the "normal" table, but with + * "reflected" code. That's bogus, but it was like that for years before + * anyone noticed. It does not correspond to any polynomial in a normal CRC + * algorithm, so it's not clear what the error-detection properties of this + * algorithm actually are. + * + * We still need to carry this around because it is used in a few on-disk + * structures that need to be pg_upgradeable. It should not be used in new + * code. + */ +#define INIT_LEGACY_CRC32(crc) ((crc) = 0xFFFFFFFF) +#define FIN_LEGACY_CRC32(crc) ((crc) ^= 0xFFFFFFFF) +#define COMP_LEGACY_CRC32(crc, data, len) \ + COMP_CRC32_REFLECTED_TABLE(crc, data, len, pg_crc32_table) +#define EQ_LEGACY_CRC32(c1, c2) ((c1) == (c2)) + +/* + * Common code for CRC computation using a lookup table. + */ +#define COMP_CRC32_NORMAL_TABLE(crc, data, len, table) \ +do { \ const unsigned char *__data = (const unsigned char *) (data); \ uint32 __len = (len); \ \ while (__len-- > 0) \ { \ - int __tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \ - (crc) = pg_crc32_table[__tab_index] ^ ((crc) << 8); \ + int __tab_index = ((int) (crc) ^ *__data++) & 0xFF; \ + (crc) = table[__tab_index] ^ ((crc) >> 8); \ } \ } while (0) -/* Check for equality of two CRCs */ -#define EQ_CRC32(c1,c2) ((c1) == (c2)) +#define COMP_CRC32_REFLECTED_TABLE(crc, data, len, table) \ +do { \ + const unsigned char *__data = (const unsigned char *) (data); \ + uint32 __len = (len); \ +\ + while (__len-- > 0) \ + { \ + int __tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \ + (crc) = table[__tab_index] ^ ((crc) << 8); \ + } \ +} while (0) -/* Constant table for CRC calculation */ +/* Constant tables for CRC-32C and CRC-32 polynomials */ +extern CRCDLLIMPORT const uint32 pg_crc32c_table[]; extern CRCDLLIMPORT const uint32 pg_crc32_table[]; #endif /* PG_CRC_H */ diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h index f56613776dc..cb6b470885d 100644 --- a/src/include/utils/pg_crc_tables.h +++ b/src/include/utils/pg_crc_tables.h @@ -11,9 +11,8 @@ * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from * http://www.ross.net/crc/download/crc_v3.txt or several other net sites. * - * We use a normal (not "reflected", in Williams' terms) CRC, using initial - * all-ones register contents and a final bit inversion. - * + * These lookup tables are for normal, not "reflected", in Williams' terms, + * CRC. * * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California @@ -26,6 +25,78 @@ #define PG_CRC_TABLES_H /* + * This table is based on the so-called Castagnoli polynomial (the same + * that is used e.g. in iSCSI). + */ +const uint32 pg_crc32c_table[256] = { + 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, + 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, + 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, + 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, + 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, + 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, + 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, + 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, + 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, + 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, + 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, + 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, + 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, + 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, + 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, + 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, + 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, + 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, + 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, + 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, + 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, + 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, + 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, + 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, + 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, + 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, + 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, + 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, + 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, + 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, + 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, + 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, + 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, + 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, + 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, + 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, + 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, + 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, + 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, + 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, + 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, + 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, + 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, + 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, + 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, + 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, + 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, + 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, + 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, + 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, + 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, + 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, + 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, + 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, + 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, + 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, + 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, + 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, + 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, + 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, + 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, + 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, + 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, + 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 +}; + + +/* * This table is based on the polynomial * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. * (This is the same polynomial used in Ethernet checksums, for instance.) |