]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Some more UIDVALIDITY issues fixed.
authorTimo Sirainen <tss@iki.fi>
Mon, 24 May 2004 02:29:43 +0000 (05:29 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 24 May 2004 02:29:43 +0000 (05:29 +0300)
--HG--
branch : HEAD

src/lib-index/mail-index-fsck.c
src/lib-index/mail-index.c
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/maildir/maildir-sync.c
src/lib-storage/index/maildir/maildir-uidlist.c
src/lib-storage/index/maildir/maildir-uidlist.h

index ebcbda4496891dd5aacd933a2b525fb6d5b9e801..76bb8599a29c9433a23153e9d69ecd96ed6b817f 100644 (file)
@@ -35,8 +35,8 @@ static int mail_index_fsck_locked(struct mail_index *index,
        /* locking already does the most important sanity checks for header */
        hdr = *index->hdr;
 
-       if (hdr.uid_validity == 0) {
-               *error_r = "uid_validity = 0";
+       if (hdr.uid_validity == 0 && hdr.next_uid != 1) {
+               *error_r = "uid_validity = 0 && next_uid != 1";
                return 0;
        }
 
index 2d9a33c25d401fc131c547e548f9c7f1351d0db3..8088d70c94f3f1bbdb9f79b3059623bb7918144f 100644 (file)
@@ -68,9 +68,10 @@ static int mail_index_check_header(struct mail_index *index,
        }
 
        /* following some extra checks that only take a bit of CPU */
-       if (hdr->uid_validity == 0) {
+       if (hdr->uid_validity == 0 && hdr->next_uid != 1) {
                mail_index_set_error(index, "Corrupted index file %s: "
-                                    "uid_validity = 0", index->filepath);
+                                    "uid_validity = 0, next_uid = %u",
+                                    index->filepath, hdr->next_uid);
                return -1;
        }
 
@@ -379,7 +380,6 @@ void mail_index_header_init(struct mail_index_header *hdr)
 
        hdr->indexid = now;
 
-       hdr->uid_validity = now;
        hdr->next_uid = 1;
 }
 
index 4f807a76b27180deed675b1c1f6d46185f38076d..868bcf6cb1eb468ba64110dd35cd4a0ca04d6d33 100644 (file)
@@ -407,7 +407,6 @@ maildir_open(struct index_storage *storage, const char *name,
 {
        struct index_mailbox *ibox;
        struct mail_index *index;
-       const struct mail_index_header *hdr;
        const char *path, *index_dir, *control_dir;
        struct stat st;
 
@@ -422,17 +421,12 @@ maildir_open(struct index_storage *storage, const char *name,
        if (ibox == NULL)
                return NULL;
 
-       if (mail_index_get_header(ibox->view, &hdr) < 0) {
-               index_storage_mailbox_free(&ibox->box);
-               return NULL;
-       }
-
        ibox->path = i_strdup(path);
        ibox->control_dir = i_strdup(control_dir);
 
        ibox->get_recent_count = maildir_get_recent_count;
        ibox->mail_interface = &maildir_mail;
-       ibox->uidlist = maildir_uidlist_init(ibox, hdr->uid_validity);
+       ibox->uidlist = maildir_uidlist_init(ibox);
 
        /* for shared mailboxes get the create mode from the
           permissions of dovecot-shared file */
index 2011c1e1130f16afa69bb5088eb61501f2b37d10..782e80898df3c518f78e574fbb4dba496d4903ca 100644 (file)
@@ -593,7 +593,8 @@ static int maildir_sync_index(struct maildir_sync_context *ctx)
        i_assert(ret == 0); /* view is locked, can't happen */
 
        uid_validity = maildir_uidlist_get_uid_validity(ibox->uidlist);
-       if (uid_validity != hdr->uid_validity && hdr->next_uid != 1) {
+       if (uid_validity != hdr->uid_validity &&
+           uid_validity != 0 && hdr->uid_validity != 0) {
                /* uidvalidity changed and mailbox isn't being initialized,
                   index must be rebuilt */
                mail_storage_set_critical(ibox->box.storage,
@@ -737,7 +738,22 @@ static int maildir_sync_index(struct maildir_sync_context *ctx)
                        &sync_stamp, sizeof(sync_stamp));
        }
 
-       if (uid_validity != hdr->uid_validity) {
+       if (hdr->uid_validity == 0) {
+               /* get the initial uidvalidity */
+               if (maildir_uidlist_update(ibox->uidlist) < 0)
+                       ret = -1;
+               uid_validity = maildir_uidlist_get_uid_validity(ibox->uidlist);
+               if (uid_validity == 0) {
+                       uid_validity = ioloop_time;
+                       maildir_uidlist_set_uid_validity(ibox->uidlist,
+                                                        uid_validity);
+               }
+       } else if (uid_validity == 0) {
+               maildir_uidlist_set_uid_validity(ibox->uidlist,
+                                                hdr->uid_validity);
+       }
+
+       if (uid_validity != hdr->uid_validity && uid_validity != 0) {
                mail_index_update_header(trans,
                        offsetof(struct mail_index_header, uid_validity),
                        &uid_validity, sizeof(uid_validity));
index ed103095e8d677968a7c40f000dc1cb3a23925cc..b89b89888908f54cedfaf65a36e15e334ebd7b19 100644 (file)
@@ -45,6 +45,7 @@ struct maildir_uidlist {
 
        unsigned int initial_read:1;
        unsigned int initial_sync:1;
+       unsigned int file_missing:1;
 };
 
 struct maildir_uidlist_sync_ctx {
@@ -109,8 +110,7 @@ void maildir_uidlist_unlock(struct maildir_uidlist *uidlist)
        uidlist->lock_fd = -1;
 }
 
-struct maildir_uidlist *
-maildir_uidlist_init(struct index_mailbox *ibox, uint32_t uid_validity)
+struct maildir_uidlist *maildir_uidlist_init(struct index_mailbox *ibox)
 {
        struct maildir_uidlist *uidlist;
 
@@ -124,7 +124,6 @@ maildir_uidlist_init(struct index_mailbox *ibox, uint32_t uid_validity)
        uidlist->files = hash_create(default_pool, default_pool, 4096,
                                     maildir_hash, maildir_cmp);
 
-       uidlist->uid_validity = uid_validity;
        uidlist->next_uid = 1;
 
        return uidlist;
@@ -258,9 +257,11 @@ int maildir_uidlist_update(struct maildir_uidlist *uidlist)
                                "open(%s) failed: %m", uidlist->fname);
                        return -1;
                }
+               uidlist->file_missing = TRUE;
                uidlist->initial_read = TRUE;
                return 0;
        }
+       uidlist->file_missing = FALSE;
 
        if (fstat(fd, &st) < 0) {
                mail_storage_set_critical(storage,
@@ -422,6 +423,12 @@ uint32_t maildir_uidlist_get_uid_validity(struct maildir_uidlist *uidlist)
        return uidlist->uid_validity;
 }
 
+void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist,
+                                     uint32_t uid_validity)
+{
+       uidlist->uid_validity = uid_validity;
+}
+
 uint32_t maildir_uidlist_get_next_uid(struct maildir_uidlist *uidlist)
 {
        return !uidlist->initial_read ? 0 : uidlist->next_uid;
@@ -439,7 +446,10 @@ static int maildir_uidlist_rewrite_fd(struct maildir_uidlist *uidlist,
        const char *filename, *flags_str;
        int ret = 0;
 
-        uidlist->version = 2;
+       uidlist->version = 2;
+
+       if (uidlist->uid_validity == 0)
+               uidlist->uid_validity = ioloop_time;
 
        str = t_str_new(4096);
        str_printfa(str, "%u %u %u\n", uidlist->version,
@@ -516,6 +526,8 @@ static int maildir_uidlist_rewrite(struct maildir_uidlist *uidlist)
                        mail_storage_set_critical(ibox->box.storage,
                                "file_dotlock_replace(%s) failed: %m", db_path);
                        ret = -1;
+               } else {
+                       uidlist->file_missing = FALSE;
                }
        } else {
                (void)close(uidlist->lock_fd);
@@ -624,6 +636,12 @@ maildir_uidlist_sync_next_partial(struct maildir_uidlist_sync_ctx *ctx,
                }
                ctx->new_files_count++;
 
+               if (uidlist->record_pool == NULL) {
+                       uidlist->record_pool =
+                               pool_alloconly_create("uidlist record_pool",
+                                                     1024);
+               }
+
                rec = p_new(uidlist->record_pool,
                            struct maildir_uidlist_rec, 1);
                rec->uid = (uint32_t)-1;
index c2868b2d7137da8118ab82bc0024d9f2d4df4e16..c08ac9a6ca06697fc0320d62e0c2f6c9c311acad 100644 (file)
@@ -13,8 +13,7 @@ enum maildir_uidlist_rec_flag {
 int maildir_uidlist_try_lock(struct maildir_uidlist *uidlist);
 void maildir_uidlist_unlock(struct maildir_uidlist *uidlist);
 
-struct maildir_uidlist *
-maildir_uidlist_init(struct index_mailbox *ibox, uint32_t uid_validity);
+struct maildir_uidlist *maildir_uidlist_init(struct index_mailbox *ibox);
 void maildir_uidlist_deinit(struct maildir_uidlist *uidlist);
 
 /* Returns -1 if error, 0 if file is broken or lost, 1 if ok. */
@@ -32,6 +31,9 @@ uint32_t maildir_uidlist_get_recent_count(struct maildir_uidlist *uidlist);
 uint32_t maildir_uidlist_get_uid_validity(struct maildir_uidlist *uidlist);
 uint32_t maildir_uidlist_get_next_uid(struct maildir_uidlist *uidlist);
 
+void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist,
+                                     uint32_t uid_validity);
+
 /* Sync uidlist with what's actually on maildir. */
 struct maildir_uidlist_sync_ctx *
 maildir_uidlist_sync_init(struct maildir_uidlist *uidlist, int partial);