From aef92409cf369afdd2ecd81a4f80083cd4082f46 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 31 Aug 2008 09:31:27 +0300 Subject: [PATCH] Write CPU endianess to transaction log header and check it's correct when reading. --HG-- branch : HEAD --- src/lib-index/mail-transaction-log-file.c | 52 ++++++++++++++++++++--- src/lib-index/mail-transaction-log.h | 7 ++- src/util/logview.c | 1 + 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/lib-index/mail-transaction-log-file.c b/src/lib-index/mail-transaction-log-file.c index 15860534a7..149c5a9cd1 100644 --- a/src/lib-index/mail-transaction-log-file.c +++ b/src/lib-index/mail-transaction-log-file.c @@ -180,6 +180,9 @@ mail_transaction_log_init_hdr(struct mail_transaction_log *log, hdr->hdr_size = sizeof(struct mail_transaction_log_header); hdr->indexid = log->index->indexid; hdr->create_stamp = ioloop_time; +#ifndef WORDS_BIGENDIAN + hdr->compat_flags |= MAIL_INDEX_COMPAT_LITTLE_ENDIAN; +#endif if (index->fd != -1) { /* not creating index - make sure we have latest header */ @@ -345,6 +348,27 @@ void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file) file_unlock(&file->file_lock); } +static ssize_t +mail_transaction_log_file_read_header(struct mail_transaction_log_file *file) +{ + ssize_t pos; + int ret; + + memset(&file->hdr, 0, sizeof(file->hdr)); + + /* try to read the whole header, but it's not necessarily an error to + read less since the older versions of the log format could be + smaller. */ + pos = 0; + do { + ret = pread(file->fd, PTR_OFFSET(&file->hdr, pos), + sizeof(file->hdr) - pos, pos); + if (ret > 0) + pos += ret; + } while (ret > 0 && pos < (ssize_t)sizeof(file->hdr)); + return ret < 0 ? -1 : pos; +} + static int mail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file, bool ignore_estale) @@ -357,24 +381,40 @@ mail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file, if (file->corrupted) return 0; - ret = pread_full(file->fd, &file->hdr, sizeof(file->hdr), 0); + ret = mail_transaction_log_file_read_header(file); if (ret < 0) { if (errno != ESTALE || !ignore_estale) { mail_index_file_set_syscall_error(file->log->index, file->filepath, - "pread_full()"); + "pread()"); } return -1; } - if (ret == 0) { + if (file->hdr.major_version != MAIL_TRANSACTION_LOG_MAJOR_VERSION) { + /* incompatible version - fix silently */ + return 0; + } + if (ret < MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE) { mail_transaction_log_file_set_corrupted(file, "unexpected end of file while reading header"); return 0; } - if (file->hdr.major_version != MAIL_TRANSACTION_LOG_MAJOR_VERSION) { - /* incompatible version - fix silently */ - return 0; + if (file->hdr.minor_version >= 2 || file->hdr.major_version > 1) { + /* we have compatibility flags */ + enum mail_index_header_compat_flags compat_flags = 0; + +#ifndef WORDS_BIGENDIAN + compat_flags |= MAIL_INDEX_COMPAT_LITTLE_ENDIAN; +#endif + if (file->hdr.compat_flags != compat_flags) { + /* architecture change */ + mail_index_set_error(file->log->index, + "Rebuilding index file %s: " + "CPU architecture changed", + file->log->index->filepath); + return 0; + } } if (file->hdr.hdr_size < MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE) { mail_transaction_log_file_set_corrupted(file, diff --git a/src/lib-index/mail-transaction-log.h b/src/lib-index/mail-transaction-log.h index 25e0dc2a4a..32b75908c8 100644 --- a/src/lib-index/mail-transaction-log.h +++ b/src/lib-index/mail-transaction-log.h @@ -5,7 +5,7 @@ struct mail_index; struct mail_index_transaction; #define MAIL_TRANSACTION_LOG_MAJOR_VERSION 1 -#define MAIL_TRANSACTION_LOG_MINOR_VERSION 1 +#define MAIL_TRANSACTION_LOG_MINOR_VERSION 2 #define MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE 24 struct mail_transaction_log_header { @@ -18,7 +18,10 @@ struct mail_transaction_log_header { uint32_t prev_file_seq; uint32_t prev_file_offset; uint32_t create_stamp; - uint64_t initial_modseq; + uint64_t initial_modseq; /* v1.1+ */ + + uint8_t compat_flags; /* enum mail_index_header_compat_flags, v1.2+ */ + uint8_t unused[3]; }; enum mail_transaction_type { diff --git a/src/util/logview.c b/src/util/logview.c index fb7bcc3480..b88982ab85 100644 --- a/src/util/logview.c +++ b/src/util/logview.c @@ -45,6 +45,7 @@ static void dump_hdr(int fd, uint64_t *modseq_r) printf("create stamp = %u\n", hdr.create_stamp); printf("initial modseq = %llu\n", (unsigned long long)hdr.initial_modseq); + printf("compat flags = %x\n", hdr.compat_flags); *modseq_r = hdr.initial_modseq; } -- 2.47.3