struct index_vsize_header {
uint64_t vsize;
uint32_t highest_uid;
+ uint32_t message_count;
};
struct maildir_index_header {
uint32_t new_check_time, new_mtime, new_mtime_nsecs;
const struct index_vsize_header *hdr = data;
printf("header\n");
- printf(" - highest uid = %u\n", hdr->highest_uid);
- printf(" - vsize ..... = %llu\n", (unsigned long long)hdr->vsize);
+ printf(" - highest uid . = %u\n", hdr->highest_uid);
+ printf(" - message count = %u\n", hdr->message_count);
+ printf(" - vsize ....... = %llu\n", (unsigned long long)hdr->vsize);
} else if (strcmp(ext->name, "maildir") == 0) {
const struct maildir_index_header *hdr = data;
int ret = 0;
hdr = mail_index_get_header(box->view);
- if (!mail_index_lookup_seq_range(box->view, vsize_hdr->highest_uid+1,
- hdr->next_uid, &seq1, &seq2)) {
- /* the last messages are already expunged,
- don't bother updating cache */
- return;
+ if (vsize_hdr->highest_uid == 0)
+ seq2 = 0;
+ else if (!mail_index_lookup_seq_range(box->view, 1,
+ vsize_hdr->highest_uid,
+ &seq1, &seq2))
+ seq2 = 0;
+
+ if (vsize_hdr->message_count != seq2) {
+ if (vsize_hdr->message_count < seq2) {
+ mail_storage_set_critical(box->storage,
+ "vsize-hdr has invalid message-count (%u < %u)",
+ vsize_hdr->message_count, seq2);
+ } else {
+ /* some messages have been expunged, rescan */
+ }
+ memset(vsize_hdr, 0, sizeof(*vsize_hdr));
+ seq2 = 0;
}
search_args = mail_search_build_init();
- mail_search_build_add_seqset(search_args, seq1, seq2);
+ mail_search_build_add_seqset(search_args, seq2 + 1,
+ hdr->messages_count);
trans = mailbox_transaction_begin(box, 0);
search_ctx = mailbox_search_init(trans, search_args, NULL);
}
vsize_hdr->vsize += vsize;
vsize_hdr->highest_uid = mail->uid;
+ vsize_hdr->message_count++;
}
mail_free(&mail);
if (mailbox_search_deinit(&search_ctx) < 0)
memset(&vsize_hdr, 0, sizeof(vsize_hdr));
}
- if (vsize_hdr.highest_uid + 1 == status_r->uidnext) {
+ if (vsize_hdr.highest_uid + 1 == status_r->uidnext &&
+ vsize_hdr.message_count == status_r->messages) {
/* up to date */
status_r->virtual_size = vsize_hdr.vsize;
return;