diff options
Diffstat (limited to 'src/backend/storage/page/bufpage.c')
-rw-r--r-- | src/backend/storage/page/bufpage.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index 326d3de8889..f0e365379a4 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -16,6 +16,7 @@ #include "access/htup_details.h" #include "access/xlog.h" +#include "storage/checksum.h" bool ignore_checksum_failure = false; @@ -948,33 +949,30 @@ PageSetChecksumInplace(Page page, BlockNumber blkno) static uint16 PageCalcChecksum16(Page page, BlockNumber blkno) { - pg_crc32 crc; - PageHeader p = (PageHeader) page; + PageHeader phdr = (PageHeader) page; + uint16 save_checksum; + uint32 checksum; /* only calculate the checksum for properly-initialized pages */ Assert(!PageIsNew(page)); - INIT_CRC32(crc); - /* - * Initialize the checksum calculation with the block number. This helps - * catch corruption from whole blocks being transposed with other whole - * blocks. + * Save pd_checksum and set it to zero, so that the checksum calculation + * isn't affected by the checksum stored on the page. We do this to + * allow optimization of the checksum calculation on the whole block + * in one go. */ - COMP_CRC32(crc, &blkno, sizeof(blkno)); + save_checksum = phdr->pd_checksum; + phdr->pd_checksum = 0; + checksum = checksum_block(page, BLCKSZ); + phdr->pd_checksum = save_checksum; - /* - * Now add in the LSN, which is always the first field on the page. - */ - COMP_CRC32(crc, page, sizeof(p->pd_lsn)); + /* mix in the block number to detect transposed pages */ + checksum ^= blkno; /* - * Now add the rest of the page, skipping the pd_checksum field. + * Reduce to a uint16 (to fit in the pd_checksum field) with an offset of + * one. That avoids checksums of zero, which seems like a good idea. */ - COMP_CRC32(crc, page + sizeof(p->pd_lsn) + sizeof(p->pd_checksum), - BLCKSZ - sizeof(p->pd_lsn) - sizeof(p->pd_checksum)); - - FIN_CRC32(crc); - - return (uint16) crc; + return (checksum % 65535) + 1; } |