]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Some fixes to opening index.
authorTimo Sirainen <tss@iki.fi>
Wed, 16 Apr 2003 15:13:24 +0000 (18:13 +0300)
committerTimo Sirainen <tss@iki.fi>
Wed, 16 Apr 2003 15:13:24 +0000 (18:13 +0300)
--HG--
branch : HEAD

src/lib-index/mail-index-open.c
src/lib-index/mail-tree.c
src/lib-index/mail-tree.h
src/lib-index/maildir/maildir-rebuild.c
src/lib-index/maildir/maildir-sync.c

index 2f348f88362ecdb4385592c5b1571a28b76eaed6..b0e67bb8ad7e642723de1ca6141f86f0598603bc 100644 (file)
@@ -301,11 +301,86 @@ static int mail_index_create_memory(struct mail_index *index,
        return TRUE;
 }
 
+static int mail_index_open_index(struct mail_index *index,
+                                enum mail_index_open_flags flags)
+{
+       struct mail_index_header hdr;
+       int ret;
+
+       if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0)
+               index->lock_type = MAIL_LOCK_SHARED;
+       else
+               index->lock_type = MAIL_LOCK_EXCLUSIVE;
+
+       /* if index is being created, we'll wait here until it's finished */
+       if (!mail_index_wait_lock(index, MAIL_LOCK_TO_FLOCK(index->lock_type)))
+               return FALSE;
+#ifdef DEBUG
+       if (index->mmap_base != NULL) {
+               mprotect(index->mmap_base, index->mmap_used_length,
+                        PROT_READ|PROT_WRITE);
+       }
+#endif
+
+       if ((ret = mail_index_read_header(index, &hdr)) < 0)
+               return FALSE;
+
+       if (ret == 0 || !mail_index_is_compatible(&hdr)) {
+               if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
+                       return FALSE;
+
+               flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
+
+               /* so, we're creating the index */
+               if (index->lock_type != MAIL_LOCK_EXCLUSIVE) {
+                       /* have to get exclusive lock first */
+                       if (!mail_index_wait_lock(index, F_UNLCK))
+                               return FALSE;
+                       return mail_index_open_index(index, flags);
+               }
+
+               mail_index_init_header(index, &hdr);
+               if (!mail_index_init_file(index, &hdr))
+                       return FALSE;
+       }
+
+       index->indexid = hdr.indexid;
+
+       if (!mail_index_mmap_update(index))
+               return FALSE;
+
+       if (index->lock_type == MAIL_LOCK_SHARED) {
+               /* we don't want to keep the shared lock while opening
+                  indexes. opening should work unlocked and some
+                  things want exclusive lock */
+               if (!mail_index_wait_lock(index, F_UNLCK))
+                       return FALSE;
+               index->lock_type = MAIL_LOCK_UNLOCK;
+       }
+
+       if (!index_open_and_fix(index, flags)) {
+               if ((index->set_flags & MAIL_INDEX_FLAG_REBUILD) == 0 ||
+                   (flags & _MAIL_INDEX_OPEN_FLAG_CREATING) != 0)
+                       return FALSE;
+
+               /* needs a rebuild */
+               if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
+                       return FALSE;
+
+               flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
+               return mail_index_open_index(index, flags);
+       }
+
+       if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
+               return FALSE;
+
+       index->opened = TRUE;
+       return TRUE;
+}
+
 int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
 {
-        struct mail_index_header hdr;
        const char *path;
-       int ret;
 
        i_assert(!index->opened);
 
@@ -328,68 +403,10 @@ int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
 
        index->filepath = i_strdup(path);
 
-       for (;;) {
-               /* if index is being created, we'll wait here until it's
-                  finished */
-               if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0)
-                       index->lock_type = MAIL_LOCK_SHARED;
-               else
-                       index->lock_type = MAIL_LOCK_EXCLUSIVE;
-               if (!mail_index_wait_lock(index,
-                                         MAIL_LOCK_TO_FLOCK(index->lock_type)))
-                       break;
-
-               if ((ret = mail_index_read_header(index, &hdr)) < 0)
-                       break;
-
-               if (ret == 0 || !mail_index_is_compatible(&hdr)) {
-                       if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
-                               break;
-
-                       flags |= _MAIL_INDEX_OPEN_FLAG_CREATING;
-
-                       /* so, we're creating the index */
-                       if (index->lock_type != MAIL_LOCK_EXCLUSIVE) {
-                               /* have to get exclusive lock first */
-                               if (!mail_index_wait_lock(index, F_UNLCK))
-                                       break;
-                               continue;
-                       }
-
-                       mail_index_init_header(index, &hdr);
-                       if (!mail_index_init_file(index, &hdr))
-                               break;
-               }
-
-               index->indexid = hdr.indexid;
-
-               if (!mail_index_mmap_update(index))
-                       break;
-
-               if (index->lock_type == MAIL_LOCK_SHARED) {
-                       /* we don't want to keep the shared lock while opening
-                          indexes. opening should work unlocked and some
-                          things want exclusive lock */
-                       if (!mail_index_wait_lock(index, F_UNLCK))
-                               break;
-                       index->lock_type = MAIL_LOCK_UNLOCK;
-               }
-
-               if (!index_open_and_fix(index, flags) ||
-                   !index->set_lock(index, MAIL_LOCK_UNLOCK)) {
-                       mail_index_close(index);
-                       return mail_index_create_memory(index, flags);
-               }
-
-               index->opened = TRUE;
-               return TRUE;
+       if (!mail_index_open_index(index, flags)) {
+               mail_index_close(index);
+               return mail_index_create_memory(index, flags);
        }
 
-       (void)close(index->fd);
-       index->fd = -1;
-
-       i_free(index->filepath);
-       index->filepath = NULL;
-
-       return mail_index_create_memory(index, flags);
+       return TRUE;
 }
