mail-index-view-sync.c revision f1765f773591385d513fb68e1799fd1cb4206852
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2003-2008 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"
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen#include "mail-index-modseq.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
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen /* After syncing view, map is replaced with sync_new_map. */
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen struct mail_index_map *sync_new_map;
f1765f773591385d513fb68e1799fd1cb4206852Timo 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;
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen bool reset, sync_expunges, quick_sync, have_expunges;
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;
20b9283d4af31e45e588014da427fb2dbcd3227aTimo Sirainen mail_index_sync_map_init(&ctx->sync_map_ctx, view,
20b9283d4af31e45e588014da427fb2dbcd3227aTimo 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
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen have_expunges = view_sync_have_expunges(view);
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen if (!have_expunges) {
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen /* no expunges, we can just replace the map */
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
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen view->index->map->refcount++;
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen mail_index_unmap(&view->map);
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen view->map = view->index->map;
5a58037ad75b88356d82240fab2bc604de03107eTimo Sirainen } else {
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen /* expunges seen. create a private map which we update.
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen if we're syncing expunges the map will finally be replaced
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen with the head map to remove the expunged messages. */
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen ctx->sync_map_update = TRUE;
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 }
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen if (sync_expunges) {
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen ctx->sync_new_map = view->index->map;
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen ctx->sync_new_map->refcount++;
f1765f773591385d513fb68e1799fd1cb4206852Timo 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
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen T_BEGIN {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen ret = mail_index_sync_record(&ctx->sync_map_ctx,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen hdr, ctx->data);
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen } T_END;
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) & \
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen MAIL_INDEX_FLAGS_MASK) == 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 }
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen mail_index_modseq_sync_end(&ctx->sync_map_ctx.modseq_ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen if (ctx->sync_new_map != NULL) {
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen mail_index_unmap(&view->map);
f1765f773591385d513fb68e1799fd1cb4206852Timo Sirainen view->map = ctx->sync_new_map;
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
20b9283d4af31e45e588014da427fb2dbcd3227aTimo 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}