From 94aa90d2d17a7aebcda5a4193a62e80ddbb169b7 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 30 May 2008 02:09:20 +0300 Subject: [PATCH] Fixes to handling races in initial index creation. --HG-- branch : HEAD --- src/lib-index/mail-index-private.h | 1 + src/lib-index/mail-index.c | 10 ++++++---- src/lib-index/mail-transaction-log-file.c | 5 ++--- src/lib-index/mail-transaction-log.c | 8 ++++---- src/lib-index/mail-transaction-log.h | 2 +- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/lib-index/mail-index-private.h b/src/lib-index/mail-index-private.h index e7f87cab21..42b928a455 100644 --- a/src/lib-index/mail-index-private.h +++ b/src/lib-index/mail-index-private.h @@ -218,6 +218,7 @@ struct mail_index { unsigned int mapping:1; unsigned int syncing:1; unsigned int need_recreate:1; + unsigned int initial_create:1; }; extern struct mail_index_module_register mail_index_module_register; diff --git a/src/lib-index/mail-index.c b/src/lib-index/mail-index.c index 95fa4c0e02..8c16e37970 100644 --- a/src/lib-index/mail-index.c +++ b/src/lib-index/mail-index.c @@ -341,19 +341,21 @@ static int mail_index_open_files(struct mail_index *index, /* Create a new indexid for us. If we're opening index into memory, index->map doesn't exist yet. */ index->indexid = ioloop_time; + index->initial_create = TRUE; if (index->map != NULL) index->map->hdr.indexid = index->indexid; } - ret = mail_transaction_log_create(index->log); + ret = mail_transaction_log_create(index->log, FALSE); + index->initial_create = FALSE; created = TRUE; } if (ret >= 0) { - ret = index->map != NULL ? 0 : mail_index_try_open(index); + ret = index->map != NULL ? 1 : mail_index_try_open(index); if (ret == 0) { - /* doesn't exist / corrupted */ + /* corrupted */ mail_transaction_log_close(index->log); - ret = mail_transaction_log_create(index->log); + ret = mail_transaction_log_create(index->log, TRUE); if (ret == 0) { if (index->map != NULL) mail_index_unmap(&index->map); diff --git a/src/lib-index/mail-transaction-log-file.c b/src/lib-index/mail-transaction-log-file.c index 1dfbb4efad..792b28a526 100644 --- a/src/lib-index/mail-transaction-log-file.c +++ b/src/lib-index/mail-transaction-log-file.c @@ -357,7 +357,8 @@ mail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file, return 0; } if (file->hdr.indexid != file->log->index->indexid) { - if (file->log->index->indexid != 0) { + if (file->log->index->indexid != 0 && + !file->log->index->initial_create) { /* index file was probably just rebuilt and we don't know about it yet */ mail_transaction_log_file_set_corrupted(file, @@ -477,8 +478,6 @@ mail_transaction_log_file_create2(struct mail_transaction_log_file *file, file->fd = fd; if (mail_transaction_log_file_read_hdr(file, FALSE) > 0 && - file->hdr.file_seq == 1 && - file->hdr.prev_file_seq == 0 && mail_transaction_log_file_stat(file, FALSE) == 0) { /* yes, it was ok */ (void)file_dotlock_delete(dotlock); diff --git a/src/lib-index/mail-transaction-log.c b/src/lib-index/mail-transaction-log.c index 08642be1a0..0e8800faac 100644 --- a/src/lib-index/mail-transaction-log.c +++ b/src/lib-index/mail-transaction-log.c @@ -99,7 +99,7 @@ int mail_transaction_log_open(struct mail_transaction_log *log) return 1; } -int mail_transaction_log_create(struct mail_transaction_log *log) +int mail_transaction_log_create(struct mail_transaction_log *log, bool reset) { struct mail_transaction_log_file *file; const char *path; @@ -125,7 +125,7 @@ int mail_transaction_log_create(struct mail_transaction_log *log) mail_transaction_log_file_free(&log->open_file); } - if (mail_transaction_log_file_create(file, FALSE) < 0) { + if (mail_transaction_log_file_create(file, reset) < 0) { mail_transaction_log_file_free(&file); return -1; } @@ -187,7 +187,7 @@ void mail_transaction_log_indexid_changed(struct mail_transaction_log *log) 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_log_create(log, FALSE); } } @@ -291,7 +291,7 @@ mail_transaction_log_refresh(struct mail_transaction_log *log, bool nfs_flush) someone deleted it manually while the index was open. try to handle this nicely by creating a new log file. */ file = log->head; - if (mail_transaction_log_create(log) < 0) + if (mail_transaction_log_create(log, FALSE) < 0) return -1; i_assert(file->refcount > 0); file->refcount--; diff --git a/src/lib-index/mail-transaction-log.h b/src/lib-index/mail-transaction-log.h index b3445fa1ea..b9defdef3d 100644 --- a/src/lib-index/mail-transaction-log.h +++ b/src/lib-index/mail-transaction-log.h @@ -122,7 +122,7 @@ void mail_transaction_log_free(struct mail_transaction_log **log); is corrupted, -1 if there was some I/O error. */ int mail_transaction_log_open(struct mail_transaction_log *log); /* Create, or recreate, the transaction log. Returns 0 if ok, -1 if error. */ -int mail_transaction_log_create(struct mail_transaction_log *log); +int mail_transaction_log_create(struct mail_transaction_log *log, bool reset); /* Close all the open transactions log files. */ void mail_transaction_log_close(struct mail_transaction_log *log); -- 2.47.3