sdbox-storage.c revision 0a7b04ec6441fdcf083392888b2e30844fc3e86d
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen/* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenextern struct mail_storage dbox_storage, sdbox_storage;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenextern struct dbox_storage_vfuncs sdbox_dbox_storage_vfuncs;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstatic struct mail_storage *sdbox_storage_alloc(void)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen pool = pool_alloconly_create("sdbox storage", 512+256);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen storage = p_new(pool, struct sdbox_storage, 1);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen storage->storage.v = sdbox_dbox_storage_vfuncs;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstatic struct mailbox *
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainensdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen /* dbox can't work without index files */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen pool = pool_alloconly_create("sdbox mailbox", 1024*3);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen index_storage_mailbox_alloc(&mbox->box, name, flags, DBOX_INDEX_PREFIX);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->save_commit_pre = sdbox_transaction_save_commit_pre;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->save_commit_post = sdbox_transaction_save_commit_post;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->save_rollback = sdbox_transaction_save_rollback;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ibox->index_flags |= MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS |
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mbox->storage = (struct sdbox_storage *)storage;
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen mail_index_ext_register(mbox->box.index, "dbox-hdr",
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen sizeof(struct sdbox_index_header), 0, 0);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainenint sdbox_read_header(struct sdbox_mailbox *mbox,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen struct sdbox_index_header *hdr, bool log_error)
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mail_index_get_header_ext(view, mbox->hdr_ext_id,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE &&
6060b7c8edf8fce73470d0df6a2479b69b01c537Timo Sirainen "sdbox %s: Invalid dbox header size",
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenvoid sdbox_update_header(struct sdbox_mailbox *mbox,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (update != NULL && !mail_guid_128_is_empty(update->mailbox_guid)) {
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen } else if (mail_guid_128_is_empty(new_hdr.mailbox_guid)) {
8000c86be02008b74acc71fa422444dc432e2c01Timo Sirainen if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
8000c86be02008b74acc71fa422444dc432e2c01Timo Sirainen mail_index_update_header_ext(trans, mbox->hdr_ext_id, 0,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenstatic int sdbox_mailbox_create_indexes(struct mailbox *box,
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen struct mail_index_transaction *new_trans = NULL;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen new_trans = mail_index_transaction_begin(box->view, 0);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (update != NULL && update->uid_validity != 0)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen /* set uidvalidity */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen uid_validity = dbox_get_uidvalidity_next(box->list);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen /* UIDVALIDITY change requires index to be reset */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen offsetof(struct mail_index_header, uid_validity),
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (update != NULL && hdr->next_uid < update->min_next_uid) {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (update != NULL && update->min_first_recent_uid != 0 &&
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen hdr->first_recent_uid < update->min_first_recent_uid) {
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen uint32_t first_recent_uid = update->min_first_recent_uid;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen offsetof(struct mail_index_header, first_recent_uid),
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen &first_recent_uid, sizeof(first_recent_uid), FALSE);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (update != NULL && update->min_highest_modseq != 0 &&
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (mail_index_transaction_commit(&new_trans) < 0) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen mail_storage_set_internal_error(box->storage);
c74ea62a27878910e3ca1614ca055d7e2b3b00d5Timo Sirainenstatic const char *
c74ea62a27878910e3ca1614ca055d7e2b3b00d5Timo Sirainensdbox_get_attachment_path_suffix(struct dbox_file *_file)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen struct sdbox_file *file = (struct sdbox_file *)_file;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen mail_guid_128_to_string(file->mbox->mailbox_guid),
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenvoid sdbox_set_mailbox_corrupted(struct mailbox *box)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (sdbox_read_header(mbox, &hdr, TRUE) < 0 || hdr.rebuild_count == 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mbox->corrupted_rebuild_count = hdr.rebuild_count;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic void sdbox_set_file_corrupted(struct dbox_file *_file)
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct sdbox_file *file = (struct sdbox_file *)_file;
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen sdbox_set_mailbox_corrupted(&file->mbox->box);
185ed0142fbbfb86e7a98519e7c6f11ec00723cdTimo Sirainenstatic int sdbox_mailbox_open(struct mailbox *box)
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* wait for mailbox creation to initialize the index */
a12399903f415a7e14c2816cffa2f7a09dcbb097Timo Sirainen /* get/generate mailbox guid */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (sdbox_read_header(mbox, &hdr, FALSE) < 0) {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* it's possible that this mailbox is just now being created
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen by another process. lock it first and see if the header is
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen available then. */
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (mail_index_sync_begin(box->index, &sync_ctx,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* regenerate it */
struct mailbox_transaction_context *t;
.class_flags = 0,
NULL,
NULL,
NULL,
.class_flags = 0,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,