summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2016-01-27 08:50:37 -0500
committerKeith Bostic <keith@wiredtiger.com>2016-01-27 08:50:37 -0500
commit262d44f7b8ba8a3023e737272ff9944e8610cd7c (patch)
tree5e126dfba7a9e419d1db25ec983aadb842a50ba3
parentec75b8e5e5f8a7f910e97df7ae2164a4080f4f63 (diff)
downloadmongo-262d44f7b8ba8a3023e737272ff9944e8610cd7c.tar.gz
WT-60: big endian support
Rework the logging endian support.
-rw-r--r--src/log/log.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/src/log/log.c b/src/log/log.c
index 3651879c938..196002030c9 100644
--- a/src/log/log.c
+++ b/src/log/log.c
@@ -606,11 +606,19 @@ __log_file_header(
/*
* Now that the record is set up, initialize the record header.
+ *
+ * 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.
*/
logrec->len = log->allocsize;
logrec->checksum = 0;
- logrec->checksum = __wt_cksum(logrec, log->allocsize);
__wt_log_record_byteswap(logrec);
+ logrec->checksum = __wt_cksum(logrec, log->allocsize);
+#if WORDS_BIGENDIAN
+ logrec->checksum = __wt_bswap32(logrec->checksum);
+#endif
+
WT_CLEAR(tmp);
memset(&myslot, 0, sizeof(myslot));
myslot.slot = &tmp;
@@ -1431,7 +1439,8 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags,
WT_LOG_RECORD *logrec;
WT_LSN end_lsn, next_lsn, rd_lsn, start_lsn;
wt_off_t log_size;
- uint32_t allocsize, cksum, firstlog, lastlog, lognum, rdup_len, reclen;
+ uint32_t allocsize, firstlog, lastlog, lognum, rdup_len, reclen;
+ uint32_t cksum_calculate, cksum_tmp;
u_int i, logcount;
int firstrecord;
bool eol;
@@ -1564,12 +1573,14 @@ advance:
WT_ERR(__wt_read(session,
log_fh, rd_lsn.offset, (size_t)allocsize, buf->mem));
/*
- * First 4 bytes is the real record length. See if we
- * need to read more than the allocation size. We expect
- * that we rarely will have to read more. Most log records
- * will be fairly small.
+ * See if we need to read more than the allocation size. We
+ * expect that we rarely will have to read more. Most log
+ * records will be fairly small.
*/
- reclen = *(uint32_t *)buf->mem;
+ reclen = ((WT_LOG_RECORD *)buf->mem)->len;
+#ifdef WORDS_BIGENDIAN
+ reclen = __wt_bswap32(reclen);
+#endif
/*
* Log files are pre-allocated. We need to detect the
* difference between a hole in the file (where this location
@@ -1610,14 +1621,22 @@ advance:
}
/*
* We read in the record, verify checksum.
+ *
+ * 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.
*/
buf->size = reclen;
logrec = (WT_LOG_RECORD *)buf->mem;
- __wt_log_record_byteswap(logrec);
- cksum = logrec->checksum;
+ cksum_tmp = logrec->checksum;
logrec->checksum = 0;
- logrec->checksum = __wt_cksum(logrec, logrec->len);
- if (logrec->checksum != cksum) {
+ cksum_calculate = __wt_cksum(logrec, reclen);
+ logrec->checksum = cksum_tmp;
+ __wt_log_record_byteswap(logrec);
+ if (logrec->checksum != cksum_calculate) {
/*
* A checksum mismatch means we have reached the end of
* the useful part of the log. This should be found on
@@ -1896,11 +1915,19 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp,
rdup_len - record->size);
record->size = rdup_len;
}
+ /*
+ * 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.
+ */
logrec = (WT_LOG_RECORD *)record->mem;
logrec->len = (uint32_t)record->size;
logrec->checksum = 0;
- logrec->checksum = __wt_cksum(logrec, record->size);
__wt_log_record_byteswap(logrec);
+ logrec->checksum = __wt_cksum(logrec, record->size);
+#ifdef WORDS_BIGENDIAN
+ logrec->checksum = __wt_bswap32(logrec->checksum);
+#endif
WT_STAT_FAST_CONN_INCR(session, log_writes);