int mdbox_mail_open(struct dbox_mail *mail, uoff_t *offset_r, struct dbox_file **file_r) { struct mail *_mail = &mail->imail.mail.mail; struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)_mail->box; uint32_t prev_file_id = 0, map_uid = 0; bool deleted; if (_mail->lookup_abort != MAIL_LOOKUP_ABORT_NEVER) { mail_set_aborted(_mail); return -1; } do { if (mail->open_file != NULL) { /* already open */ } else if (!_mail->saving) { if (mdbox_mail_lookup(mbox, _mail->transaction->view, _mail->seq, &map_uid) < 0) return -1; if (dbox_mail_open_init(mail, map_uid) < 0) return -1; } else { /* mail is being saved in this transaction */ mail->open_file = mdbox_save_file_get_file(_mail->transaction, _mail->seq, &mail->offset); } if (!dbox_file_is_open(mail->open_file)) mail->imail.mail.stats_open_lookup_count++; if (dbox_file_open(mail->open_file, &deleted) <= 0) return -1; if (deleted) { /* either it's expunged now or moved to another file. */ struct mdbox_file *mfile = (struct mdbox_file *)mail->open_file; if (mfile->file_id == prev_file_id) { dbox_mail_set_expunged(mail, map_uid); return -1; } prev_file_id = mfile->file_id; if (mdbox_map_refresh(mbox->storage->map) < 0) return -1; dbox_file_unref(&mail->open_file); } } while (mail->open_file == NULL); *file_r = mail->open_file; *offset_r = mail->offset; return 0; }
static int mdbox_sync_expunge(struct mdbox_sync_context *ctx, uint32_t seq, const guid_128_t guid_128) { uint32_t map_uid; if (seq_range_array_add(&ctx->expunged_seqs, seq)) { /* already marked as expunged in this sync */ return 0; } if (dbox_sync_verify_expunge_guid(ctx, seq, guid_128) < 0) return -1; if (mdbox_mail_lookup(ctx->mbox, ctx->sync_view, seq, &map_uid) < 0) return -1; if (mdbox_map_update_refcount(ctx->map_trans, map_uid, -1) < 0) return -1; return 0; }