virtual-sync.c revision 7e209b78ca757294dbbc15604c88673b3a6b0c39
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *const *kw_all;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* messages expunged within this sync */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen ARRAY_DEFINE(all_adds, struct virtual_add_record);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_sync_set_uidvalidity(struct virtual_sync_context *ctx)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen offsetof(struct mail_index_header, uid_validity),
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_sync_external_flags(struct virtual_sync_context *ctx,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *const *kw_names;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* copy flags */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_index_update_flags(ctx->trans, vseq, MODIFY_REPLACE, flags);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* copy keywords */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen kw_names = mail_get_keywords(bbox->sync_mail);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen keywords = mail_index_keywords_create(ctx->index, kw_names);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mail_index_update_keywords(ctx->trans, vseq, MODIFY_REPLACE, keywords);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int virtual_sync_mail_cmp(const void *p1, const void *p2)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const struct virtual_sync_mail *m1 = p1, *m2 = p2;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (m1->vrec.mailbox_id < m2->vrec.mailbox_id)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (m1->vrec.mailbox_id > m2->vrec.mailbox_id)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenvirtual_backend_box_sync_mail_set(struct virtual_backend_box *bbox)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen trans = mailbox_transaction_begin(bbox->box, 0);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenvirtual_backend_box_sync_mail_unset(struct virtual_backend_box *bbox)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic int bbox_mailbox_id_cmp(const void *p1, const void *p2)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const struct virtual_backend_box *b1 = p1, *b2 = p2;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic bool virtual_sync_ext_header_read(struct virtual_sync_context *ctx)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const struct virtual_mail_index_header *ext_hdr;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const struct virtual_mail_index_mailbox_record *mailboxes;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen unsigned int i, count, ext_name_offset, ext_mailbox_count;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mail_index_get_header_ext(ctx->sync_view, ctx->mbox->virtual_ext_id,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ctx->mbox->prev_uid_validity == hdr->uid_validity &&
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ctx->mbox->prev_change_counter == ext_hdr->change_counter) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* fully refreshed */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ctx->mbox->prev_uid_validity = hdr->uid_validity;
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen ctx->mbox->search_args_crc32 != ext_hdr->search_args_crc32) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ctx->mbox->prev_change_counter = ext_hdr->change_counter;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ext_hdr->mailbox_count > INT_MAX/sizeof(*mailboxes)) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_error("virtual %s: Broken mailbox_count header",
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* update mailbox backends */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = 0; i < ext_mailbox_count; i++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (mailboxes[i].id > ext_hdr->highest_mailbox_id ||
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen i_error("virtual %s: Broken mailbox name_len",
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (ext_name_offset + mailboxes[i].name_len > ext_size) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const unsigned char *nameptr;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen nameptr = CONST_PTR_OFFSET(ext_data, ext_name_offset);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen name = t_strndup(nameptr, mailboxes[i].name_len);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bbox = virtual_backend_box_lookup_name(ctx->mbox, name);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* mailbox no longer exists */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bbox->sync_uid_validity = mailboxes[i].uid_validity;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bbox->sync_highest_modseq = mailboxes[i].highest_modseq;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ctx->mbox->highest_mailbox_id = ext_hdr->highest_mailbox_id;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* assign new mailbox IDs if any are missing */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bboxes = array_get_modifiable(&ctx->mbox->backend_boxes, &count);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = 0; i < count; i++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bboxes[i]->mailbox_id = ++ctx->mbox->highest_mailbox_id;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* sort the backend mailboxes by mailbox_id. */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen qsort(bboxes, count, sizeof(*bboxes), bbox_mailbox_id_cmp);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void virtual_sync_ext_header_rewrite(struct virtual_sync_context *ctx)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct virtual_mail_index_mailbox_record mailbox;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bboxes = array_get_modifiable(&ctx->mbox->backend_boxes, &count);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen name_pos = mailbox_pos + sizeof(mailbox) * count;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ext_hdr.change_counter = ++ctx->mbox->prev_change_counter;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ext_hdr.highest_mailbox_id = ctx->mbox->highest_mailbox_id;
7e209b78ca757294dbbc15604c88673b3a6b0c39Timo Sirainen ext_hdr.search_args_crc32 = ctx->mbox->search_args_crc32;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), name_pos + 256);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen buffer_append(buf, &ext_hdr, sizeof(ext_hdr));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = 0; i < count; i++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bboxes[i]->mailbox_id > bboxes[i-1]->mailbox_id);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mailbox.uid_validity = bboxes[i]->sync_uid_validity;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mailbox.highest_modseq = bboxes[i]->sync_highest_modseq;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen buffer_write(buf, mailbox_pos, &mailbox, sizeof(mailbox));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen buffer_write(buf, name_pos, bboxes[i]->name, mailbox.name_len);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mail_index_get_header_ext(ctx->sync_view, ctx->mbox->virtual_ext_id,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mail_index_ext_resize(ctx->trans, ctx->mbox->virtual_ext_id,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mail_index_update_header_ext(ctx->trans, ctx->mbox->virtual_ext_id,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void virtual_sync_ext_header_update(struct virtual_sync_context *ctx)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* we changed something - update the change counter in header */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ext_hdr.change_counter = ++ctx->mbox->prev_change_counter;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mail_index_update_header_ext(ctx->trans, ctx->mbox->virtual_ext_id,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen offsetof(struct virtual_mail_index_header, change_counter),
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen &ext_hdr.change_counter, sizeof(ext_hdr.change_counter));
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_sync_index_rec(struct virtual_sync_context *ctx,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen uint32_t virtual_ext_id = ctx->mbox->virtual_ext_id;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* don't care */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!mail_index_lookup_seq_range(ctx->sync_view,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* already expunged, nothing to do. */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_index_lookup_ext(ctx->sync_view, vseq, virtual_ext_id,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bbox = virtual_backend_box_lookup(ctx->mbox, vrec->mailbox_id);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (!mail_set_uid(bbox->sync_mail, vrec->real_uid))
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen flags = sync_rec->add_flags & MAIL_FLAGS_NONRECENT;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen flags = sync_rec->remove_flags & MAIL_FLAGS_NONRECENT;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen kw_names[0] = ctx->kw_all[sync_rec->keyword_idx];
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen keywords = mailbox_keywords_create_valid(bbox->box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen keywords = mailbox_keywords_create_valid(bbox->box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_update_keywords(bbox->sync_mail, MODIFY_REPLACE,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic void virtual_sync_index_changes(struct virtual_sync_context *ctx)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen keywords = mail_index_get_keywords(ctx->index);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen ctx->kw_all = array_count(keywords) == 0 ? NULL :
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen while (mail_index_sync_next(ctx->index_sync_ctx, &sync_rec))
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void virtual_sync_index_finish(struct virtual_sync_context *ctx)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* mark the newly seen messages as recent */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mail_index_lookup_seq_range(ctx->sync_view, hdr->first_recent_uid,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_mailbox_set_recent_seq(&ctx->mbox->ibox, ctx->sync_view,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* entire mailbox list needs to be rewritten */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* update only changed parts in the header */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic int virtual_sync_backend_box_init(struct virtual_backend_box *bbox)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen enum mailbox_search_result_flags result_flags;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen trans = mailbox_transaction_begin(bbox->box, 0);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen mail_search_args_init(bbox->search_args, bbox->box, FALSE, NULL);
db0735f9b388c5bcfb781b1b25015e898d63d953Timo Sirainen search_ctx = mailbox_search_init(trans, bbox->search_args, NULL);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* save the result and keep it updated */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen result_flags = MAILBOX_SEARCH_RESULT_FLAG_UPDATE |
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mailbox_search_result_save(search_ctx, result_flags);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* add the found UIDs to uidmap. virtual_uid gets assigned later. */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen while (mailbox_search_next(search_ctx, mail) > 0) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic int virtual_backend_uidmap_cmp(const void *p1, const void *p2)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const struct virtual_backend_uidmap *u1 = p1, *u2 = p2;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenvirtual_sync_backend_add_existing_uids(struct virtual_sync_context *ctx,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* add the currently existing UIDs to uidmap. */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen messages = mail_index_view_get_messages_count(ctx->sync_view);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mail_index_lookup_uid(ctx->sync_view, vseq, &vuid);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen seq_range_array_add(&result->uids, 0, vrec->real_uid);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* the uidmap must be sorted by real_uids */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen uids = array_get_modifiable(&bbox->uids, &uid_count);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen qsort(uids, uid_count, sizeof(*uids), virtual_backend_uidmap_cmp);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenvirtual_sync_backend_remove_expunged_uids(struct mail_search_result *result)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)result->box;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen unsigned int i, count;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = 0; i < count; i++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (uid = range[i].seq1; uid <= range[i].seq2; uid++) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (!mail_index_lookup_seq(ibox->view, uid, &seq))
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic int virtual_sync_backend_box_continue(struct virtual_sync_context *ctx,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const enum mailbox_search_result_flags result_flags =
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)bbox->box;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* build the initial search result from the existing UIDs */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen result = mailbox_search_result_alloc(bbox->box, bbox->search_args,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen virtual_sync_backend_add_existing_uids(ctx, bbox, result);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* changes done from now on must update the sync queue */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen virtual_sync_backend_remove_expunged_uids(result);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* get list of changed messages */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (!mail_index_lookup_seq_range(ibox->view, 1, bbox->sync_next_uid-1,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen t_array_init(&flag_updates, I_MIN(128, old_msg_count));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen modseq = mail_index_modseq_lookup(ibox->view, seq);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (index_search_result_update_flags(result, &flag_updates) < 0 ||
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen index_search_result_update_appends(result, old_msg_count) < 0) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic int virtual_backend_uidmap_bsearch_cmp(const void *key, const void *data)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen const struct virtual_backend_uidmap *uidmap = data;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenvirtual_sync_mailbox_box_remove(struct virtual_sync_context *ctx,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen unsigned int i, src, dest, uid_count, rec_count, left;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* everything in removed_uids should exist in bbox->uids */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen uidmap = array_get_modifiable(&bbox->uids, &rec_count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* find the first uidmap record to be removed */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (!bsearch_insert_pos(&uids[0].seq1, uidmap, rec_count,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* remove the unwanted messages */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen for (i = src = dest = 0; i < uid_count; i++) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen array_delete(&bbox->uids, dest + left, src - dest);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenvirtual_sync_mailbox_box_add(struct virtual_sync_context *ctx,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen unsigned int i, src, dest, uid_count, add_count, rec_count;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* none of added_uids should exist in bbox->uids. find the position
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen of the first inserted index. */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen uidmap = array_get_modifiable(&bbox->uids, &rec_count);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (rec_count == 0 || uids[0].seq1 > uidmap[rec_count-1].real_uid) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* fast path: usually messages are appended */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen } else if (bsearch_insert_pos(&uids[0].seq1, uidmap, rec_count,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* make space for all added UIDs. */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen uidmap = array_get_modifiable(&bbox->uids, &rec_count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* add/move the UIDs to their correct positions */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen for (i = 0; i < uid_count; i++) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen while (src < rec_count && uidmap[src].real_uid < uid) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic void virtual_sync_mailbox_box_update(struct virtual_sync_context *ctx,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen ARRAY_TYPE(seq_range) removed_uids, added_uids, temp_uids;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mailbox_search_result_sync(bbox->search_result,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* if any of the pending removes came back, we don't want to expunge
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen them anymore. also since they already exist, remove them from
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen added_uids. */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen count1 = array_count(&bbox->sync_pending_removes);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen array_append_array(&temp_uids, &bbox->sync_pending_removes);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen &bbox->sync_pending_removes, &added_uids) > 0) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* delay removing messages that don't match the search
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen criteria, but don't delay removing expunged messages */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen seq_range_array_remove_seq_range(&removed_uids,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen seq_range_array_merge(&bbox->sync_pending_removes,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen } else if (array_count(&bbox->sync_pending_removes) > 0) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* remove all current and old */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen seq_range_array_merge(&bbox->sync_pending_removes,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen virtual_sync_mailbox_box_remove(ctx, bbox, &removed_uids);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen virtual_sync_mailbox_box_add(ctx, bbox, &added_uids);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic bool virtual_sync_find_seqs(struct virtual_backend_box *bbox,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen unsigned int *idx1_r,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen unsigned int *idx2_r)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)bbox->box;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mail_index_lookup_uid(ibox->view, sync_rec->seq1, &uid1);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mail_index_lookup_uid(ibox->view, sync_rec->seq2, &uid2);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen uidmap = array_get_modifiable(&bbox->uids, &count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen (void)bsearch_insert_pos(&uid1, uidmap, count, sizeof(*uidmap),
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (idx == count || uidmap[idx].real_uid > uid2)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen while (idx < count && uidmap[idx].real_uid <= uid2) idx++;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic int virtual_sync_backend_box_sync(struct virtual_sync_context *ctx,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen sync_ctx = mailbox_sync_init(bbox->box, sync_flags);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen while (mailbox_sync_next(sync_ctx, &sync_rec)) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* no need to keep track of expunges */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen seq_range_array_add_range(&ctx->sync_expunges,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen return mailbox_sync_deinit(&sync_ctx, 0, NULL);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void virtual_sync_backend_ext_header(struct virtual_sync_context *ctx,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen const unsigned int uidval_pos =
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen offsetof(struct virtual_mail_index_mailbox_record,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct virtual_mail_index_mailbox_record mailbox;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mailbox_get_status(bbox->box, STATUS_UIDVALIDITY |
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (bbox->sync_uid_validity == status.uidvalidity &&
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bbox->sync_highest_modseq == status.highest_modseq)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* mailbox changed - update extension header */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen bbox->sync_highest_modseq = status.highest_modseq;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* we'll rewrite the entire header later */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mailbox.uid_validity = bbox->sync_uid_validity;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mailbox.highest_modseq = bbox->sync_highest_modseq;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mailbox_offset = sizeof(struct virtual_mail_index_header) +
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mail_index_update_header_ext(ctx->trans, ctx->mbox->virtual_ext_id,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic int virtual_sync_backend_box(struct virtual_sync_context *ctx,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct index_mailbox *ibox = (struct index_mailbox *)bbox->box;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* if we already did some changes to index, commit them before
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen syncing starts. */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* we use modseqs for speeding up initial search result build.
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen make sure the backend has them enabled. */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen sync_flags = ctx->flags & (MAILBOX_SYNC_FLAG_FULL_READ |
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* first sync in this process */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (mailbox_sync(bbox->box, sync_flags, STATUS_UIDVALIDITY,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (status.uidvalidity != bbox->sync_uid_validity) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* UID validity changed since last sync (or this is
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen the first sync), do a full search */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* build the initial search using the saved modseq.
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen we can't directly update the search result because
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen uidmap isn't finished for all messages yet, so
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen mark the sync to be retried. */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen ret = virtual_sync_backend_box_continue(ctx, bbox);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* sync using the existing search result */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen ret = virtual_sync_backend_box_sync(ctx, bbox, sync_flags);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic void virtual_sync_backend_map_uids(struct virtual_sync_context *ctx)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen uint32_t virtual_ext_id = ctx->mbox->virtual_ext_id;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen struct virtual_backend_box *bbox, *const *bboxes;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen unsigned int j = 0, uidmap_count = 0;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen messages = mail_index_view_get_messages_count(ctx->sync_view);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* sort the messages in current view by their backend mailbox and
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mail_index_lookup_ext(ctx->sync_view, vseq, virtual_ext_id,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen qsort(vmails, messages, sizeof(*vmails), virtual_sync_mail_cmp);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* create real mailbox uid -> virtual uid mapping and expunge
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen messages no longer matching the search rule */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen for (i = 0; i < messages; i++) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (bbox == NULL || bbox->mailbox_id != vrec->mailbox_id) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* add the rest of the newly seen messages */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen for (; j < uidmap_count; j++) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* the entire mailbox is lost */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mail_index_lookup_uid(ctx->sync_view, vseq, &vuid);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* if virtual record doesn't exist in uidmap, it's expunged */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen for (; j < uidmap_count; j++) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* newly seen message */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* exists - update uidmap and flags */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* if there are any mailboxes we didn't yet sync, add new messages in
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen bboxes = array_get(&ctx->mbox->backend_boxes, &count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen for (i = 0; i < count; i++) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen add_rec.rec.mailbox_id = bboxes[i]->mailbox_id;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen uidmap = array_get_modifiable(&bboxes[i]->uids, &uidmap_count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen for (j = 0; j < uidmap_count; j++) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic int virtual_add_record_cmp(const void *p1, const void *p2)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen const struct virtual_add_record *add1 = p1, *add2 = p2;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (add1->received_date < add2->received_date)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (add1->received_date > add2->received_date)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* if they're in same mailbox, we can order them correctly by the UID.
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if they're in different mailboxes, ordering by UID doesn't really
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen help but it doesn't really harm either. */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* two messages in different mailboxes have the same received date
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic void virtual_sync_backend_sort_new(struct virtual_sync_context *ctx)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen unsigned int i, count;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* get all messages' received dates */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen adds = array_get_modifiable(&ctx->all_adds, &count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (bbox == NULL || bbox->mailbox_id != vrec->mailbox_id) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (!mail_set_uid(bbox->sync_mail, vrec->real_uid))
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* probably expunged already, just add it somewhere */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen qsort(adds, count, sizeof(*adds), virtual_add_record_cmp);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainenstatic void virtual_sync_backend_add_new(struct virtual_sync_context *ctx)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen uint32_t virtual_ext_id = ctx->mbox->virtual_ext_id;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen adds = array_get_modifiable(&ctx->all_adds, &count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (adds[0].rec.mailbox_id == adds[count-1].rec.mailbox_id) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* all messages are from a single mailbox. add them in
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen the same order. */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* sort new messages by received date to get the add order */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (bbox == NULL || bbox->mailbox_id != vrec->mailbox_id) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mail_index_update_ext(ctx->trans, vseq, virtual_ext_id,
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen virtual_sync_external_flags(ctx, bbox, vseq, vrec->real_uid);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* assign UIDs to new messages */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen first_uid = mail_index_get_header(ctx->sync_view)->next_uid;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen mail_index_append_assign_uids(ctx->trans, first_uid, &next_uid);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* update virtual UIDs in uidmap */
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (bbox == NULL || bbox->mailbox_id != vrec->mailbox_id) {
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen uidmap = array_get_modifiable(&bbox->uids, &uid_count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (!bsearch_insert_pos(&vrec->real_uid, uidmap, uid_count,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int virtual_sync_backend_boxes(struct virtual_sync_context *ctx)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bboxes = array_get(&ctx->mbox->backend_boxes, &count);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < count; i++) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (virtual_sync_backend_box(ctx, bboxes[i]) < 0)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen /* initial sync: assign virtual UIDs to existing messages and
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen sync all flags */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void virtual_sync_backend_boxes_finish(struct virtual_sync_context *ctx)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bboxes = array_get(&ctx->mbox->backend_boxes, &count);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen for (i = 0; i < count; i++)
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen virtual_backend_box_sync_mail_unset(bboxes[i]);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int virtual_sync_finish(struct virtual_sync_context *ctx, bool success)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (mail_index_sync_commit(&ctx->index_sync_ctx) < 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_storage_set_index_error(&ctx->mbox->ibox);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_index_sync_rollback(&ctx->index_sync_ctx);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int virtual_sync(struct virtual_mailbox *mbox,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* Removed messages are expunged when
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen a) EXPUNGE is used
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen b) Mailbox is being opened (FIX_INCONSISTENT is set) */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_sync_flags = MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY |
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = mail_index_sync_begin(ctx->index, &ctx->index_sync_ctx,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* apply changes from virtual index to backend mailboxes */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* update list of UIDs in backend mailboxes */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvirtual_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (index_mailbox_want_full_sync(&mbox->ibox, flags))