]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixes to handling races in initial index creation.
authorTimo Sirainen <tss@iki.fi>
Thu, 29 May 2008 23:09:20 +0000 (02:09 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 29 May 2008 23:09:20 +0000 (02:09 +0300)
--HG--
branch : HEAD

src/lib-index/mail-index-private.h
src/lib-index/mail-index.c
src/lib-index/mail-transaction-log-file.c
src/lib-index/mail-transaction-log.c
src/lib-index/mail-transaction-log.h

index e7f87cab210f89ecc37ce2fb940c5c34111a1976..42b928a4556dae4b5301ed19f2cb5f0d4af87000 100644 (file)
@@ -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;
index 95fa4c0e020d6e1eed992b3ca554f5822726ddb7..8c16e379706110d33b3c986dd2d325567379a89e 100644 (file)
@@ -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);
index 1dfbb4efadb145204d729a325ac9b6659da992c7..792b28a5269075907c4566f9682218760a0ebbde 100644 (file)
@@ -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);
index 08642be1a01247646310d459ea69895dafcc8b2e..0e8800faaceb1443c1fa58902526748cb27ea033 100644 (file)
@@ -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--;
index b3445fa1ea43f482a336c1914d9e9a9bf811a4ca..b9defdef3dc6bcd0a25290f6c1e06cf17ed88d2f 100644 (file)
@@ -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);