mail-index-view-sync.c revision eddd9bf1a1369aea4a2715f6be1137da6d17d293
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2003-2007 Dovecot authors, see the included COPYING file */
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;
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen enum mail_index_view_sync_flags flags;
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen struct mail_index_sync_map_ctx sync_map_ctx;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen ARRAY_TYPE(seq_range) expunges;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen unsigned int finish_min_msg_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const void *data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t data_offset;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen unsigned int failed:1;
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen unsigned int sync_map_update:1;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen unsigned int skipped_expunges:1;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen unsigned int last_read: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
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenstatic int
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainenview_sync_set_log_view_range(struct mail_index_view *view, bool sync_expunges,
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen bool quick_sync, bool *reset_r)
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen{
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen const struct mail_index_header *hdr = &view->index->map->hdr;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen uint32_t start_seq, end_seq;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen uoff_t start_offset, end_offset;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen int ret;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen end_seq = hdr->log_file_seq;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen end_offset = hdr->log_file_head_offset;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen if (quick_sync) {
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen start_seq = end_seq;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen start_offset = end_offset;
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen /* we'll just directly to the end */
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen view->log_file_head_seq = end_seq;
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen view->log_file_head_offset = end_offset;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen } else {
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen start_seq = view->log_file_expunge_seq;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen start_offset = view->log_file_expunge_offset;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen for (;;) {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* the view begins from the first non-synced transaction */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen ret = mail_transaction_log_view_set(view->log_view,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen start_seq, start_offset,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen end_seq, end_offset,
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainen reset_r);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (ret <= 0) {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (ret < 0)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen return -1;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* FIXME: use the new index to get needed
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen changes */
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen mail_index_set_error(view->index,
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen "Transaction log got desynced for index %s",
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen view->index->filepath);
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen view->inconsistent = TRUE;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen return -1;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainen if (!*reset_r || sync_expunges)
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen break;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* we can't do this. sync only up to reset. */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen &end_seq, &end_offset);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen end_seq--; end_offset = (uoff_t)-1;
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen if (end_seq < start_seq) {
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen /* we have only this reset log */
c680a6b35b459045e92814778908da5a93922107Timo Sirainen mail_transaction_log_view_clear(view->log_view,
c680a6b35b459045e92814778908da5a93922107Timo Sirainen view->log_file_expunge_seq);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen break;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen }
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen }
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen return 0;
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen}
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenview_sync_get_expunges(struct mail_index_view *view,
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen ARRAY_TYPE(seq_range) *expunges_r,
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen unsigned int *expunge_count_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;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen unsigned int count, expunge_count = 0;
a0d1b7178be151f49204ca2b33d5fa0ba314571aTimo Sirainen uint32_t prev_seq = 0;
49e9acb52bb5d328f8cf10bce1082c4bc213caeaTimo Sirainen bool reset;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen int ret;
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen if (view_sync_set_log_view_range(view, TRUE, FALSE, &reset) < 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++) {
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen if (!mail_index_lookup_seq_range(view, src->seq1, src->seq2,
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen &dest->seq1, &dest->seq2))
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen count--;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen else {
a0d1b7178be151f49204ca2b33d5fa0ba314571aTimo Sirainen i_assert(dest->seq1 > prev_seq);
a0d1b7178be151f49204ca2b33d5fa0ba314571aTimo Sirainen prev_seq = dest->seq2;
a0d1b7178be151f49204ca2b33d5fa0ba314571aTimo Sirainen
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen expunge_count += dest->seq2 - dest->seq1 + 1;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen dest++;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen }
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen }
b032dc80e358f09893f09999f172ff12f5dbbb8eTimo Sirainen array_delete(expunges_r, count, array_count(expunges_r) - count);
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen *expunge_count_r = expunge_count;
7b3bf1de3fa7eee2185d1e404812b50c295e2b93Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenstatic bool have_existing_expunges(struct mail_index_view *view,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen const struct seq_range *range, size_t size)
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen{
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen const struct seq_range *range_end;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen uint32_t seq1, seq2;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen range_end = CONST_PTR_OFFSET(range, size);
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen for (; range < range_end; range++) {
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen if (mail_index_lookup_seq_range(view, range->seq1, range->seq2,
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen &seq1, &seq2))
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen return TRUE;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen return FALSE;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen}
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainenstatic bool view_sync_have_expunges(struct mail_index_view *view)
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen{
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen const struct mail_transaction_header *hdr;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen const void *data;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen uint32_t seq;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen uoff_t offset;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen bool have_expunges = FALSE;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen int ret;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view,
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen &seq, &offset);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view,
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen &hdr, &data)) > 0) {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0)
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen continue;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0) {
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen /* this is simply a request for expunge */
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen continue;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen /* we have an expunge. see if it still exists. */
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen if (have_existing_expunges(view, data, hdr->size)) {
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen have_expunges = TRUE;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen break;
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen }
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen }
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen mail_transaction_log_view_seek(view->log_view, seq, offset);
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen /* handle failures as having expunges (which is safer).
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen we'll probably fail later. */
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen return ret < 0 || have_expunges;
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen}
fd3f33bdb57170d63aea66ecacc8bea0f0145d6aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
7761758f43d6150be4b07f4c54457ce662f78c4cTimo Sirainen enum mail_index_view_sync_flags flags,
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;
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen ARRAY_TYPE(seq_range) expunges = ARRAY_INIT;
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen unsigned int expunge_count = 0;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen bool reset, sync_expunges, quick_sync;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(!view->syncing);
d39c0e195c67be5f2b0a15f25a8d6039bef02711Timo Sirainen i_assert(view->transactions == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen quick_sync = (flags & MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT) != 0;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen if (mail_index_view_is_inconsistent(view)) {
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen if ((flags & MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT) == 0) {
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen mail_index_set_error(view->index,
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen "%s view is inconsistent",
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen view->index->filepath);
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen return -1;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen }
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen view->inconsistent = FALSE;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen }
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen sync_expunges = (flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) == 0;
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen if (quick_sync) {
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen i_assert(sync_expunges);
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen i_array_init(&expunges, 1);
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen } else if (sync_expunges) {
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen /* get list of all expunges first */
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen if (view_sync_get_expunges(view, &expunges, &expunge_count) < 0)
1d06a935b555024420d1c22249f0c847e51a9b7aTimo Sirainen return -1;
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen if (view_sync_set_log_view_range(view, sync_expunges, quick_sync,
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen &reset) < 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;
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen ctx->flags = flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->expunges = expunges;
fb36dcb603524f860f1e4edf987fd3b028acac6fTimo Sirainen ctx->finish_min_msg_count = reset || quick_sync ? 0 :
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen view->map->hdr.messages_count - expunge_count;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen MAIL_INDEX_SYNC_HANDLER_VIEW);
56561d472db25ebda35ae6afdc7f7deb75c323fcTimo Sirainen
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen if (reset && view->map->hdr.messages_count > 0 &&
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen (flags & MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT) == 0) {
530c3ece3717ad8193046ea7774227f91971a0dcTimo Sirainen view->inconsistent = TRUE;
530c3ece3717ad8193046ea7774227f91971a0dcTimo Sirainen mail_index_set_error(view->index,
530c3ece3717ad8193046ea7774227f91971a0dcTimo Sirainen "%s reset, view is now inconsistent",
530c3ece3717ad8193046ea7774227f91971a0dcTimo Sirainen view->index->filepath);
530c3ece3717ad8193046ea7774227f91971a0dcTimo Sirainen }
530c3ece3717ad8193046ea7774227f91971a0dcTimo Sirainen
ba94d6d7e2f7b07d51f5c27e7532f6502ac9a298Timo Sirainen if (sync_expunges || !view_sync_have_expunges(view)) {
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen if (view->index->map->hdr.messages_count <
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen ctx->finish_min_msg_count) {
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen mail_index_set_error(view->index,
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen "Index %s lost messages without expunging "
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen "(%u -> %u)", view->index->filepath,
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen view->map->hdr.messages_count,
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen view->index->map->hdr.messages_count);
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen ctx->finish_min_msg_count = 0;
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen view->inconsistent = TRUE;
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen }
07afd4db18860589803c46a3ee0559bda1c9e1b4Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->sync_new_map = view->index->map;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->sync_new_map->refcount++;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo 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 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;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen }
0c09e57c5d5a649c248d0073438d79acbb80c72bTimo Sirainen
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen if (view->map->refcount > 1) {
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen map = mail_index_map_clone(view->map);
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen mail_index_unmap(&view->map);
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen view->map = map;
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen } else {
9bc6e10d9c6d6ffb4a2ed49a3b3d2a180f2a87a3Timo Sirainen map = view->map;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen }
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen#ifdef DEBUG
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen mail_index_map_check(view->map);
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo Sirainen#endif
e26a771fad55dfba4d5021d12ed5685c951d9b7bTimo 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
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainenstatic bool
24c6aaf3c540d078021bb4a326982ae4e3d7eaf8Timo Sirainenview_sync_is_hidden(struct mail_index_view *view, 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
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen if (!array_is_created(&view->syncs_hidden))
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen syncs = array_get(&view->syncs_hidden, &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
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainenstatic bool
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainenmail_index_view_sync_want(struct mail_index_view_sync_ctx *ctx,
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen const struct mail_transaction_header *hdr)
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen{
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen struct mail_index_view *view = ctx->view;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen uint32_t seq;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen uoff_t offset, next_offset;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen mail_transaction_log_view_get_prev_pos(view->log_view, &seq, &offset);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen next_offset = offset + sizeof(*hdr) + hdr->size;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen if ((hdr->type & MAIL_TRANSACTION_EXPUNGE) != 0 &&
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen (hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0) {
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen if ((ctx->flags & MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES) != 0) {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen i_assert(!LOG_IS_BEFORE(seq, offset,
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_expunge_seq,
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_expunge_offset));
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (!ctx->skipped_expunges) {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_expunge_seq = seq;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_expunge_offset = offset;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen ctx->skipped_expunges = TRUE;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen }
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen return FALSE;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen }
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (LOG_IS_BEFORE(seq, offset, view->log_file_expunge_seq,
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_expunge_offset)) {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen /* already synced */
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen return FALSE;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen }
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen }
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (LOG_IS_BEFORE(seq, offset, view->log_file_head_seq,
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_head_offset)) {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen /* already synced */
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen return FALSE;
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen }
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_head_seq = seq;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_head_offset = next_offset;
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen return TRUE;
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen}
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo 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;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (!mail_index_view_sync_want(ctx, hdr)) {
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen /* This is a visible record that we don't want to
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen sync. */
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen continue;
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen }
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, &seq, &offset);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen /* If we started from a map that we didn't create ourself,
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen some of the transactions may already be synced. at the end
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen of this view sync we'll update file_seq=0 so that this check
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen always becomes FALSE for subsequent syncs. */
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen synced_to_map = view->map->hdr.log_file_seq != 0 &&
6f4ddcbd1961beb71a7e2b3e12f5af26942671c0Timo Sirainen LOG_IS_BEFORE(seq, offset,
6f4ddcbd1961beb71a7e2b3e12f5af26942671c0Timo Sirainen view->map->hdr.log_file_seq,
6f4ddcbd1961beb71a7e2b3e12f5af26942671c0Timo Sirainen view->map->hdr.log_file_head_offset);
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) {
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen i_assert((hdr->type & MAIL_TRANSACTION_EXPUNGE) == 0 ||
bbe90c4805e7032fdcefde3df125df0ca8be1befTimo Sirainen (hdr->type & MAIL_TRANSACTION_EXTERNAL) == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen T_FRAME(
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen ret = mail_index_sync_record(&ctx->sync_map_ctx,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen hdr, ctx->data);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen );
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen if (ret < 0)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return -1;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen /* skip changes committed by hidden transactions (eg. in IMAP
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen store +flags.silent command) */
24c6aaf3c540d078021bb4a326982ae4e3d7eaf8Timo Sirainen if (view_sync_is_hidden(view, 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) & \
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen ~MAIL_INDEX_MAIL_FLAG_DIRTY) == 0)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainenstatic bool
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:
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen ctx->hdr = NULL;
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen return FALSE;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen }
8ef80b0b9c73fb0a0188788b14b3e15084b7a452Timo Sirainen return TRUE;
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen}
d67f54632110cfb6aafe2d7cd1f99b031c0b208aTimo Sirainen
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainenbool mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
c979eeda1f46483d9c963e265786b701d7683d77Timo 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);
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen if (ret <= 0) {
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen if (ret < 0)
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen ctx->failed = TRUE;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen return FALSE;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ctx->data_offset = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen } while (!mail_index_view_sync_get_rec(ctx, sync_rec));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen return TRUE;
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
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainenmail_index_view_sync_clean_log_syncs(struct mail_index_view *view)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen{
87ca2e468841829b44c09d618ac02f61a30b7a49Timo Sirainen const struct mail_index_view_log_sync_area *syncs;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen unsigned int i, count;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (!array_is_created(&view->syncs_hidden))
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen return;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen /* Clean up to view's tail */
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen syncs = array_get(&view->syncs_hidden, &count);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen for (i = 0; i < count; i++) {
cc6ed00c61fda24799c905e403b94a2a8c39ae5cTimo Sirainen if ((syncs[i].log_file_offset +
cc6ed00c61fda24799c905e403b94a2a8c39ae5cTimo Sirainen syncs[i].length > view->log_file_expunge_offset &&
cc6ed00c61fda24799c905e403b94a2a8c39ae5cTimo Sirainen syncs[i].log_file_seq == view->log_file_expunge_seq) ||
cc6ed00c61fda24799c905e403b94a2a8c39ae5cTimo Sirainen syncs[i].log_file_seq > view->log_file_expunge_seq)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen break;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (i > 0)
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen array_delete(&view->syncs_hidden, 0, i);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen}
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainenint mail_index_view_sync_commit(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;
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen int ret = ctx->failed ? -1 : 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(view->syncing);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_ctx = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen if ((!ctx->last_read || view->inconsistent) &&
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen (ctx->flags & MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we didn't sync everything */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->inconsistent = TRUE;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen if (view->sync_new_map != NULL) {
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen mail_index_unmap(&view->map);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->map = view->sync_new_map;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view->sync_new_map = NULL;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen }
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen i_assert(view->map->hdr.messages_count >= ctx->finish_min_msg_count);
687794a61c9e3bf27c712b442b8fc8836c63ae44Timo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen if (!ctx->skipped_expunges) {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_expunge_seq = view->log_file_head_seq;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->log_file_expunge_offset = view->log_file_head_offset;
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen }
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen if (ctx->sync_map_update) {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen /* log offsets have no meaning in views. make sure they're not
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen tried to be used wrong by setting them to zero. */
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen view->map->hdr.log_file_seq = 0;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen view->map->hdr.log_file_head_offset = 0;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen view->map->hdr.log_file_tail_offset = 0;
23230b2a3fe09ed29bd1314c7b8b4a0b17ea0ecfTimo Sirainen }
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen mail_index_sync_map_deinit(&ctx->sync_map_ctx);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen mail_index_view_sync_clean_log_syncs(ctx->view);
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#ifdef DEBUG
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen mail_index_map_check(view->map);
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen#endif
945631faab2bf1aed8d95a1fd0c317a9ce153725Timo Sirainen
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen /* set log view to empty range so unneeded memory gets freed */
c680a6b35b459045e92814778908da5a93922107Timo Sirainen mail_transaction_log_view_clear(view->log_view,
c680a6b35b459045e92814778908da5a93922107Timo Sirainen view->log_file_expunge_seq);
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);
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen return ret;
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}