mdbox-sync.c revision 637455ebee0453f860c9bce0626c485e35fb83de
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#include "hex-binary.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mdbox-storage.h"
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#include "mdbox-storage-rebuild.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mdbox-map.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mdbox-file.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mdbox-sync.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <stdlib.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <dirent.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define DBOX_REBUILD_COUNT 3
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainenstatic int
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainendbox_sync_verify_expunge_guid(struct mdbox_sync_context *ctx, uint32_t seq,
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen const uint8_t guid_128[MAIL_GUID_128_SIZE])
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen{
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen const void *data;
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen uint32_t uid;
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &uid);
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen mail_index_lookup_ext(ctx->sync_view, seq,
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen ctx->mbox->guid_ext_id, &data, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_guid_128_is_empty(guid_128) ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen memcmp(data, guid_128, MAIL_GUID_128_SIZE) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(&ctx->mbox->storage->storage.storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Mailbox %s: Expunged GUID mismatch for UID %u: %s vs %s",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->mbox->box.vname, uid,
b7b81543899e306c71e6152516d8698416162bcbTimo Sirainen binary_to_hex(data, MAIL_GUID_128_SIZE),
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen binary_to_hex(guid_128, MAIL_GUID_128_SIZE));
e12648867876aaec17e06ee4caef0bb60363449dTimo Sirainen ctx->mbox->storage->storage.files_corrupted = TRUE;
e12648867876aaec17e06ee4caef0bb60363449dTimo Sirainen return -1;
e12648867876aaec17e06ee4caef0bb60363449dTimo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mdbox_sync_expunge(struct mdbox_sync_context *ctx, uint32_t seq,
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen const uint8_t guid_128[MAIL_GUID_128_SIZE])
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t map_uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (seq_range_exists(&ctx->expunged_seqs, seq)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* already marked as expunged in this sync */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (dbox_sync_verify_expunge_guid(ctx, seq, guid_128) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mdbox_mail_lookup(ctx->mbox, ctx->sync_view, seq, &map_uid) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq_range_array_add(&ctx->expunged_seqs, 0, seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_append(&ctx->expunged_map_uids, &map_uid, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mdbox_sync_add(struct mdbox_sync_context *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_sync_rec *sync_rec)
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen{
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen uint32_t seq, seq1, seq2;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (sync_rec->type != MAIL_INDEX_SYNC_TYPE_EXPUNGE) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* not interested */
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen return 0;
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mail_index_lookup_seq_range(ctx->sync_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_rec->uid1, sync_rec->uid2,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen &seq1, &seq2)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* already expunged everything. nothing to do. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen for (seq = seq1; seq <= seq2; seq++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mdbox_sync_expunge(ctx, seq, sync_rec->guid_128) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int dbox_sync_mark_expunges(struct mdbox_sync_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen enum mail_index_transaction_flags flags =
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box = &ctx->mbox->box;
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen struct mail_index_transaction *trans;
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen struct seq_range_iter iter;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int n;
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen const void *data;
2a734f36105e33ab452d057df6bc7a2b7d9f96f0Timo Sirainen uint32_t seq, uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen /* use a separate transaction here so that we can commit the changes
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen during map transaction */
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen trans = mail_index_transaction_begin(ctx->sync_view, flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (seq_range_array_iter_nth(&iter, n++, &seq)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_lookup_ext(ctx->sync_view, seq,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ctx->mbox->guid_ext_id, &data, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_expunge_guid(trans, seq, data);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (mail_index_transaction_commit(&trans) < 0)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return -1;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (box->v.sync_notify != NULL) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* do notifications after commit finished successfully */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen while (seq_range_array_iter_nth(&iter, n++, &seq)) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &uid);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen box->v.sync_notify(box, uid, MAILBOX_SYNC_TYPE_EXPUNGE);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen }
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen }
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen return 0;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen}
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainenstatic int mdbox_sync_index_finish_expunges(struct mdbox_sync_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct dbox_map_transaction_context *map_trans;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
659fe5d24825b160cae512538088020d97a60239Timo Sirainen map_trans = dbox_map_transaction_begin(ctx->mbox->storage->map, FALSE);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = dbox_map_update_refcounts(map_trans, &ctx->expunged_map_uids, -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* write refcount changes to map index */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = dbox_map_transaction_commit(map_trans);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen /* write changes to mailbox index */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ret = dbox_sync_mark_expunges(ctx);
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen /* this finally finishes the map sync and makes it clear that the
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen map transaction was successfully finished. */
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen if (ret < 0)
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen dbox_map_transaction_set_failed(map_trans);
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen dbox_map_transaction_free(&map_trans);
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen return ret;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstatic int mdbox_sync_index(struct mdbox_sync_context *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mailbox *box = &ctx->mbox->box;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_index_header *hdr;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_sync_rec sync_rec;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seq1, seq2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen hdr = mail_index_get_header(ctx->sync_view);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen if (hdr->uid_validity == 0) {
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen /* newly created index file */
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen return 0;
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen }
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* mark the newly seen messages as recent */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_lookup_seq_range(ctx->sync_view, hdr->first_recent_uid,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen hdr->next_uid, &seq1, &seq2)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mailbox_set_recent_seq(&ctx->mbox->box, ctx->sync_view,
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen seq1, seq2);
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen }
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen /* read all changes and group changes to same file_id together */
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen i_array_init(&ctx->expunged_seqs, 64);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_array_init(&ctx->expunged_map_uids, 64);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec)) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if ((ret = mdbox_sync_add(ctx, &sync_rec)) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0 && array_count(&ctx->expunged_seqs) > 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mdbox_sync_index_finish_expunges(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (box->v.sync_notify != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen box->v.sync_notify(box, 0, 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen array_free(&ctx->expunged_seqs);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_free(&ctx->expunged_map_uids);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret == 0 ? 1 :
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (ctx->mbox->storage->storage.files_corrupted ? 0 : -1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic int mdbox_refresh_header(struct mdbox_mailbox *mbox, bool retry)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen{
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen struct mail_index_view *view;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen struct mdbox_index_header hdr;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen int ret;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen view = mail_index_view_open(mbox->box.index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mdbox_read_header(mbox, &hdr);
7c95b03620a03a43dd72d39608cea5fc77393ad6Timo Sirainen mail_index_view_close(&view);
7c95b03620a03a43dd72d39608cea5fc77393ad6Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mbox->storage->storage.files_corrupted ? -1 : 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (retry) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (void)mail_index_refresh(mbox->box.index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return mdbox_refresh_header(mbox, FALSE);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen }
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen return ret;
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainenint mdbox_sync_begin(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen struct mdbox_sync_context **ctx_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_storage *storage = mbox->box.storage;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mdbox_sync_context *ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_index_sync_flags sync_flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen bool rebuild, storage_rebuilt = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rebuild = mdbox_refresh_header(mbox, TRUE) < 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (flags & MDBOX_SYNC_FLAG_FORCE_REBUILD) != 0;
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen if (rebuild) {
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen if (mdbox_storage_rebuild(mbox->storage) < 0)
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index_mailbox_reset_uidvalidity(&mbox->box);
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen storage_rebuilt = TRUE;
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx = i_new(struct mdbox_sync_context, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->mbox = mbox;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->flags = flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_flags = index_storage_get_sync_flags(&mbox->box);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!rebuild && (flags & MDBOX_SYNC_FLAG_FORCE) == 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((flags & MDBOX_SYNC_FLAG_FSYNC) != 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_FSYNC;
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen /* don't write unnecessary dirty flag updates */
757726d9acbd04cf0d0d4be8ce14e11525476a0bTimo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0;; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mail_index_sync_begin(mbox->box.index,
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen &ctx->index_sync_ctx,
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen &ctx->sync_view, &ctx->trans,
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainen sync_flags);
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainen if (ret <= 0) {
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainen if (ret < 0)
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen mail_storage_set_index_error(&mbox->box);
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen i_free(ctx);
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen *ctx_r = NULL;
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen return ret;
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
685393de106e55b61f754d420e378d05bd462ebbTimo Sirainen /* now that we're locked, check again if we want to rebuild */
87712707722ef7d73acb065546e61afa4455cd9eTimo Sirainen if (mdbox_refresh_header(mbox, FALSE) < 0)
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen ret = 0;
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((ret = mdbox_sync_index(ctx)) > 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* failure. keep the index locked while we're doing a
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rebuild. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!storage_rebuilt) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we'll need to rebuild storage too.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen try again from the beginning. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mbox->storage->storage.files_corrupted = TRUE;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen mail_index_sync_rollback(&ctx->index_sync_ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return mdbox_sync_begin(mbox, flags, ctx_r);
9d3ccd79130199ffdb19a688027d49bf20a4aaaaTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_critical(storage,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "dbox %s: Storage keeps breaking",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx->mbox->box.path);
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen ret = -1;
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen }
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen mail_index_sync_rollback(&ctx->index_sync_ctx);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen if (ret < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
bb26f09873c18f342cd1ab2d0ee0b9018e6546d9Timo Sirainen *ctx_r = ctx;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainenint mdbox_sync_finish(struct mdbox_sync_context **_ctx, bool success)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mdbox_sync_context *ctx = *_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret = success ? 0 : -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *_ctx = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (success) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_index_sync_commit(&ctx->index_sync_ctx) < 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_storage_set_index_error(&ctx->mbox->box);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_sync_rollback(&ctx->index_sync_ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(ctx);
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen return ret;
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen}
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainenint mdbox_sync(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mdbox_sync_context *sync_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mdbox_sync_begin(mbox, flags, &sync_ctx) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (sync_ctx == NULL)
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen return 0;
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen return mdbox_sync_finish(&sync_ctx, TRUE);
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen}
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstruct mailbox_sync_context *
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenmdbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen enum mdbox_sync_flags mdbox_sync_flags = 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen int ret = 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (!box->opened) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (mailbox_open(box) < 0)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ret = -1;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if (ret == 0 && (index_mailbox_want_full_sync(&mbox->box, flags) ||
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen mbox->storage->storage.files_corrupted)) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen mdbox_sync_flags |= MDBOX_SYNC_FLAG_FORCE_REBUILD;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ret = mdbox_sync(mbox, mdbox_sync_flags);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen return index_mailbox_sync_init(box, flags, ret < 0);
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstatic int mdbox_sync_altmove_add_files(struct mdbox_storage *dstorage,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ARRAY_TYPE(seq_range) *file_ids)
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen struct mail_storage *storage = &dstorage->storage.storage;
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen DIR *dir;
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen struct dirent *d;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct stat st;
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen time_t altmove_mtime;
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen string_t *path;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int file_id, dir_len;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (dstorage->set->mdbox_altmove == 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dstorage->alt_storage_dir == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen altmove_mtime = ioloop_time - dstorage->set->mdbox_altmove;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we want to quickly find the latest alt file, but we also want to
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen avoid accessing the alt storage as much as possible. so we'll do
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen this by finding the lowest numbered file (n) from primary storage.
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen hopefully one of n-[1..m] is appendable in alt storage. */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen dir = opendir(dstorage->storage_dir);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (dir == NULL) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_storage_set_critical(storage,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen "opendir(%s) failed: %m", dstorage->storage_dir);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen path = t_str_new(256);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen str_append(path, dstorage->storage_dir);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen str_append_c(path, '/');
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen dir_len = str_len(path);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (errno = 0; (d = readdir(dir)) != NULL; errno = 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (strncmp(d->d_name, MDBOX_MAIL_FILE_PREFIX,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen strlen(MDBOX_MAIL_FILE_PREFIX)) != 0)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen continue;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen str_truncate(path, dir_len);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen str_append(path, d->d_name);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen file_id = strtoul(d->d_name + strlen(MDBOX_MAIL_FILE_PREFIX),
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen NULL, 10);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (stat(str_c(path), &st) < 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen mail_storage_set_critical(storage,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen "stat(%s) failed: %m", str_c(path));
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen } else if (st.st_mtime < altmove_mtime) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen seq_range_array_add(file_ids, 0, file_id);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen }
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (errno != 0) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen mail_storage_set_critical(storage,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen "readdir(%s) failed: %m", dstorage->storage_dir);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ret = -1;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (closedir(dir) < 0) {
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen mail_storage_set_critical(storage,
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen "closedir(%s) failed: %m", dstorage->storage_dir);
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen ret = -1;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen }
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen return ret;
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen}
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenint mdbox_sync_purge(struct mail_storage *_storage)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen{
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen struct mdbox_storage *storage = (struct mdbox_storage *)_storage;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen ARRAY_TYPE(seq_range) ref0_file_ids;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct dbox_file *file;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct seq_range_iter iter;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen unsigned int i = 0;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t file_id;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen bool deleted;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret = 0;
i_array_init(&ref0_file_ids, 64);
if (dbox_map_get_zero_ref_files(storage->map, &ref0_file_ids) < 0)
ret = -1;
/* add also files that can be altmoved */
if (mdbox_sync_altmove_add_files(storage, &ref0_file_ids) < 0)
ret = -1;
seq_range_array_iter_init(&iter, &ref0_file_ids); i = 0;
while (seq_range_array_iter_nth(&iter, i++, &file_id)) T_BEGIN {
file = mdbox_file_init(storage, file_id);
if (dbox_file_open(file, &deleted) > 0 && !deleted) {
if (mdbox_file_purge(file) < 0)
ret = -1;
} else {
dbox_map_remove_file_id(storage->map, file_id);
}
dbox_file_unref(&file);
} T_END;
array_free(&ref0_file_ids);
return ret;
}