index 6e939c0ccaa1b1ceb7e92f71aa565ae88ca6cb5d..a9cb231ff02b7d71b37847b2f7c1fe18ee3da080 100644 (file)
@@ -318,6 +318,19 @@ static int mail_tree_init(struct mail_tree *tree)
        return TRUE;
 }
 
+int mail_tree_reset(struct mail_tree *tree)
+{
+       i_assert(tree->index->lock_type == MAIL_LOCK_EXCLUSIVE);
+
+       if (!mail_tree_init(tree) ||
+           (!tree->anon_mmap && !_mail_tree_mmap_update(tree, TRUE))) {
+               tree->index->header->flags |= MAIL_INDEX_FLAG_REBUILD_TREE;
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 int mail_tree_rebuild(struct mail_tree *tree)
 {
        struct mail_index_record *rec;
@@ -325,11 +338,8 @@ int mail_tree_rebuild(struct mail_tree *tree)
        if (!tree->index->set_lock(tree->index, MAIL_LOCK_EXCLUSIVE))
                return FALSE;
 
-       if (!mail_tree_init(tree) ||
-           (!tree->anon_mmap && !_mail_tree_mmap_update(tree, TRUE))) {
-               tree->index->header->flags |= MAIL_INDEX_FLAG_REBUILD_TREE;
+       if (!mail_tree_reset(tree))
                return FALSE;
-       }
 
        rec = tree->index->lookup(tree->index, 1);
        while (rec != NULL) {
index b6c91494ff40266c7a00cedbdb715268fff79e3b..775c8c7da382e82138a9b03fc4da29460ad64215 100644 (file)
@@ -47,6 +47,7 @@ int mail_tree_create(struct mail_index *index);
 int mail_tree_open_or_create(struct mail_index *index);
 void mail_tree_free(struct mail_tree *tree);
 
+int mail_tree_reset(struct mail_tree *tree);
 int mail_tree_rebuild(struct mail_tree *tree);
 int mail_tree_sync_file(struct mail_tree *tree, int *fsync_fd);
 
index a7576f0e0deec8b9bbe6c9412db0a3eb5656043a..9c8f01040fc5859f6fc858dd27ffce74e7003f68 100644 (file)
@@ -4,6 +4,7 @@
 #include "maildir-index.h"
 #include "mail-index-data.h"
 #include "mail-index-util.h"
+#include "mail-tree.h"
 
 #include <unistd.h>
 #include <sys/stat.h>
@@ -35,6 +36,9 @@ int maildir_index_rebuild(struct mail_index *index)
        if (!mail_index_data_reset(index->data))
                return FALSE;
 
+       if (!mail_tree_reset(index->tree))
+               return FALSE;
+
        /* read the mails by syncing */
        if (!index->sync_and_lock(index, MAIL_LOCK_UNLOCK, NULL))
                return FALSE;
index bc0c6be17a665dbd53aecbab8e1342a4ccb05acf..2a1c1b997cf3c37213c22a79fc962f66a49a8961 100644 (file)
@@ -484,13 +484,19 @@ static int maildir_index_lock_and_sync(struct mail_index *index, int *changes,
                if (uidlist != NULL &&
                    uidlist->uid_validity != index->header->uid_validity) {
                        /* uidvalidity changed */
-                       if (!index->rebuilding) {
+                       if (!index->rebuilding && index->opened) {
                                index_set_corrupted(index,
                                        "UIDVALIDITY changed in uidlist");
                                return FALSE;
                        }
 
+                       if (!index->rebuilding) {
+                               index->set_flags |= MAIL_INDEX_FLAG_REBUILD;
+                               return FALSE;
+                       }
+
                        index->header->uid_validity = uidlist->uid_validity;
+                       i_assert(index->header->next_uid == 1);
                }
 
                if (uidlist != NULL &&