mail-index-view-sync.c revision 7761758f43d6150be4b07f4c54457ce662f78c4c
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#include "mail-index-view-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-sync-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-log.h"
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_view_sync_ctx {
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen struct mail_index_view *view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_transaction_type visible_sync_mask;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_sync_map_ctx sync_map_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ARRAY_TYPE(seq_range) expunges;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen const struct mail_transaction_header *hdr;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen const void *data;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen size_t data_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int sync_map_update:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int skipped_appends:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int skipped_expunges:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int last_read:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_transaction_log_sort_expunges(ARRAY_TYPE(seq_range) *expunges,
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen const struct seq_range *src, size_t src_size)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen{
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen /* Note that all the sequences are actually still UIDs at this point */
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen const struct seq_range *src_end;
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen struct seq_range *dest, new_exp;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen unsigned int first, i, dest_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(src_size % sizeof(*src) == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* @UNSAFE */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (dest_count == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_append(expunges, src, src_size / sizeof(*src));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen src_end = CONST_PTR_OFFSET(src, src_size);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen for (i = 0; src != src_end; src++) {
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen /* src[] must be sorted. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (src->seq1 > src->seq2 ||
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen (src+1 != src_end && src->seq2 >= src[1].seq1))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (; i < dest_count; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (src->seq1 < dest[i].seq1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen new_exp = *src;
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen first = i;
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen while (i < dest_count && src->seq2 >= dest[i].seq1-1) {
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen /* we can/must merge with next record */
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen if (new_exp.seq2 < dest[i].seq2)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen new_exp.seq2 = dest[i].seq2;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i++;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (first > 0 && new_exp.seq1 <= dest[first-1].seq2+1) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen /* continue previous record */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (dest[first-1].seq2 < new_exp.seq2)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen dest[first-1].seq2 = new_exp.seq2;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen } else if (i == first) {
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen array_insert(expunges, i, &new_exp, 1);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i++; first++;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen dest = array_get_modifiable(expunges, &dest_count);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen } else {
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen /* use next record */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen dest[first] = new_exp;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen first++;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (i > first) {
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen array_delete(expunges, first, i - first);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i = first;
ab286a8b58306eb8d22fc18342b6c199fd428e1eTimo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen return 0;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic void view_sync_get_tail(struct mail_index_view *view,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t *seq_r, uoff_t *offset_r)
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen{
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (LOG_IS_BEFORE(view->log_file_append_seq,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen view->log_file_append_offset,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen view->log_file_expunge_seq,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen view->log_file_expunge_offset)) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *seq_r = view->log_file_append_seq;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *offset_r = view->log_file_append_offset;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen } else {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *seq_r = view->log_file_expunge_seq;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen *offset_r = view->log_file_expunge_offset;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen i_assert(!LOG_IS_BEFORE(view->log_file_head_seq,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen view->log_file_head_offset,
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen *seq_r, *offset_r));
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainenstatic int view_sync_set_log_view_range(struct mail_index_view *view)
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen{
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen const struct mail_index_header *hdr = view->index->hdr;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen uint32_t tail_seq;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen uoff_t tail_offset;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen int ret;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen view_sync_get_tail(view, &tail_seq, &tail_offset);
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen /* the view begins from the first non-synced transaction */
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen ret = mail_transaction_log_view_set(view->log_view,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen tail_seq, tail_offset,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen hdr->log_file_seq,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen hdr->log_file_head_offset);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (ret <= 0) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (ret == 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* FIXME: use the new index to get needed changes */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen mail_index_set_error(view->index,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen "Transaction log got desynced for index %s",
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen view->index->filepath);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen mail_index_set_inconsistent(view->index);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen return -1;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen return 0;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic int
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenview_sync_get_expunges(struct mail_index_view *view,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ARRAY_TYPE(seq_range) *expunges_r)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen const struct mail_transaction_header *hdr;
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen struct seq_range *src, *src_end, *dest;
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen const void *data;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen unsigned int count;
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen int ret;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (view_sync_set_log_view_range(view) < 0)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen return -1;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* get a list of expunge transactions. there may be some that we have
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen already synced, but it doesn't matter because they'll get dropped
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen out when converting to sequences */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_array_init(expunges_r, 64);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen &hdr, &data)) > 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen continue;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* this is simply a request for expunge */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen continue;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (mail_transaction_log_sort_expunges(expunges_r, data,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen hdr->size) < 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen "Corrupted expunge record");
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ret = -1;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen break;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
7c95b03620a03a43dd72d39608cea5fc77393ad6Timo Sirainen if (ret < 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen array_free(expunges_r);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen return -1;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* convert UIDs to sequences */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen src = dest = array_get_modifiable(expunges_r, &count);
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen src_end = src + count;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen for (; src != src_end; src++) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen ret = mail_index_lookup_uid_range(view, src->seq1,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen src->seq2,
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen &dest->seq1,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen &dest->seq2);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_assert(ret == 0);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (dest->seq1 == 0)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen count--;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen else
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen dest++;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen array_delete(expunges_r, count, array_count(expunges_r) - count);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen return 0;
ab286a8b58306eb8d22fc18342b6c199fd428e1eTimo Sirainen}
ab286a8b58306eb8d22fc18342b6c199fd428e1eTimo Sirainen
7c95b03620a03a43dd72d39608cea5fc77393ad6Timo Sirainenstatic void mail_index_view_hdr_drop_appends(struct mail_index_view *view,
7c95b03620a03a43dd72d39608cea5fc77393ad6Timo Sirainen struct mail_index_map *map)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen{
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* Keep message count the same. */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen map->hdr.next_uid = view->hdr.next_uid;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen map->hdr.messages_count = view->hdr.messages_count;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* Keep the old message flag counts also, although they may be
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen somewhat stale already. We just don't want them to be more than
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen our old messages_count. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen map->hdr.recent_messages_count = view->hdr.recent_messages_count;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen map->hdr.seen_messages_count = view->hdr.seen_messages_count;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen map->hdr.deleted_messages_count = view->hdr.deleted_messages_count;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen}
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen#ifdef DEBUG
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic void mail_index_view_check(struct mail_index_view *view)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen{
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen unsigned int i, del = 0, recent = 0, seen = 0;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_assert(view->hdr.messages_count == view->map->records_count);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_assert(view->hdr.deleted_messages_count ==
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen view->map->hdr.deleted_messages_count);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_assert(view->hdr.recent_messages_count ==
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen view->map->hdr.recent_messages_count);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_assert(view->hdr.seen_messages_count ==
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen view->map->hdr.seen_messages_count);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (i = 0; i < view->map->records_count; i++) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const struct mail_index_record *rec;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, i);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (rec->flags & MAIL_DELETED) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_assert(rec->uid >= view->hdr.first_deleted_uid_lowwater);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen del++;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (rec->flags & MAIL_RECENT) {
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_assert(rec->uid >= view->hdr.first_recent_uid_lowwater);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen recent++;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen if (rec->flags & MAIL_SEEN)
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen seen++;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen else
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_assert(rec->uid >= view->hdr.first_unseen_uid_lowwater);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_assert(del == view->hdr.deleted_messages_count);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_assert(recent == view->hdr.recent_messages_count);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_assert(seen == view->hdr.seen_messages_count);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen}
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen#endif
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen#define MAIL_INDEX_VIEW_VISIBLE_FLAGS_MASK \
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen (MAIL_INDEX_SYNC_TYPE_FLAGS | \
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET | \
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD | MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen#define MAIL_TRANSACTION_VISIBLE_SYNC_MASK \
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen (MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE | \
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen MAIL_TRANSACTION_KEYWORD_RESET)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen#define VIEW_IS_SYNCED_TO_SAME(hdr, tail_seq, tail_offset) \
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ((hdr)->log_file_seq == (tail_seq) && \
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen (hdr)->log_file_head_offset == (tail_offset))
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen enum mail_index_view_sync_flags flags,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen struct mail_index_view_sync_ctx **ctx_r)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_view_sync_ctx *ctx;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen struct mail_index_map *map;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint32_t tail_seq;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uoff_t tail_offset;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen enum mail_transaction_type visible_mask = 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ARRAY_TYPE(seq_range) expunges = ARRAY_INIT;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen i_assert(!view->syncing);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(view->transactions == 0);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_view_lock_head(view) < 0)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen return -1;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0) {
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* get list of all expunges first */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_sync_get_expunges(view, &expunges) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen visible_mask = MAIL_TRANSACTION_VISIBLE_SYNC_MASK;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen visible_mask = MAIL_TRANSACTION_VISIBLE_SYNC_MASK &
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ~MAIL_TRANSACTION_EXPUNGE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_sync_set_log_view_range(view) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (array_is_created(&expunges))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_free(&expunges);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen ctx->view = view;
8830fab191cab8440281eb641dfdd93974b2933bTimo Sirainen ctx->visible_sync_mask = visible_mask;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen ctx->expunges = expunges;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_SYNC_HANDLER_VIEW);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
92888ef30960c30ccc9e030fe7eab5d4d04a7d1cTimo Sirainen if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->sync_new_map = view->index->map;
92888ef30960c30ccc9e030fe7eab5d4d04a7d1cTimo Sirainen view->sync_new_map->refcount++;
92888ef30960c30ccc9e030fe7eab5d4d04a7d1cTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* since we're syncing everything, the counters get fixed */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->broken_counters = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* keep the old mapping without expunges until we're
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen fully synced */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen } else {
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* We need a private copy of the map if we don't want to
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen sync expunges.
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen If view's map is the head map, it means that it contains
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen already all the latest changes and there's no need for us
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen to apply any changes to it. This can only happen if there
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen hadn't been any expunges. */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen uint32_t old_records_count = view->map->records_count;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (view->map != view->index->map) {
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* Using non-head mapping. We have to apply
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen transactions to it to get latest changes into it. */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen ctx->sync_map_update = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Unless map was synced at the exact same position as
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen view, the message flags can't be reliably used to
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen update flag counters. note that map->hdr may contain
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen old information if another process updated the
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index file since. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view->map->mmap_base != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen hdr = view->map->mmap_base;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->map->hdr = *hdr;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view_sync_get_tail(view, &tail_seq, &tail_offset);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen ctx->sync_map_ctx.unreliable_flags =
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen !VIEW_IS_SYNCED_TO_SAME(&view->map->hdr,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen tail_seq, tail_offset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->sync_map_update) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Copy only the mails that we see currently, since
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen we're going to append the new ones when we see
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen their transactions. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(view->map->records_count >=
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen view->hdr.messages_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->map->records_count = view->hdr.messages_count;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen }
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#ifdef DEBUG
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (!ctx->sync_map_ctx.unreliable_flags) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen i_assert(view->map->hdr.messages_count ==
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen view->hdr.messages_count);
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen mail_index_view_check(view);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen }
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#endif
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen map = mail_index_map_clone(view->map);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen view->map->records_count = old_records_count;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen mail_index_unmap(view->index, &view->map);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen view->map = map;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (ctx->sync_map_update) {
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen /* Start the sync using our old view's header.
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen The old view->hdr may differ from map->hdr if
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen another view sharing the map with us had synced
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen itself. */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen i_assert(map->hdr_base == map->hdr_copy_buf->data);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_index_view_hdr_drop_appends(view, map);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->hdr = map->hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen i_assert(map->records_count == map->hdr.messages_count);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen /* Syncing the view invalidates all previous looked up records.
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen Unreference the mappings this view keeps because of them. */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen mail_index_view_unref_maps(view);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen view->syncing = TRUE;
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen *ctx_r = ctx;
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen return 0;
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen}
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainenstatic bool view_sync_area_find(ARRAY_TYPE(view_log_sync_area) *sync_arr,
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen uint32_t seq, uoff_t offset)
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen{
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen const struct mail_index_view_log_sync_area *syncs;
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen unsigned int i, count;
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen if (!array_is_created(sync_arr))
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen return FALSE;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen syncs = array_get(sync_arr, &count);
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen for (i = 0; i < count; i++) {
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen if (syncs[i].log_file_offset <= offset &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen offset - syncs[i].log_file_offset < syncs[i].length &&
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen syncs[i].log_file_seq == seq)
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen return TRUE;
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen }
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen return FALSE;
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen}
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen
4c1827d5d718d6f610df3209a2eb95a6591698afTimo Sirainenstatic bool
5a4ab3d6e108a899c8b51bebd0094a37b738d5a1Timo Sirainenmail_index_view_sync_want(struct mail_index_view_sync_ctx *ctx,
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen const struct mail_transaction_header *hdr)
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen{
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen struct mail_index_view *view = ctx->view;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen uint32_t seq;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen uoff_t offset, next_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view, &seq, &offset);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen next_offset = offset + sizeof(*hdr) + hdr->size;
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen case MAIL_TRANSACTION_APPEND:
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen if ((ctx->visible_sync_mask & MAIL_TRANSACTION_APPEND) == 0) {
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen i_assert(!LOG_IS_BEFORE(seq, offset,
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen view->log_file_append_seq,
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen view->log_file_append_offset));
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen if (!ctx->skipped_appends) {
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen view->log_file_append_seq = seq;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen view->log_file_append_offset = offset;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen ctx->skipped_appends = TRUE;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen }
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen return FALSE;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen }
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen if (LOG_IS_BEFORE(seq, offset, view->log_file_append_seq,
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen view->log_file_append_offset)) {
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen /* already synced */
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen return FALSE;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen }
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen break;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen case MAIL_TRANSACTION_EXPUNGE:
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen /* expunge request. this will be ignored */
cd65dfcedc603fabbf644be793efb09096f6c1b5Timo Sirainen break;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen }
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen if ((ctx->visible_sync_mask & MAIL_TRANSACTION_EXPUNGE) == 0) {
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen i_assert(!LOG_IS_BEFORE(seq, offset,
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen view->log_file_expunge_seq,
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen view->log_file_expunge_offset));
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (!ctx->skipped_expunges) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen view->log_file_expunge_seq = seq;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->log_file_expunge_offset = offset;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen ctx->skipped_expunges = TRUE;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen }
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen return FALSE;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if (LOG_IS_BEFORE(seq, offset, view->log_file_expunge_seq,
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen view->log_file_expunge_offset)) {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* already synced */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen return FALSE;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen break;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen default:
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if ((hdr->type & ctx->visible_sync_mask) != 0)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen break;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_VISIBLE_SYNC_MASK) == 0)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen break;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* visible record that we want to skip */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen return FALSE;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if (LOG_IS_BEFORE(seq, offset, view->log_file_head_seq,
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen view->log_file_head_offset)) {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* already synced */
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen return FALSE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->log_file_head_seq = seq;
28dd1eeb9fdb93051bb5899c80cf300d69ba9f9eTimo Sirainen view->log_file_head_offset = next_offset;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen return TRUE;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen}
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen
4c1827d5d718d6f610df3209a2eb95a6591698afTimo Sirainenstatic int
4c1827d5d718d6f610df3209a2eb95a6591698afTimo Sirainenmail_index_view_sync_get_next_transaction(struct mail_index_view_sync_ctx *ctx)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen{
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_view *view = ctx->view;
05751847e5e493fecfd0634d35d21722aad44a0bTimo Sirainen const struct mail_transaction_header *hdr;
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen uint32_t seq;
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen uoff_t offset;
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen int ret;
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen bool synced_to_map;
91b5eae18db48ebb70eee5407a7ab52bf798ee12Timo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen for (;;) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* Get the next transaction from log. */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen &ctx->data);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (ret <= 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (ret < 0)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return -1;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ctx->hdr = NULL;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ctx->last_read = TRUE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen return 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen hdr = ctx->hdr;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (!mail_index_view_sync_want(ctx, hdr)) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* This is a visible record that we don't want to
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen sync. */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen continue;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* If we started from a map that we didn't create ourself,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen some of the transactions may already be synced. at the end
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen of this view sync we'll update file_seq=0 so that this check
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen always becomes FALSE for subsequent syncs. */
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen synced_to_map = view->map->hdr.log_file_seq != 0 &&
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen !LOG_IS_BEFORE(seq, offset,
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen view->map->hdr.log_file_seq,
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen view->map->hdr.log_file_head_offset);
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen /* Apply transaction to view's mapping if needed (meaning we
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen didn't just re-map the view to head mapping). */
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen if (ctx->sync_map_update && !synced_to_map) {
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0 ||
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen (hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0);
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen
28dd1eeb9fdb93051bb5899c80cf300d69ba9f9eTimo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx,
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen hdr, ctx->data) < 0)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen return -1;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen }
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if ((hdr->type & ctx->visible_sync_mask) == 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* non-visible change that we just wanted to update
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen to map. */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen continue;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen }
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen /* skip changes committed by hidden transactions (eg. in IMAP
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen store +flags.silent command) */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (view_sync_area_find(&view->syncs_hidden, seq, offset))
b47c57ee07ccfe76cc23b23bc720e17fe9a46d5cTimo Sirainen continue;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen break;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen }
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen return 1;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen}
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen#define FLAG_UPDATE_IS_INTERNAL(u) \
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ((((u)->add_flags | (u)->remove_flags) & \
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ~(MAIL_INDEX_MAIL_FLAG_DIRTY | MAIL_RECENT)) == 0)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainenstatic int
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainenmail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen struct mail_index_view_sync_rec *rec)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen{
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen const struct mail_transaction_header *hdr = ctx->hdr;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen const void *data = ctx->data;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen case MAIL_TRANSACTION_APPEND: {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* data contains the appended records, but we don't care */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid1 = rec->uid2 = 0;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ctx->data_offset += hdr->size;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen break;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen case MAIL_TRANSACTION_EXPUNGE: {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen const struct mail_transaction_expunge *exp =
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* this is simply a request for expunge */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ctx->data_offset = ctx->hdr->size;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen return 0;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* data contains mail_transaction_expunge[] */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_EXPUNGE;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid1 = exp->uid1;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid2 = exp->uid2;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ctx->data_offset += sizeof(*exp);
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen break;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen case MAIL_TRANSACTION_FLAG_UPDATE: {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen const struct mail_transaction_flag_update *update =
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen /* data contains mail_transaction_flag_update[] */
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen for (;;) {
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen ctx->data_offset += sizeof(*update);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if (!FLAG_UPDATE_IS_INTERNAL(update))
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen break;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen /* skip internal flag changes */
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen if (ctx->data_offset == ctx->hdr->size)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen return 0;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen update = CONST_PTR_OFFSET(data, ctx->data_offset);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_FLAGS;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid1 = update->uid1;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid2 = update->uid2;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen break;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen case MAIL_TRANSACTION_KEYWORD_UPDATE: {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen const struct mail_transaction_keyword_update *update = data;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen const uint32_t *uids;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen /* data contains mail_transaction_keyword_update header,
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen the keyword name and an array of { uint32_t uid1, uid2; } */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if (ctx->data_offset == 0) {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* skip over the header and name */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ctx->data_offset = sizeof(*update) + update->name_size;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if ((ctx->data_offset % 4) != 0)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ctx->data_offset += 4 - (ctx->data_offset % 4);
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen uids = CONST_PTR_OFFSET(data, ctx->data_offset);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid1 = uids[0];
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid2 = uids[1];
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen ctx->data_offset += sizeof(uint32_t) * 2;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen break;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen case MAIL_TRANSACTION_KEYWORD_RESET: {
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen const struct mail_transaction_keyword_reset *reset =
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen /* data contains mail_transaction_keyword_reset[] */
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid1 = reset->uid1;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen rec->uid2 = reset->uid2;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen ctx->data_offset += sizeof(*reset);
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen break;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen }
09714f2f8d4c8cc7d89930f7eb836816d8dc9eb8Timo Sirainen default:
09714f2f8d4c8cc7d89930f7eb836816d8dc9eb8Timo Sirainen i_unreached();
09714f2f8d4c8cc7d89930f7eb836816d8dc9eb8Timo Sirainen }
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen return 1;
09714f2f8d4c8cc7d89930f7eb836816d8dc9eb8Timo Sirainen}
09714f2f8d4c8cc7d89930f7eb836816d8dc9eb8Timo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen struct mail_index_view_sync_rec *sync_rec)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen{
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen int ret;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen do {
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (ctx->hdr == NULL || ctx->data_offset == ctx->hdr->size) {
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen ret = mail_index_view_sync_get_next_transaction(ctx);
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen if (ret <= 0)
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen return ret;
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen ctx->data_offset = 0;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen }
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen } while (!mail_index_view_sync_get_rec(ctx, sync_rec));
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen return 1;
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen}
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainenvoid mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen const ARRAY_TYPE(seq_range) **expunges_r)
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen{
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen *expunges_r = &ctx->expunges;
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen}
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenstatic void
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenmail_index_view_sync_clean_log_syncs(struct mail_index_view *view)
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen{
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen const struct mail_index_view_log_sync_area *syncs;
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen uint32_t tail_seq;
e4fb5bfcdff32d337d054cce36e00e1cdfaae9f8Timo Sirainen uoff_t tail_offset;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen unsigned int i, count;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (!array_is_created(&view->syncs_hidden))
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen return;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen /* Clean up to view's tail */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen view_sync_get_tail(view, &tail_seq, &tail_offset);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen syncs = array_get(&view->syncs_hidden, &count);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen for (i = 0; i < count; i++) {
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if ((syncs[i].log_file_offset + syncs[i].length > tail_offset &&
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen syncs[i].log_file_seq == tail_seq) ||
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen syncs[i].log_file_seq > tail_seq)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen break;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen }
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (i > 0)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen array_delete(&view->syncs_hidden, 0, i);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen}
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx **_ctx)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen{
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen struct mail_index_view_sync_ctx *ctx = *_ctx;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen struct mail_index_view *view = ctx->view;
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen i_assert(view->syncing);
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen *_ctx = NULL;
19593623a2278039be23fc93e3404c012920b664Timo Sirainen
19593623a2278039be23fc93e3404c012920b664Timo Sirainen if (!ctx->last_read) {
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen /* we didn't sync everything */
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen view->inconsistent = TRUE;
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen }
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen if (view->sync_new_map != NULL) {
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen mail_index_unmap(view->index, &view->map);
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen view->map = view->sync_new_map;
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen view->sync_new_map = NULL;
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen }
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen if (!ctx->skipped_expunges) {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->log_file_expunge_seq = view->log_file_head_seq;
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen view->log_file_expunge_offset = view->log_file_head_offset;
0ce3bbb0f03fb0ee99258b41b5a1d689c1158a75Timo Sirainen }
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen if (!ctx->skipped_appends) {
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen view->log_file_append_seq = view->log_file_head_seq;
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen view->log_file_append_offset = view->log_file_head_offset;
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen }
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen if (ctx->sync_map_update) {
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen /* log offsets have no meaning in views. make sure they're not
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen tried to be used wrong by setting them to zero. */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen view->map->hdr.log_file_seq = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->map->hdr.log_file_head_offset = 0;
45edf6cad665a5c270322516c587708a0c630b80Timo Sirainen view->map->hdr.log_file_tail_offset = 0;
68917b81c83e8a4d18a81cda188ffa5cb643c46cTimo Sirainen }
68917b81c83e8a4d18a81cda188ffa5cb643c46cTimo Sirainen view->hdr = view->map->hdr;
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen mail_index_sync_map_deinit(&ctx->sync_map_ctx);
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen mail_index_view_sync_clean_log_syncs(ctx->view);
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#ifdef DEBUG
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (!view->broken_counters && !ctx->sync_map_ctx.unreliable_flags)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen mail_index_view_check(view);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#endif
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen /* set log view to empty range so unneeded memory gets freed */
e2ea49bd487d76b425e270321e9cf1e546642de0Timo Sirainen (void)mail_transaction_log_view_set(view->log_view,
c48140ca508ebc9642737e7fd6c8d9e52f95df32Timo Sirainen view->log_file_head_seq,
c48140ca508ebc9642737e7fd6c8d9e52f95df32Timo Sirainen view->log_file_head_offset,
c48140ca508ebc9642737e7fd6c8d9e52f95df32Timo Sirainen view->log_file_head_seq,
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen view->log_file_head_offset);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen if (array_is_created(&ctx->expunges))
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen array_free(&ctx->expunges);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen view->syncing = FALSE;
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen i_free(ctx);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen}
c48140ca508ebc9642737e7fd6c8d9e52f95df32Timo Sirainen
c48140ca508ebc9642737e7fd6c8d9e52f95df32Timo Sirainenvoid mail_index_view_add_hidden_transaction(struct mail_index_view *view,
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen uint32_t log_file_seq,
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen uoff_t log_file_offset,
c48140ca508ebc9642737e7fd6c8d9e52f95df32Timo Sirainen unsigned int length)
c48140ca508ebc9642737e7fd6c8d9e52f95df32Timo Sirainen{
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct mail_index_view_log_sync_area *area;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (!array_is_created(&view->syncs_hidden))
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_array_init(&view->syncs_hidden, 32);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen area = array_append_space(&view->syncs_hidden);
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen area->log_file_seq = log_file_seq;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen area->log_file_offset = log_file_offset;
3c24d47ad5ff02ea00684233bef314ef2eefda4aTimo Sirainen area->length = length;
19593623a2278039be23fc93e3404c012920b664Timo Sirainen}
19593623a2278039be23fc93e3404c012920b664Timo Sirainen