mdbox-storage-rebuild.c revision cd89cbcf9ef73a0855ffcbe799b4fc2442b28cbb
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen ARRAY_DEFINE(msgs, struct mdbox_rebuild_msg *);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic unsigned int guid_hash(const void *p)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const uint8_t *s = p;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int i, g, h = 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen for (i = 0; i < MAIL_GUID_128_SIZE; i++) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen h = (h << 4) + s[i];
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if ((g = h & 0xf0000000UL)) {
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen h = h ^ (g >> 24);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int guid_cmp(const void *p1, const void *p2)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmdbox_storage_rebuild_init(struct mdbox_storage *storage)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ctx = i_new(struct mdbox_storage_rebuild_context, 1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ctx->pool = pool_alloconly_create("dbox map rebuild", 1024*256);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ctx->guid_hash = hash_table_create(default_pool, ctx->pool, 0,
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenmdbox_storage_rebuild_deinit(struct mdbox_storage_rebuild_context *ctx)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int mdbox_rebuild_msg_offset_cmp(const void *p1, const void *p2)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const struct mdbox_rebuild_msg *const *m1 = p1, *const *m2 = p2;
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainenstatic int mdbox_rebuild_msg_uid_cmp(struct mdbox_rebuild_msg *const *m1,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenstatic int rebuild_file_mails(struct mdbox_storage_rebuild_context *ctx,
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen while ((ret = dbox_file_seek_next(file, &offset, &last)) >= 0) {
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen if ((ret = dbox_file_metadata_read(file)) < 0)
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen /* file is corrupted. fix it and retry. */
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen /* use existing file header if it was ok */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* seek to the offset where we last left off */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen guid = dbox_file_metadata_get(file, DBOX_METADATA_GUID);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "Message is missing GUID");
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen rec = p_new(ctx->pool, struct mdbox_rebuild_msg, 1);
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen mail_generate_guid_128_hash(guid, rec->guid_128);
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen if (hash_table_lookup(ctx->guid_hash, rec->guid_128) != NULL) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* duplicate. save this as a refcount=0 to map,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen so it will eventually be deleted. */
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk hash_table_insert(ctx->guid_hash, rec->guid_128, rec);
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainenstatic int rebuild_add_file(struct mdbox_storage_rebuild_context *ctx,
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen unsigned int len;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen if (!is_numeric(fname, '\0') || file_id == 0) {
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen if (len > 7 && strcmp(fname + len - 7, ".broken") != 0) {
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen i_warning("dbox rebuild: File name is missing ID: %s",
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen /* small optimization: typically files are returned sorted. in that
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen case we don't need to sort them ourself. */
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen file = mdbox_file_init(ctx->storage, file_id);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if ((ret = dbox_file_open(file, &deleted)) > 0 && !deleted)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen i_error("dbox rebuild: Failed to fix file %s", path);
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenrebuild_add_missing_map_uids(struct mdbox_storage_rebuild_context *ctx,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen unsigned int i, count;
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen msgs = array_get_modifiable(&ctx->msgs, &count);
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen for (i = 0; i < count; i++) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_append(ctx->trans, msgs[i]->map_uid, &seq);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenstatic int rebuild_apply_map(struct mdbox_storage_rebuild_context *ctx)
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen struct mdbox_rebuild_msg search_msg, *search_msgp = &search_msg;
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen unsigned int count;
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen array_sort(&ctx->msgs, mdbox_rebuild_msg_offset_cmp);
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen msgs = array_get_modifiable(&ctx->msgs, &count);
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen for (seq = 1; seq <= hdr->messages_count; seq++) {
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen if (dbox_map_view_lookup_rec(map, ctx->sync_view,
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen /* look up the rebuild msg record for this message */
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen pos = bsearch(&search_msgp, msgs, count, sizeof(*msgs),
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen /* map record points to non-existing message. */
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen rebuild_add_missing_map_uids(ctx, hdr->next_uid);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen /* afterwards we're interested in looking up map_uids.
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen re-sort the messages to make it easier. */
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen array_sort(&ctx->msgs, mdbox_rebuild_msg_uid_cmp);
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainenrebuild_lookup_map_uid(struct mdbox_storage_rebuild_context *ctx,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen struct mdbox_rebuild_msg search_msg, *search_msgp = &search_msg;
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainenrebuild_mailbox_multi(struct mdbox_storage_rebuild_context *ctx,
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen struct dbox_sync_rebuild_context *rebuild_ctx,
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen const struct mdbox_mail_index_record *dbox_rec;
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen memset(&new_dbox_rec, 0, sizeof(new_dbox_rec));
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen for (seq = 1; seq <= hdr->messages_count; seq++) {
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen mail_index_lookup_ext(view, seq, mbox->ext_id,
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen map_uid = dbox_rec == NULL ? 0 : dbox_rec->map_uid;
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainen mail_index_lookup_ext(view, seq, mbox->guid_ext_id,
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen /* see if we can find this message based on
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen 1) GUID, 2) map_uid */
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen /* not a multi-dbox message, ignore. */
4a514fb20e04df397842cde11cc9ea92abfe9728Timo Sirainen /* multi-dbox message that wasn't found with GUID.
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen either it's lost or GUID has been corrupted. we can
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen still try to look it up using map_uid. */
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen /* map_uid is wrong, update it */
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen mail_index_update_ext(trans, seq, mbox->ext_id,
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen /* everything was ok */
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen /* keep this message */
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen mail_index_update_ext(trans, new_seq, mbox->ext_id,
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenmdbox_rebuild_get_header(struct mail_index_view *view, uint32_t hdr_ext_id,
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen mail_index_get_header_ext(view, hdr_ext_id, &data, &data_size);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r)));
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenstatic void mdbox_header_update(struct dbox_sync_rebuild_context *rebuild_ctx,
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen mdbox_rebuild_get_header(rebuild_ctx->view, mbox->hdr_ext_id, &hdr);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen mdbox_rebuild_get_header(rebuild_ctx->backup_view,
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* make sure we have valid mailbox guid */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (mail_guid_128_is_empty(hdr.mailbox_guid)) {
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen if (!mail_guid_128_is_empty(backup_hdr.mailbox_guid)) {
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen memcpy(hdr.mailbox_guid, backup_hdr.mailbox_guid,
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen /* update map's uid-validity */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen hdr.map_uid_validity = dbox_map_get_uid_validity(mbox->storage->map);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* and write changes */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen mail_index_update_header_ext(rebuild_ctx->trans, mbox->hdr_ext_id, 0,
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenrebuild_mailbox(struct mdbox_storage_rebuild_context *ctx,
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct dbox_sync_rebuild_context *rebuild_ctx;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen box = mdbox_mailbox_alloc(&ctx->storage->storage.storage,
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen (void)mail_storage_get_last_error(box->storage, &error);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* non-temporary error, ignore */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen ret = mail_index_sync_begin(box->index, &sync_ctx, &view, &trans,
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen rebuild_ctx = dbox_sync_index_rebuild_init(&mbox->box, view, trans);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen rebuild_mailbox_multi(ctx, rebuild_ctx, mbox, view, trans);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenrebuild_namespace_mailboxes(struct mdbox_storage_rebuild_context *ctx,
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainenstatic int rebuild_mailboxes(struct mdbox_storage_rebuild_context *ctx)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct mail_user *user = ctx->storage->storage.storage.user;
0bd259973f98837cf0e41fdee3e2a578e51ad09eTimo Sirainen for (ns = user->namespaces; ns != NULL; ns = ns->next) {
0bd259973f98837cf0e41fdee3e2a578e51ad09eTimo Sirainen if (ns->storage == &ctx->storage->storage.storage &&
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenstatic int rebuild_msg_mailbox_commit(struct rebuild_msg_mailbox *msg)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (mail_index_sync_commit(&msg->sync_ctx) < 0)
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainenstatic int rebuild_restore_msg(struct mdbox_storage_rebuild_context *ctx,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct mail_storage *storage = &ctx->storage->storage.storage;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen /* first see if message contains the mailbox it was originally
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen file = mdbox_file_init(ctx->storage, msg->file_id);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen ret = dbox_file_get_mail_stream(file, msg->offset, NULL);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (ret > 0 && !deleted && dbox_file_metadata_read(file) > 0) {
8f70c97f7ab7b7e1683ed5cfcd96721a899c2520Timo Sirainen /* we shouldn't get here, so apparently we couldn't fix
8f70c97f7ab7b7e1683ed5cfcd96721a899c2520Timo Sirainen something. just ignore the mail.. */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* we have the destination mailbox. now open it and add the message
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen strcmp(mailbox, ctx->prev_msg.box->name) == 0 ?
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen box = mdbox_mailbox_alloc(storage, ctx->default_list,
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen (void)mail_storage_get_last_error(box->storage, &error);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (error == MAIL_ERROR_NOTFOUND && !created) {
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* mailbox doesn't exist currently? see if creating
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* see if we can save to INBOX instead. */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* this shouldn't happen */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* switch the mailbox cache if necessary */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (box != ctx->prev_msg.box && ctx->prev_msg.box != NULL) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (rebuild_msg_mailbox_commit(&ctx->prev_msg) < 0)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen hdr = mail_index_get_header(ctx->prev_msg.view);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen /* add the new message */
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen mail_index_append(ctx->prev_msg.trans, ctx->prev_msg.next_uid++, &seq);
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen mail_index_update_ext(ctx->prev_msg.trans, seq, mbox->ext_id,
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen mail_index_update_ext(ctx->prev_msg.trans, seq, mbox->guid_ext_id,
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainenstatic int rebuild_handle_zero_refs(struct mdbox_storage_rebuild_context *ctx)
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen unsigned int i, count;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen /* if we have messages at this point which have refcount=0, they're
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen either already expunged or they were somehow lost for some reason.
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen we'll need to figure out what to do about them. */
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen msgs = array_get_modifiable(&ctx->msgs, &count);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen for (i = 0; i < count; i++) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* we've seen the map record, trust it. */
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen /* either map record was lost for this message or the message
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen was lost from its mailbox. safest way to handle this is to
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen restore the message. */
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (rebuild_msg_mailbox_commit(&ctx->prev_msg) < 0)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenstatic void rebuild_update_refcounts(struct mdbox_storage_rebuild_context *ctx)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen unsigned int i, count;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* update refcounts for existing map records */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen msgs = array_get_modifiable(&ctx->msgs, &count);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen for (seq = 1, i = 0; seq <= hdr->messages_count && i < count; seq++) {
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_index_lookup_uid(ctx->sync_view, seq, &map_uid);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen /* we've already expunged this map record */
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen if (ref16_p == NULL || *ref16_p != msgs[i]->refcount) {
cb933f0a570a9cef5c975eadb818aa6b1002a269Timo Sirainen /* update refcounts for newly created map records */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int rebuild_finish(struct mdbox_storage_rebuild_context *ctx)
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainenstatic int mdbox_storage_rebuild_scan(struct mdbox_storage_rebuild_context *ctx)
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen unsigned int dir_len;
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen if (dbox_map_open(ctx->storage->map, TRUE) < 0)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen /* begin by locking the map, so that other processes can't try to
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen rebuild at the same time. */
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen ret = mail_index_sync_begin(ctx->storage->map->index, &ctx->sync_ctx,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_storage_set_internal_error(&ctx->storage->storage.storage);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_reset_error(ctx->storage->map->index);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uid_validity = dbox_map_get_uid_validity(ctx->storage->map);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen offsetof(struct mail_index_header, uid_validity),
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_storage_set_critical(&ctx->storage->storage.storage,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "opendir(%s) failed: %m", ctx->storage->storage_dir);
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen for (errno = 0; (d = readdir(dir)) != NULL; errno = 0) {
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen if (strncmp(d->d_name, MDBOX_MAIL_FILE_PREFIX,
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen mail_storage_set_critical(&ctx->storage->storage.storage,
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen "readdir(%s) failed: %m", ctx->storage->storage_dir);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen mail_storage_set_critical(&ctx->storage->storage.storage,
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen "closedir(%s) failed: %m", ctx->storage->storage_dir);
e200d1ba38eeebfb0b9e60150d93753ec6d823c8Timo Sirainenint mdbox_storage_rebuild(struct mdbox_storage *storage)
d06c46087e9e6e66bbbbb9df1d5b33154349515cTimo Sirainen /* no multi-dbox files */
47d5cc09738defd0020c797866e2a25a344aa65aTimo Sirainen mail_storage_set_critical(&storage->storage.storage,
47d5cc09738defd0020c797866e2a25a344aa65aTimo Sirainen i_warning("dbox %s: rebuilding indexes", storage->storage_dir);