mail-index-view-sync.c revision e063aca6bc2f08bec516d4b631052ea9191f011d
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-view-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-sync-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-log.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_view_sync_ctx {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen enum mail_transaction_type visible_sync_mask;
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen struct mail_index_sync_map_ctx sync_map_ctx;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen ARRAY_TYPE(seq_range) expunges;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const void *data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t data_offset;
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen unsigned int skipped_some:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int last_read:1;
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen unsigned int sync_map_update:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstatic int
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainenmail_transaction_log_sort_expunges(ARRAY_TYPE(seq_range) *expunges,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen const struct seq_range *src, size_t src_size)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen{
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen /* Note that all the sequences are actually still UIDs at this point */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen const struct seq_range *src_end;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen struct seq_range *dest, new_exp;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen unsigned int first, i, dest_count;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i_assert(src_size % sizeof(*src) == 0);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* @UNSAFE */
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (dest_count == 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_append(expunges, src, src_size / sizeof(*src));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen src_end = CONST_PTR_OFFSET(src, src_size);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (i = 0; src != src_end; src++) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* src[] must be sorted. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (src->seq1 > src->seq2 ||
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (src+1 != src_end && src->seq2 >= src[1].seq1))
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return -1;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen for (; i < dest_count; i++) {
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (src->seq1 < dest[i].seq1)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen break;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen new_exp = *src;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen first = i;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen while (i < dest_count && src->seq2 >= dest[i].seq1-1) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* we can/must merge with next record */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (new_exp.seq2 < dest[i].seq2)
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen new_exp.seq2 = dest[i].seq2;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i++;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (first > 0 && new_exp.seq1 <= dest[first-1].seq2+1) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* continue previous record */
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (dest[first-1].seq2 < new_exp.seq2)
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen dest[first-1].seq2 = new_exp.seq2;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen } else if (i == first) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_insert(expunges, i, &new_exp, 1);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i++; first++;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen } else {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen /* use next record */
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen dest[first] = new_exp;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen first++;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (i > first) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_delete(expunges, first, i - first);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen dest = array_get_modifiable(expunges, &dest_count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen i = first;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen}
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainenstatic int view_sync_set_log_view_range(struct mail_index_view *view)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen{
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen const struct mail_index_header *hdr = view->index->hdr;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen int ret;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen /* the view begins from the first non-synced transaction */
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen ret = mail_transaction_log_view_set(view->log_view,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen view->log_file_seq,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen view->log_file_offset,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen hdr->log_file_seq,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen hdr->log_file_index_int_offset);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen if (ret <= 0) {
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen if (ret == 0) {
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen /* FIXME: use the new index to get needed changes */
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen mail_index_set_error(view->index,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen "Transaction log got desynced for index %s",
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen view->index->filepath);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen mail_index_set_inconsistent(view->index);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen }
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen return -1;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen }
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen return 0;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen}
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenview_sync_get_expunges(struct mail_index_view *view,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen ARRAY_TYPE(seq_range) *expunges_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
659fe5d24825b160cae512538088020d97a60239Timo Sirainen const struct mail_transaction_header *hdr;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen struct seq_range *src, *src_end, *dest;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen const void *data;
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen unsigned int count;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen int ret;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen if (view_sync_set_log_view_range(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen /* get a list of expunge transactions. there may be some that we have
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen already synced, but it doesn't matter because they'll get dropped
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen out when converting to sequences */
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen i_array_init(expunges_r, 64);
659fe5d24825b160cae512538088020d97a60239Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen &hdr, &data)) > 0) {
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen continue;
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen /* this is simply a request for expunge */
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen continue;
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen }
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_transaction_log_sort_expunges(expunges_r, data,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen hdr->size) < 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen "Corrupted expunge record");
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ret = -1;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen break;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen if (ret < 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_free(expunges_r);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen /* convert UIDs to sequences */
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen src = dest = array_get_modifiable(expunges_r, &count);
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen src_end = src + count;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen for (; src != src_end; src++) {
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen ret = mail_index_lookup_uid_range(view, src->seq1,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen src->seq2,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen &dest->seq1,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen &dest->seq2);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen i_assert(ret == 0);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen if (dest->seq1 == 0)
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen count--;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen else
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen dest++;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_delete(expunges_r, count, array_count(expunges_r) - count);
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainenstatic void mail_index_view_hdr_update(struct mail_index_view *view,
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen struct mail_index_map *map)
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen{
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* Keep message count the same. */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen map->hdr.next_uid = view->hdr.next_uid;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen map->hdr.messages_count = view->hdr.messages_count;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* Keep the old message flag counts also, although they may be
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen somewhat stale already. We just don't want them to be more than
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen our old messages_count. */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen map->hdr.recent_messages_count = view->hdr.recent_messages_count;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen map->hdr.seen_messages_count = view->hdr.seen_messages_count;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen map->hdr.deleted_messages_count = view->hdr.deleted_messages_count;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen /* Keep log position so we know where to continue syncing */
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen map->hdr.log_file_seq = view->hdr.log_file_seq;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen map->hdr.log_file_index_int_offset =
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->hdr.log_file_index_int_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen map->hdr.log_file_index_ext_offset =
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->hdr.log_file_index_ext_offset;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen view->hdr = map->hdr;
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen buffer_write(map->hdr_copy_buf, 0, &map->hdr, sizeof(map->hdr));
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen}
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#ifdef DEBUG
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainenstatic void mail_index_view_check(struct mail_index_view *view)
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen{
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen unsigned int i, del = 0, recent = 0, seen = 0;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(view->hdr.deleted_messages_count ==
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen view->map->hdr.deleted_messages_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(view->hdr.recent_messages_count ==
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen view->map->hdr.recent_messages_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(view->hdr.seen_messages_count ==
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen view->map->hdr.seen_messages_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen for (i = 0; i < view->map->records_count; i++) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen const struct mail_index_record *rec;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen rec = MAIL_INDEX_MAP_IDX(view->map, i);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (rec->flags & MAIL_DELETED) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(rec->uid >= view->hdr.first_deleted_uid_lowwater);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen del++;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (rec->flags & MAIL_RECENT) {
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(rec->uid >= view->hdr.first_recent_uid_lowwater);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen recent++;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen if (rec->flags & MAIL_SEEN)
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen seen++;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen else
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(rec->uid >= view->hdr.first_unseen_uid_lowwater);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(del == view->hdr.deleted_messages_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(recent == view->hdr.recent_messages_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen i_assert(seen == view->hdr.seen_messages_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen}
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#endif
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#define MAIL_INDEX_VIEW_VISIBLE_FLAGS_MASK \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (MAIL_INDEX_SYNC_TYPE_FLAGS | \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET | \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD | MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen#define MAIL_TRANSACTION_VISIBLE_SYNC_MASK \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND | \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen MAIL_TRANSACTION_FLAG_UPDATE | MAIL_TRANSACTION_KEYWORD_UPDATE | \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen MAIL_TRANSACTION_KEYWORD_RESET)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen#define VIEW_IS_SYNCED_TO_SAME(view, hdr) \
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen ((hdr)->log_file_seq == (view)->log_file_seq && \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (hdr)->log_file_index_int_offset == (view)->log_file_offset && \
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen (hdr)->log_file_index_ext_offset == (view)->log_file_offset && \
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen (!array_is_created(&view->syncs_done) || \
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen array_count(&view->syncs_done) == 0))
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen enum mail_index_view_sync_type sync_type,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view_sync_ctx **ctx_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view_sync_ctx *ctx;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct mail_index_map *map;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen enum mail_transaction_type visible_mask = 0;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen ARRAY_TYPE(seq_range) expunges = ARRAY_INIT;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(!view->syncing);
d39c0e195c67be5f2b0a15f25a8d6039bef02711Timo Sirainen i_assert(view->transactions == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_index_view_lock_head(view) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen if (sync_type == MAIL_INDEX_VIEW_SYNC_TYPE_ALL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* get list of all expunges first */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_sync_get_expunges(view, &expunges) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bcf5af3335a814e4923ba1bf2e0d80eb6dabfb22Timo Sirainen /* only flags, appends and expunges can be left to be synced later */
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen switch (sync_type) {
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen case MAIL_INDEX_VIEW_SYNC_TYPE_ALL:
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen visible_mask = MAIL_TRANSACTION_VISIBLE_SYNC_MASK;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen break;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen case MAIL_INDEX_VIEW_SYNC_TYPE_NOAPPENDS_NOEXPUNGES:
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen visible_mask = MAIL_TRANSACTION_VISIBLE_SYNC_MASK &
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ~(MAIL_TRANSACTION_EXPUNGE | MAIL_TRANSACTION_APPEND);
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen break;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen case MAIL_INDEX_VIEW_SYNC_TYPE_NOEXPUNGES:
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen visible_mask = MAIL_TRANSACTION_VISIBLE_SYNC_MASK &
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen ~MAIL_TRANSACTION_EXPUNGE;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen break;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen if (view_sync_set_log_view_range(view) < 0) {
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (array_is_created(&expunges))
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_free(&expunges);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->view = view;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ctx->visible_sync_mask = visible_mask;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->expunges = expunges;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen MAIL_INDEX_SYNC_HANDLER_VIEW);
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen if (sync_type == MAIL_INDEX_VIEW_SYNC_TYPE_ALL) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->sync_new_map = view->index->map;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->sync_new_map->refcount++;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen /* since we're syncing everything, the counters get fixed */
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen view->broken_counters = FALSE;
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* keep the old mapping without expunges until we're
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen fully synced */
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen } else {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* We need a private copy of the map if we don't want to
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen sync expunges.
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen If view's map is the head map, it means that it contains
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen already all the latest changes and there's no need for us
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen to apply any changes to it. This can only happen if there
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen hadn't been any expunges. */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen uint32_t old_records_count = view->map->records_count;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (view->map != view->index->map) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Using non-head mapping. We have to apply
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen transactions to it to get latest changes into it. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ctx->sync_map_update = TRUE;
0c09e57c5d5a649c248d0073438d79acbb80c72bTimo Sirainen
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen /* Unless map was synced at the exact same position as
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen view, the message flags can't be reliably used to
0c09e57c5d5a649c248d0073438d79acbb80c72bTimo Sirainen update flag counters. note that map->hdr may contain
0c09e57c5d5a649c248d0073438d79acbb80c72bTimo Sirainen old information if another process updated the
0c09e57c5d5a649c248d0073438d79acbb80c72bTimo Sirainen index file since. */
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen if (view->map->mmap_base != NULL) {
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen const struct mail_index_header *hdr;
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen hdr = view->map->mmap_base;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen view->map->hdr = *hdr;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen }
fa5957ffc9b676bfd649fa9953e63e72ee4ebeb4Timo Sirainen ctx->sync_map_ctx.unreliable_flags =
5cdd348121e62a6244ba2f93db781731f7129a71Timo Sirainen !VIEW_IS_SYNCED_TO_SAME(view, &view->map->hdr);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Copy only the mails that we see currently, since
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen we're going to append the new ones when we see
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen their transactions. */
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen i_assert(view->map->records_count >=
d7095f3a4466fbb78b2d5eb3d322bc15a5b0ab1fTimo Sirainen view->hdr.messages_count);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->map->records_count = view->hdr.messages_count;
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#ifdef DEBUG
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen if (!ctx->sync_map_ctx.unreliable_flags) {
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen i_assert(view->map->hdr.messages_count ==
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen view->hdr.messages_count);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen mail_index_view_check(view);
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen }
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#endif
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen map = mail_index_map_clone(view->map);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->map->records_count = old_records_count;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen mail_index_unmap(view->index, &view->map);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen view->map = map;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (ctx->sync_map_update) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Start the sync using our old view's header.
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen The old view->hdr may differ from map->hdr if
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen another view sharing the map with us had synced
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen itself. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen i_assert(map->hdr_base == map->hdr_copy_buf->data);
c75721032dbe34369b94ad02444c89111d6686d4Timo Sirainen mail_index_view_hdr_update(view, map);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
20c26f4fcf9ef87434761829cc209c2f84ff5716Timo Sirainen
20c26f4fcf9ef87434761829cc209c2f84ff5716Timo Sirainen i_assert(map->records_count == map->hdr.messages_count);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen }
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Syncing the view invalidates all previous looked up records.
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen Unreference the mappings this view keeps because of them. */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen mail_index_view_unref_maps(view);
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen view->syncing = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *ctx_r = ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainenstatic void
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainenview_add_synced_transaction(struct mail_index_view *view,
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen uint32_t log_file_seq, uoff_t log_file_offset)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen struct mail_index_view_log_sync_area *pos;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if (!array_is_created(&view->syncs_done))
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen i_array_init(&view->syncs_done, 32);
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen pos = array_append_space(&view->syncs_done);
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen pos->log_file_seq = log_file_seq;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen pos->log_file_offset = log_file_offset;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen pos->length = 1;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen}
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainenstatic bool view_sync_area_find(ARRAY_TYPE(view_log_sync_area) *sync_arr,
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen uint32_t seq, uoff_t offset)
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen{
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen const struct mail_index_view_log_sync_area *syncs;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen if (!array_is_created(sync_arr))
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen syncs = array_get(sync_arr, &count);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen for (i = 0; i < count; i++) {
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if (syncs[i].log_file_offset <= offset &&
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen offset - syncs[i].log_file_offset < syncs[i].length &&
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen syncs[i].log_file_seq == seq)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic int
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenmail_index_view_sync_get_next_transaction(struct mail_index_view_sync_ctx *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view = ctx->view;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen const struct mail_transaction_header *hdr;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen uint32_t seq;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen uoff_t offset;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen int ret;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen bool synced_to_map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen for (;;) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Get the next transaction from log. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen &ctx->data);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (ret <= 0) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (ret < 0)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return -1;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ctx->hdr = NULL;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ctx->last_read = TRUE;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return 0;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen hdr = ctx->hdr;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen if ((hdr->type & ctx->visible_sync_mask) == 0 &&
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen (hdr->type & MAIL_TRANSACTION_VISIBLE_SYNC_MASK) != 0) {
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen /* This is a visible record that we don't want to
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen sync. */
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen ctx->skipped_some = TRUE;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen continue;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen }
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
d2b0d5daa7350cd0d67f011e8b390a256f5f4218Timo Sirainen if (!ctx->skipped_some) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* We haven't skipped anything while syncing this view.
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen Update this view's synced log offset. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->log_file_seq = seq;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen view->log_file_offset = offset + sizeof(*hdr) +
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen hdr->size;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen /* skip everything we've already synced */
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if (view_sync_area_find(&view->syncs_done, seq, offset))
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen continue;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
af93c63a95bff1efbad7443fee0699fe772ed1b4Timo Sirainen if (ctx->skipped_some) {
af93c63a95bff1efbad7443fee0699fe772ed1b4Timo Sirainen /* We've been skipping some transactions, which means
af93c63a95bff1efbad7443fee0699fe772ed1b4Timo Sirainen we'll go through these same transactions again
af93c63a95bff1efbad7443fee0699fe772ed1b4Timo Sirainen later. Since we're syncing this one, we don't want
af93c63a95bff1efbad7443fee0699fe772ed1b4Timo Sirainen to do it again. */
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen view_add_synced_transaction(view, seq, offset);
af93c63a95bff1efbad7443fee0699fe772ed1b4Timo Sirainen }
af93c63a95bff1efbad7443fee0699fe772ed1b4Timo Sirainen
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen /* if we started from a map that we didn't create ourself,
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen some of the external transactions may already be synced.
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen at the end of view sync we'll update the ext_offset in the
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen header so that this check always becomes FALSE for
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen subsequent syncs. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen synced_to_map = offset < view->hdr.log_file_index_ext_offset &&
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen seq == view->hdr.log_file_seq &&
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen (hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0;
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Apply transaction to view's mapping if needed (meaning we
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen didn't just re-map the view to head mapping). */
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen if (ctx->sync_map_update && !synced_to_map) {
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (mail_index_sync_record(&ctx->sync_map_ctx,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen hdr, ctx->data) < 0)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return -1;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen if ((hdr->type & ctx->visible_sync_mask) == 0) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* non-visible change that we just wanted to update
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen to map. */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen continue;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen /* skip changes committed by hidden transactions (eg. in IMAP
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen store +flags.silent command) */
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if (view_sync_area_find(&view->syncs_hidden, seq, offset))
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen continue;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#define FLAG_UPDATE_IS_INTERNAL(u) \
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen ((((u)->add_flags | (u)->remove_flags) & \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ~(MAIL_INDEX_MAIL_FLAG_DIRTY | MAIL_RECENT)) == 0)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainenstatic int
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainenmail_index_view_sync_get_rec(struct mail_index_view_sync_ctx *ctx,
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen struct mail_index_view_sync_rec *rec)
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen{
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_header *hdr = ctx->hdr;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const void *data = ctx->data;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen switch (hdr->type & MAIL_TRANSACTION_TYPE_MASK) {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen case MAIL_TRANSACTION_APPEND: {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* data contains the appended records, but we don't care */
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_APPEND;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen rec->uid1 = rec->uid2 = 0;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen ctx->data_offset += hdr->size;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen break;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen case MAIL_TRANSACTION_EXPUNGE: {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_expunge *exp =
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen /* this is simply a request for expunge */
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen ctx->data_offset = ctx->hdr->size;
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen return 0;
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen }
e063aca6bc2f08bec516d4b631052ea9191f011dTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* data contains mail_transaction_expunge[] */
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_EXPUNGE;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen rec->uid1 = exp->uid1;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen rec->uid2 = exp->uid2;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen ctx->data_offset += sizeof(*exp);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen break;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen case MAIL_TRANSACTION_FLAG_UPDATE: {
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen const struct mail_transaction_flag_update *update =
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* data contains mail_transaction_flag_update[] */
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen for (;;) {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ctx->data_offset += sizeof(*update);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (!FLAG_UPDATE_IS_INTERNAL(update))
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen break;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* skip internal flag changes */
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ctx->data_offset == ctx->hdr->size)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return 0;
d0143523a87b41eae0b118ff03aad539903b3555Timo Sirainen
d0143523a87b41eae0b118ff03aad539903b3555Timo Sirainen update = CONST_PTR_OFFSET(data, ctx->data_offset);
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen }
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_FLAGS;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen rec->uid1 = update->uid1;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen rec->uid2 = update->uid2;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen break;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen case MAIL_TRANSACTION_KEYWORD_UPDATE: {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const struct mail_transaction_keyword_update *update = data;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen const uint32_t *uids;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* data contains mail_transaction_keyword_update header,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen the keyword name and an array of { uint32_t uid1, uid2; } */
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (ctx->data_offset == 0) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* skip over the header and name */
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen ctx->data_offset = sizeof(*update) + update->name_size;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if ((ctx->data_offset % 4) != 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->data_offset += 4 - (ctx->data_offset % 4);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uids = CONST_PTR_OFFSET(data, ctx->data_offset);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen rec->uid1 = uids[0];
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen rec->uid2 = uids[1];
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->data_offset += sizeof(uint32_t) * 2;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen break;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen case MAIL_TRANSACTION_KEYWORD_RESET: {
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen const struct mail_transaction_keyword_reset *reset =
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen CONST_PTR_OFFSET(data, ctx->data_offset);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* data contains mail_transaction_keyword_reset[] */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->type = MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->uid1 = reset->uid1;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen rec->uid2 = reset->uid2;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen ctx->data_offset += sizeof(*reset);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen break;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen }
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen default:
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen i_unreached();
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen return 1;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen}
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen struct mail_index_view_sync_rec *sync_rec)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen do {
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen if (ctx->hdr == NULL || ctx->data_offset == ctx->hdr->size) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen ret = mail_index_view_sync_get_next_transaction(ctx);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (ret <= 0)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return ret;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ctx->data_offset = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen } while (!mail_index_view_sync_get_rec(ctx, sync_rec));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainenvoid mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen const ARRAY_TYPE(seq_range) **expunges_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen *expunges_r = &ctx->expunges;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic void
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainenmail_index_view_sync_clean_log_syncs(struct mail_index_view_sync_ctx *ctx,
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen ARRAY_TYPE(view_log_sync_area) *sync_arr,
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen bool fast_clean)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen{
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen struct mail_index_view *view = ctx->view;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen const struct mail_index_view_log_sync_area *syncs;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen uint32_t seq = view->log_file_seq;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen uoff_t offset = view->log_file_offset;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen unsigned int i, count;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen if (!array_is_created(sync_arr))
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if (!ctx->skipped_some && fast_clean) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Nothing skipped. Clean it up the quick way. */
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen array_clear(sync_arr);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen /* Clean up until view's current syncing position */
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen syncs = array_get(sync_arr, &count);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen for (i = 0; i < count; i++) {
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if ((syncs[i].log_file_offset + syncs[i].length > offset &&
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen syncs[i].log_file_seq == seq) ||
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen syncs[i].log_file_seq > seq)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen break;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (i > 0)
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen array_delete(sync_arr, 0, i);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen}
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx **_ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct mail_index_view_sync_ctx *ctx = *_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view *view = ctx->view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(view->syncing);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_ctx = NULL;
9873ccef8e39b55637d80fd1a27619ea2c91cfd5Timo Sirainen mail_index_sync_map_deinit(&ctx->sync_map_ctx);
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen mail_index_view_sync_clean_log_syncs(ctx, &view->syncs_done, TRUE);
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen mail_index_view_sync_clean_log_syncs(ctx, &view->syncs_hidden, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (!ctx->last_read) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we didn't sync everything */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->inconsistent = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (view->sync_new_map != NULL) {
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen mail_index_unmap(view->index, &view->map);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->map = view->sync_new_map;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->sync_new_map = NULL;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen if (ctx->sync_map_update) {
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen if (view->log_file_seq != view->map->hdr.log_file_seq) {
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen i_assert(view->log_file_seq >
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen view->map->hdr.log_file_seq);
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen view->map->hdr.log_file_seq = view->log_file_seq;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_index_ext_offset =
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen view->log_file_offset;
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen } else {
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen i_assert(view->log_file_offset >=
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_index_int_offset);
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen if (view->log_file_offset >
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_index_ext_offset) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_index_ext_offset =
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen view->log_file_offset;
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen }
0b924289a76fadafc3fdabcbc70e6f5562d230b6Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_index_int_offset =
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->log_file_offset;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen buffer_write(view->map->hdr_copy_buf, 0,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen &view->map->hdr, sizeof(view->map->hdr));
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen } else {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(view->inconsistent ||
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->log_file_offset >=
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen view->map->hdr.log_file_index_int_offset);
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen view->hdr = view->map->hdr;
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#ifdef DEBUG
e8f0aa694cd3a08e50deebb9f4af7ef61f939714Timo Sirainen if (!view->broken_counters && !ctx->sync_map_ctx.unreliable_flags)
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen mail_index_view_check(view);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#endif
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen /* set log view to empty range so unneeded memory gets freed */
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen (void)mail_transaction_log_view_set(view->log_view,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen view->log_file_seq,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen view->log_file_offset,
a24f6b02ed8d0dde933a715be1c86f01977bf610Timo Sirainen view->log_file_seq,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen view->log_file_offset);
7888a9d2008eab9985096c46e1da9ee985c22a2aTimo Sirainen
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen if (array_is_created(&ctx->expunges))
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_free(&ctx->expunges);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->syncing = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainenvoid mail_index_view_add_hidden_transaction(struct mail_index_view *view,
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen uint32_t log_file_seq,
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen uoff_t log_file_offset,
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen unsigned int length)
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen{
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen struct mail_index_view_log_sync_area *area;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen if (!array_is_created(&view->syncs_hidden))
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen i_array_init(&view->syncs_hidden, 32);
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen area = array_append_space(&view->syncs_hidden);
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen area->log_file_seq = log_file_seq;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen area->log_file_offset = log_file_offset;
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen area->length = length;
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen}