sdbox-sync.c revision ae1636c09e096904119db3410ba911625246f892
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen#include "lib.h"
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen#include "dbox-attachment.h"
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen#include "sdbox-storage.h"
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen#include "sdbox-file.h"
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen#include "sdbox-sync.h"
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen#define SDBOX_REBUILD_COUNT 3
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
71df09024cea5f2faa93da3bb9513ee96ba6bf22Timo Sirainenstatic void
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainendbox_sync_file_move_if_needed(struct dbox_file *file,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen enum sdbox_sync_entry_type type)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen bool move_to_alt = type == SDBOX_SYNC_ENTRY_TYPE_MOVE_TO_ALT;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen bool deleted;
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen if (move_to_alt != dbox_file_is_in_alt(file)) {
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen /* move the file. if it fails, nothing broke so
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen don't worry about it. */
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen if (dbox_file_open(file, &deleted) > 0 && !deleted)
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen (void)sdbox_file_move(file, move_to_alt);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenstatic void sdbox_sync_file(struct sdbox_sync_context *ctx,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen uint32_t seq, uint32_t uid,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen enum sdbox_sync_entry_type type)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct dbox_file *file;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen switch (type) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen case SDBOX_SYNC_ENTRY_TYPE_EXPUNGE:
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (!mail_index_transaction_is_expunged(ctx->trans, seq)) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mail_index_expunge(ctx->trans, seq);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen array_append(&ctx->expunged_uids, &uid, 1);
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen break;
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen case SDBOX_SYNC_ENTRY_TYPE_MOVE_FROM_ALT:
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen case SDBOX_SYNC_ENTRY_TYPE_MOVE_TO_ALT:
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen file = sdbox_file_init(ctx->mbox, uid);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen dbox_sync_file_move_if_needed(file, type);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen dbox_file_unref(&file);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen break;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenstatic void sdbox_sync_add(struct sdbox_sync_context *ctx,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen const struct mail_index_sync_rec *sync_rec)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen uint32_t uid;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen enum sdbox_sync_entry_type type;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen uint32_t seq, seq1, seq2;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (sync_rec->type == MAIL_INDEX_SYNC_TYPE_EXPUNGE) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* we're interested */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen type = SDBOX_SYNC_ENTRY_TYPE_EXPUNGE;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen } else if (sync_rec->type == MAIL_INDEX_SYNC_TYPE_FLAGS) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* we care only about alt flag changes */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if ((sync_rec->add_flags & DBOX_INDEX_FLAG_ALT) != 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen type = SDBOX_SYNC_ENTRY_TYPE_MOVE_TO_ALT;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen else if ((sync_rec->remove_flags & DBOX_INDEX_FLAG_ALT) != 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen type = SDBOX_SYNC_ENTRY_TYPE_MOVE_FROM_ALT;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen else
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen } else {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* not interested */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (!mail_index_lookup_seq_range(ctx->sync_view,
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen sync_rec->uid1, sync_rec->uid2,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen &seq1, &seq2)) {
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen /* already expunged everything. nothing to do. */
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen return;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen for (seq = seq1; seq <= seq2; seq++) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &uid);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen sdbox_sync_file(ctx, seq, uid, type);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen }
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainenstatic int sdbox_sync_index(struct sdbox_sync_context *ctx)
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct mailbox *box = &ctx->mbox->box;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen const struct mail_index_header *hdr;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct mail_index_sync_rec sync_rec;
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen uint32_t seq1, seq2;
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen hdr = mail_index_get_header(ctx->sync_view);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (hdr->uid_validity == 0) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* newly created index file */
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen mail_storage_set_critical(box->storage,
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen "sdbox %s: Broken index: missing UIDVALIDITY",
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen mailbox_get_path(box));
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen return 0;
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen }
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen /* mark the newly seen messages as recent */
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen if (mail_index_lookup_seq_range(ctx->sync_view, hdr->first_recent_uid,
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen hdr->next_uid, &seq1, &seq2))
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen index_mailbox_set_recent_seq(box, ctx->sync_view, seq1, seq2);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec))
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen sdbox_sync_add(ctx, &sync_rec);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen return 1;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainenstatic void dbox_sync_file_expunge(struct sdbox_sync_context *ctx,
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen uint32_t uid)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen struct mailbox *box = &ctx->mbox->box;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct dbox_file *file;
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen struct sdbox_file *sfile;
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen int ret;
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen file = sdbox_file_init(ctx->mbox, uid);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen sfile = (struct sdbox_file *)file;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (file->storage->attachment_dir != NULL)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = sdbox_file_unlink_with_attachments(sfile);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen else
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = dbox_file_unlink(file);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* do sync_notify only when the file was unlinked by us */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (ret > 0 && box->v.sync_notify != NULL)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen box->v.sync_notify(box, uid, MAILBOX_SYNC_TYPE_EXPUNGE);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen dbox_file_unref(&file);
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen}
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenstatic void dbox_sync_expunge_files(struct sdbox_sync_context *ctx)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen const uint32_t *uidp;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen /* NOTE: Index is no longer locked. Multiple processes may be unlinking
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen the files at the same time. */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen array_foreach(&ctx->expunged_uids, uidp)
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen dbox_sync_file_expunge(ctx, *uidp);
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen if (ctx->mbox->box.v.sync_notify != NULL)
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen ctx->mbox->box.v.sync_notify(&ctx->mbox->box, 0, 0);
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen}
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainenstatic int
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainensdbox_refresh_header(struct sdbox_mailbox *mbox, bool retry, bool log_error)
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct mail_index_view *view;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct sdbox_index_header hdr;
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen int ret;
88339cce70862ea6c6fac5615975e1e94a52a72eTimo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen view = mail_index_view_open(mbox->box.index);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = sdbox_read_header(mbox, &hdr, log_error);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen mail_index_view_close(&view);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen if (ret < 0 && retry) {
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen (void)mail_index_refresh(mbox->box.index);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen return sdbox_refresh_header(mbox, FALSE, log_error);
3c3002ee03e2c20034f73cfec80c6647320bd27cTimo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return ret;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenint sdbox_sync_begin(struct sdbox_mailbox *mbox, enum sdbox_sync_flags flags,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct sdbox_sync_context **ctx_r)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct mail_storage *storage = mbox->box.storage;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct sdbox_sync_context *ctx;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen enum mail_index_sync_flags sync_flags;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen unsigned int i;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen int ret;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen bool rebuild, force_rebuild;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen force_rebuild = (flags & SDBOX_SYNC_FLAG_FORCE_REBUILD) != 0;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen rebuild = force_rebuild ||
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mbox->corrupted_rebuild_count != 0 ||
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen sdbox_refresh_header(mbox, TRUE, FALSE) < 0;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ctx = i_new(struct sdbox_sync_context, 1);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ctx->mbox = mbox;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ctx->flags = flags;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen i_array_init(&ctx->expunged_uids, 32);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen sync_flags = index_storage_get_sync_flags(&mbox->box);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (!rebuild && (flags & SDBOX_SYNC_FLAG_FORCE) == 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen if ((flags & SDBOX_SYNC_FLAG_FSYNC) != 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_FSYNC;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* don't write unnecessary dirty flag updates */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen sync_flags |= MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen for (i = 0;; i++) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = mail_index_sync_begin(mbox->box.index,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen &ctx->index_sync_ctx,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen &ctx->sync_view, &ctx->trans,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen sync_flags);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (ret <= 0) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (ret < 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mail_storage_set_index_error(&mbox->box);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen array_free(&ctx->expunged_uids);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen i_free(ctx);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen *ctx_r = NULL;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return ret;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (rebuild)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = 0;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen else {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if ((ret = sdbox_sync_index(ctx)) > 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen break;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* failure. keep the index locked while we're doing a
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen rebuild. */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (ret == 0) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (i >= SDBOX_REBUILD_COUNT) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mail_storage_set_critical(storage,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen "sdbox %s: Index keeps breaking",
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mailbox_get_path(&ctx->mbox->box));
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = -1;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen } else {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen /* do a full resync and try again. */
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen i_warning("sdbox %s: Rebuilding index",
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mailbox_get_path(&ctx->mbox->box));
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen rebuild = FALSE;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = sdbox_sync_index_rebuild(mbox,
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen force_rebuild);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mail_index_sync_rollback(&ctx->index_sync_ctx);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (ret < 0) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen array_free(&ctx->expunged_uids);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen i_free(ctx);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return -1;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen *ctx_r = ctx;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return 0;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenint sdbox_sync_finish(struct sdbox_sync_context **_ctx, bool success)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct sdbox_sync_context *ctx = *_ctx;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen int ret = success ? 0 : -1;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen *_ctx = NULL;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (success) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (mail_index_sync_commit(&ctx->index_sync_ctx) < 0) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mail_storage_set_index_error(&ctx->mbox->box);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = -1;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen } else {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen dbox_sync_expunge_files(ctx);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen } else {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen mail_index_sync_rollback(&ctx->index_sync_ctx);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen array_free(&ctx->expunged_uids);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen i_free(ctx);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return ret;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenint sdbox_sync(struct sdbox_mailbox *mbox, enum sdbox_sync_flags flags)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct sdbox_sync_context *sync_ctx;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (sdbox_sync_begin(mbox, flags, &sync_ctx) < 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return -1;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (sync_ctx == NULL)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return 0;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return sdbox_sync_finish(&sync_ctx, TRUE);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainenstruct mailbox_sync_context *
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainensdbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen{
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen enum sdbox_sync_flags sdbox_sync_flags = 0;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen int ret = 0;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (!box->opened) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (mailbox_open(box) < 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = -1;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if (ret == 0 && index_mailbox_want_full_sync(&mbox->box, flags)) {
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0)
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen sdbox_sync_flags |= SDBOX_SYNC_FLAG_FORCE_REBUILD;
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen ret = sdbox_sync(mbox, sdbox_sync_flags);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen }
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen return index_mailbox_sync_init(box, flags, ret < 0);
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen}
f6d57a2c182f63cd52819f0abb3c3d9f828afe19Timo Sirainen