From: Timo Sirainen Date: Mon, 24 May 2004 02:29:43 +0000 (+0300) Subject: Some more UIDVALIDITY issues fixed. X-Git-Tag: 1.1.alpha1~4055 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92888ef30960c30ccc9e030fe7eab5d4d04a7d1c;p=thirdparty%2Fdovecot%2Fcore.git Some more UIDVALIDITY issues fixed. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-index-fsck.c b/src/lib-index/mail-index-fsck.c index ebcbda4496..76bb8599a2 100644 --- a/src/lib-index/mail-index-fsck.c +++ b/src/lib-index/mail-index-fsck.c @@ -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; } diff --git a/src/lib-index/mail-index.c b/src/lib-index/mail-index.c index 2d9a33c25d..8088d70c94 100644 --- a/src/lib-index/mail-index.c +++ b/src/lib-index/mail-index.c @@ -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; } diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index 4f807a76b2..868bcf6cb1 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -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 */ diff --git a/src/lib-storage/index/maildir/maildir-sync.c b/src/lib-storage/index/maildir/maildir-sync.c index 2011c1e113..782e80898d 100644 --- a/src/lib-storage/index/maildir/maildir-sync.c +++ b/src/lib-storage/index/maildir/maildir-sync.c @@ -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)); diff --git a/src/lib-storage/index/maildir/maildir-uidlist.c b/src/lib-storage/index/maildir/maildir-uidlist.c index ed103095e8..b89b898889 100644 --- a/src/lib-storage/index/maildir/maildir-uidlist.c +++ b/src/lib-storage/index/maildir/maildir-uidlist.c @@ -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; diff --git a/src/lib-storage/index/maildir/maildir-uidlist.h b/src/lib-storage/index/maildir/maildir-uidlist.h index c2868b2d71..c08ac9a6ca 100644 --- a/src/lib-storage/index/maildir/maildir-uidlist.h +++ b/src/lib-storage/index/maildir/maildir-uidlist.h @@ -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);