dovecot: Handle indexid changes better.
dovecot at dovecot.org
dovecot at dovecot.org
Thu Jun 28 01:52:05 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/4ea31bf18a56
changeset: 5819:4ea31bf18a56
user: Timo Sirainen <tss at iki.fi>
date: Thu Jun 28 01:03:18 2007 +0300
description:
Handle indexid changes better.
diffstat:
9 files changed, 79 insertions(+), 17 deletions(-)
src/lib-index/mail-cache-compress.c | 2 -
src/lib-index/mail-index-map.c | 26 +++++++++++++++++++-----
src/lib-index/mail-index-sync-update.c | 1
src/lib-index/mail-index-write.c | 1
src/lib-index/mail-index.c | 12 ++++++++++-
src/lib-index/mail-transaction-log-file.c | 28 ++++++++++++++++----------
src/lib-index/mail-transaction-log-private.h | 1
src/lib-index/mail-transaction-log.c | 22 ++++++++++++++++++++
src/lib-index/mail-transaction-log.h | 3 ++
diffs (262 lines):
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-cache-compress.c
--- a/src/lib-index/mail-cache-compress.c Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-cache-compress.c Thu Jun 28 01:03:18 2007 +0300
@@ -139,7 +139,7 @@ mail_cache_copy(struct mail_cache *cache
memset(&hdr, 0, sizeof(hdr));
hdr.version = MAIL_CACHE_VERSION;
hdr.compat_sizeof_uoff_t = sizeof(uoff_t);
- hdr.indexid = idx_hdr->indexid;
+ hdr.indexid = cache->index->indexid;
hdr.file_seq = get_next_file_seq(cache, view);
o_stream_send(output, &hdr, sizeof(hdr));
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-index-map.c
--- a/src/lib-index/mail-index-map.c Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-index-map.c Thu Jun 28 01:03:18 2007 +0300
@@ -7,6 +7,7 @@
#include "read-full.h"
#include "mail-index-private.h"
#include "mail-index-sync-private.h"
+#include "mail-transaction-log-private.h"
static void mail_index_map_init_extbufs(struct mail_index_map *map,
unsigned int initial_count)
@@ -252,7 +253,18 @@ static bool mail_index_check_header_comp
"Corrupted header size (%u > %"PRIuUOFF_T")",
index->filepath, hdr->header_size,
file_size);
- return 0;
+ return FALSE;
+ }
+
+ if (hdr->indexid != index->indexid) {
+ if (index->indexid != 0) {
+ mail_index_set_error(index, "Index file %s: "
+ "indexid changed: %u -> %u",
+ index->filepath, index->indexid,
+ hdr->indexid);
+ }
+ index->indexid = hdr->indexid;
+ mail_transaction_log_indexid_changed(index->log);
}
return TRUE;
@@ -609,7 +621,6 @@ static void mail_index_header_init(struc
static void mail_index_header_init(struct mail_index *index,
struct mail_index_header *hdr)
{
- i_assert(index->indexid != 0);
i_assert((sizeof(*hdr) % sizeof(uint64_t)) == 0);
memset(hdr, 0, sizeof(*hdr));
@@ -741,9 +752,14 @@ int mail_index_map(struct mail_index *in
reopening succeeds) */
(void)mail_index_map_latest_file(index, &index->map, &lock_id);
- /* and update the map with the latest changes from
- transaction log */
- ret = mail_index_sync_map(index, &index->map, type, TRUE);
+ /* if we're creating the index file, we don't have any
+ logs yet */
+ if (index->log->head != NULL) {
+ /* and update the map with the latest changes from
+ transaction log */
+ ret = mail_index_sync_map(index, &index->map,
+ type, TRUE);
+ }
/* we need the lock only if we didn't move the map to memory */
if (!MAIL_INDEX_MAP_IS_IN_MEMORY(index->map))
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-index-sync-update.c Thu Jun 28 01:03:18 2007 +0300
@@ -799,6 +799,7 @@ int mail_index_sync_map(struct mail_inde
#ifdef DEBUG
mail_index_map_check(map);
#endif
+ i_assert(map->hdr.indexid == index->indexid);
/* transaction log tracks internally the current tail offset.
besides using header updates, it also updates the offset to skip
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-index-write.c
--- a/src/lib-index/mail-index-write.c Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-index-write.c Thu Jun 28 01:03:18 2007 +0300
@@ -20,6 +20,7 @@ static int mail_index_recreate(struct ma
int ret, fd;
i_assert(!MAIL_INDEX_IS_IN_MEMORY(index));
+ i_assert(map->hdr.indexid == index->indexid);
fd = mail_index_create_tmp_file(index, &path);
if (fd == -1)
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-index.c
--- a/src/lib-index/mail-index.c Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-index.c Thu Jun 28 01:03:18 2007 +0300
@@ -1,6 +1,7 @@
/* Copyright (C) 2003-2004 Timo Sirainen */
#include "lib.h"
+#include "ioloop.h"
#include "array.h"
#include "buffer.h"
#include "hash.h"
@@ -404,11 +405,20 @@ static bool mail_index_open_files(struct
if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
return FALSE;
+ /* if dovecot.index exists, read it first so that we can get
+ the correct indexid and log sequence */
+ (void)mail_index_try_open(index);
+
+ if (index->indexid == 0) {
+ /* create a new indexid for us */
+ index->indexid = ioloop_time;
+ }
+
ret = mail_transaction_log_create(index->log);
created = TRUE;
}
if (ret >= 0) {
- ret = created ? 0 : mail_index_try_open(index);
+ ret = index->map != NULL ? 0 : mail_index_try_open(index);
if (ret == 0) {
/* doesn't exist / corrupted */
index->map = mail_index_map_alloc(index);
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-transaction-log-file.c Thu Jun 28 01:03:18 2007 +0300
@@ -20,6 +20,7 @@ mail_transaction_log_file_set_corrupted(
{
va_list va;
+ file->corrupted = TRUE;
file->hdr.indexid = 0;
if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
/* indexid=0 marks the log file as corrupted */
@@ -142,9 +143,6 @@ mail_transaction_log_init_hdr(struct mai
struct mail_index *index = log->index;
unsigned int lock_id = 0;
- if (log->index->indexid == 0)
- log->index->indexid = ioloop_time;
-
memset(hdr, 0, sizeof(*hdr));
hdr->major_version = MAIL_TRANSACTION_LOG_MAJOR_VERSION;
hdr->minor_version = MAIL_TRANSACTION_LOG_MINOR_VERSION;
@@ -154,9 +152,15 @@ mail_transaction_log_init_hdr(struct mai
if (index->fd != -1) {
/* not creating index - make sure we have latest header */
- if (mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD,
- &lock_id) <= 0)
- return -1;
+ if (!index->mapping) {
+ if (mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD,
+ &lock_id) <= 0)
+ return -1;
+ } else {
+ /* if we got here from mapping, the .log file is
+ corrupted. use whatever values we got from index
+ file */
+ }
}
if (index->map != NULL) {
hdr->prev_file_seq = index->map->hdr.log_file_seq;
@@ -313,6 +317,9 @@ mail_transaction_log_file_read_hdr(struc
int ret;
i_assert(!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file));
+
+ if (file->corrupted)
+ return 0;
ret = pread_full(file->fd, &file->hdr, sizeof(file->hdr), 0);
if (ret < 0) {
@@ -347,18 +354,19 @@ mail_transaction_log_file_read_hdr(struc
if (file->hdr.indexid == 0) {
/* corrupted */
+ file->corrupted = TRUE;
mail_index_set_error(file->log->index,
"Transaction log file %s: marked corrupted",
file->filepath);
return 0;
}
if (file->hdr.indexid != file->log->index->indexid) {
- if (file->log->index->fd != -1) {
+ if (file->log->index->indexid != 0) {
/* index file was probably just rebuilt and we don't
know about it yet */
mail_transaction_log_file_set_corrupted(file,
- "invalid indexid (%u != %u)",
- file->hdr.indexid, file->log->index->indexid);
+ "indexid changed %u -> %u",
+ file->log->index->indexid, file->hdr.indexid);
return 0;
}
@@ -462,7 +470,7 @@ mail_transaction_log_file_create2(struct
} else {
file->fd = fd;
if (mail_transaction_log_file_read_hdr(file,
- FALSE) == 0) {
+ FALSE) > 0) {
/* yes, it was ok */
(void)file_dotlock_delete(dotlock);
return 0;
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-transaction-log-private.h
--- a/src/lib-index/mail-transaction-log-private.h Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-transaction-log-private.h Thu Jun 28 01:03:18 2007 +0300
@@ -46,6 +46,7 @@ struct mail_transaction_log_file {
struct file_lock *file_lock;
unsigned int locked:1;
+ unsigned int corrupted:1;
};
struct mail_transaction_log {
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-transaction-log.c
--- a/src/lib-index/mail-transaction-log.c Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-transaction-log.c Thu Jun 28 01:03:18 2007 +0300
@@ -137,6 +137,28 @@ void mail_transaction_log_move_to_memory
mail_transaction_log_file_move_to_memory(log->head);
}
+void mail_transaction_log_indexid_changed(struct mail_transaction_log *log)
+{
+ struct mail_transaction_log_file *file;
+
+ mail_transaction_logs_clean(log);
+
+ for (file = log->files; file != NULL; file = file->next) {
+ if (file->hdr.indexid != log->index->indexid) {
+ mail_transaction_log_file_set_corrupted(file,
+ "indexid changed: %u -> %u",
+ file->hdr.indexid, log->index->indexid);
+ }
+ }
+
+ if (log->head != NULL &&
+ log->head->hdr.indexid != log->index->indexid) {
+ if (--log->head->refcount == 0)
+ mail_transaction_log_file_free(&log->head);
+ (void)mail_transaction_log_create(log);
+ }
+}
+
void mail_transaction_logs_clean(struct mail_transaction_log *log)
{
struct mail_transaction_log_file *file, *next;
diff -r 86282604e2f5 -r 4ea31bf18a56 src/lib-index/mail-transaction-log.h
--- a/src/lib-index/mail-transaction-log.h Thu Jun 28 00:04:31 2007 +0300
+++ b/src/lib-index/mail-transaction-log.h Thu Jun 28 01:03:18 2007 +0300
@@ -123,6 +123,9 @@ int mail_transaction_log_create(struct m
int mail_transaction_log_create(struct mail_transaction_log *log);
/* Close all the open transactions log files. */
void mail_transaction_log_close(struct mail_transaction_log *log);
+
+/* Notify of indexid change */
+void mail_transaction_log_indexid_changed(struct mail_transaction_log *log);
/* Returns the file seq/offset where the mailbox is currently synced at.
Since the log is rotated only when mailbox is fully synced, the sequence
More information about the dovecot-cvs
mailing list