summaryrefslogtreecommitdiff
path: root/src/block/block_open.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/block/block_open.c')
-rw-r--r--src/block/block_open.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/src/block/block_open.c b/src/block/block_open.c
index dd0f3f0716a..d9b2f908737 100644
--- a/src/block/block_open.c
+++ b/src/block/block_open.c
@@ -296,15 +296,21 @@ __wt_desc_init(WT_SESSION_IMPL *session, WT_FH *fh, uint32_t allocsize)
WT_RET(__wt_scr_alloc(session, allocsize, &buf));
memset(buf->mem, 0, allocsize);
+ /*
+ * Checksum a little-endian version of the header, and write everything
+ * in little-endian format. The checksum is (potentially) returned in a
+ * big-endian format, swap it into place in a separate step.
+ */
desc = buf->mem;
desc->magic = WT_BLOCK_MAGIC;
desc->majorv = WT_BLOCK_MAJOR_VERSION;
desc->minorv = WT_BLOCK_MINOR_VERSION;
-
- /* Update the checksum. */
desc->cksum = 0;
+ __wt_block_desc_byteswap(desc);
desc->cksum = __wt_cksum(desc, allocsize);
-
+#ifdef WORDS_BIGENDIAN
+ desc->cksum = __wt_bswap32(desc->cksum);
+#endif
ret = __wt_write(session, fh, (wt_off_t)0, (size_t)allocsize, desc);
__wt_scr_free(session, &buf);
@@ -321,7 +327,7 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block)
WT_BLOCK_DESC *desc;
WT_DECL_ITEM(buf);
WT_DECL_RET;
- uint32_t cksum;
+ uint32_t cksum_calculate, cksum_tmp;
/* Use a scratch buffer to get correct alignment for direct I/O. */
WT_RET(__wt_scr_alloc(session, block->allocsize, &buf));
@@ -330,14 +336,19 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block)
WT_ERR(__wt_read(session,
block->fh, (wt_off_t)0, (size_t)block->allocsize, buf->mem));
+ /*
+ * Handle little- and big-endian objects. Objects are written in little-
+ * endian format: save the header checksum, and calculate the checksum
+ * for the header in its little-endian form. Then, restore the header's
+ * checksum, and byte-swap the whole thing as necessary, leaving us with
+ * a calculated checksum that should match the checksum in the header.
+ */
desc = buf->mem;
- WT_ERR(__wt_verbose(session, WT_VERB_BLOCK,
- "%s: magic %" PRIu32
- ", major/minor: %" PRIu32 "/%" PRIu32
- ", checksum %#" PRIx32,
- block->name, desc->magic,
- desc->majorv, desc->minorv,
- desc->cksum));
+ cksum_tmp = desc->cksum;
+ desc->cksum = 0;
+ cksum_calculate = __wt_cksum(desc, block->allocsize);
+ desc->cksum = cksum_tmp;
+ __wt_block_desc_byteswap(desc);
/*
* We fail the open if the checksum fails, or the magic number is wrong
@@ -348,10 +359,7 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block)
* may have entered the wrong file name, and is now frantically pounding
* their interrupt key.
*/
- cksum = desc->cksum;
- desc->cksum = 0;
- if (desc->magic != WT_BLOCK_MAGIC ||
- cksum != __wt_cksum(desc, block->allocsize))
+ if (desc->magic != WT_BLOCK_MAGIC || desc->cksum != cksum_calculate)
WT_ERR_MSG(session, WT_ERROR,
"%s does not appear to be a WiredTiger file", block->name);
@@ -365,6 +373,14 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block)
WT_BLOCK_MAJOR_VERSION, WT_BLOCK_MINOR_VERSION,
desc->majorv, desc->minorv);
+ WT_ERR(__wt_verbose(session, WT_VERB_BLOCK,
+ "%s: magic %" PRIu32
+ ", major/minor: %" PRIu32 "/%" PRIu32
+ ", checksum %#" PRIx32,
+ block->name, desc->magic,
+ desc->majorv, desc->minorv,
+ desc->cksum));
+
err: __wt_scr_free(session, &buf);
return (ret);
}