From: Timo Sirainen Date: Mon, 23 Mar 2009 22:15:50 +0000 (-0400) Subject: dbox: Create usable indexes when mailboxes are created. X-Git-Tag: 2.0.alpha1~1038^2~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d1bf0693a0b6587d1f91e143f03b550d492a93de;p=thirdparty%2Fdovecot%2Fcore.git dbox: Create usable indexes when mailboxes are created. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox/dbox-save.c b/src/lib-storage/index/dbox/dbox-save.c index 31e62b074c..8af6e21c27 100644 --- a/src/lib-storage/index/dbox/dbox-save.c +++ b/src/lib-storage/index/dbox/dbox-save.c @@ -307,6 +307,30 @@ void dbox_save_cancel(struct mail_save_context *_ctx) (void)dbox_save_finish(_ctx); } +static void dbox_add_missing_map_uidvalidity(struct dbox_save_context *ctx) +{ + const struct dbox_index_header *hdr; + struct dbox_index_header new_hdr; + const void *data; + size_t data_size; + + mail_index_get_header_ext(ctx->mbox->ibox.view, + ctx->mbox->dbox_hdr_ext_id, + &data, &data_size); + if (data_size == sizeof(*hdr)) { + hdr = data; + if (hdr->map_uid_validity != 0) + return; + new_hdr = *hdr; + } else { + memset(&new_hdr, 0, sizeof(new_hdr)); + } + new_hdr.map_uid_validity = + dbox_map_get_uid_validity(ctx->mbox->storage->map); + mail_index_update_header_ext(ctx->trans, ctx->mbox->dbox_hdr_ext_id, 0, + &new_hdr, sizeof(new_hdr)); +} + int dbox_transaction_save_commit_pre(struct dbox_save_context *ctx) { struct dbox_transaction_context *t = @@ -355,6 +379,8 @@ int dbox_transaction_save_commit_pre(struct dbox_save_context *ctx) unsigned int i, count; uint32_t next_map_uid = first_map_uid; + dbox_add_missing_map_uidvalidity(ctx); + memset(&rec, 0, sizeof(rec)); mails = array_get(&ctx->mails, &count); for (i = 0; i < count; i++) { diff --git a/src/lib-storage/index/dbox/dbox-storage-rebuild.c b/src/lib-storage/index/dbox/dbox-storage-rebuild.c index 5c4a45e431..8c2b56e697 100644 --- a/src/lib-storage/index/dbox/dbox-storage-rebuild.c +++ b/src/lib-storage/index/dbox/dbox-storage-rebuild.c @@ -717,8 +717,7 @@ int dbox_storage_rebuild(struct dbox_storage *storage) } storage->have_multi_msgs = TRUE; - if (storage->sync_rebuild) - i_warning("dbox %s: rebuilding indexes", storage->storage_dir); + i_warning("dbox %s: rebuilding indexes", storage->storage_dir); ctx = dbox_storage_rebuild_init(storage); ret = dbox_storage_rebuild_scan(ctx); diff --git a/src/lib-storage/index/dbox/dbox-storage.c b/src/lib-storage/index/dbox/dbox-storage.c index 3ef8b27d3a..495db9baad 100644 --- a/src/lib-storage/index/dbox/dbox-storage.c +++ b/src/lib-storage/index/dbox/dbox-storage.c @@ -8,6 +8,7 @@ #include "unlink-old-files.h" #include "index-mail.h" #include "mail-copy.h" +#include "mailbox-uidvalidity.h" #include "maildir/maildir-uidlist.h" #include "dbox-map.h" #include "dbox-file.h" @@ -215,23 +216,6 @@ static void dbox_destroy(struct mail_storage *_storage) index_storage_destroy(_storage); } -static int create_dbox(struct mail_storage *storage, const char *path) -{ - mode_t mode; - gid_t gid; - - mailbox_list_get_dir_permissions(storage->list, &mode, &gid); - if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) < 0 && - errno != EEXIST) { - if (!mail_storage_set_error_from_errno(storage)) { - mail_storage_set_critical(storage, - "mkdir(%s) failed: %m", path); - } - return -1; - } - return 0; -} - static const char * dbox_get_alt_path(struct dbox_storage *storage, const char *path) { @@ -297,6 +281,63 @@ dbox_open(struct dbox_storage *storage, const char *name, return &mbox->ibox.box; } +uint32_t dbox_get_uidvalidity_next(struct mail_storage *storage) +{ + const char *path; + + path = mailbox_list_get_path(storage->list, NULL, + MAILBOX_LIST_PATH_TYPE_CONTROL); + path = t_strconcat(path, "/"DBOX_UIDVALIDITY_FILE_NAME, NULL); + return mailbox_uidvalidity_next(path); +} + +static void dbox_write_index_header(struct mailbox *box) +{ + struct dbox_mailbox *mbox = (struct dbox_mailbox *)box; + struct mail_index_transaction *trans; + struct dbox_index_header hdr; + uint32_t uid_validity; + + trans = mail_index_transaction_begin(mbox->ibox.view, 0); + + /* set dbox header */ + memset(&hdr, 0, sizeof(hdr)); + mail_index_update_header_ext(trans, mbox->dbox_hdr_ext_id, 0, + &hdr, sizeof(hdr)); + + /* set uidvalidity */ + uid_validity = dbox_get_uidvalidity_next(&mbox->storage->storage); + mail_index_update_header(trans, + offsetof(struct mail_index_header, uid_validity), + &uid_validity, sizeof(uid_validity), TRUE); + + (void)mail_index_transaction_commit(&trans); +} + +static int create_dbox(struct mail_storage *_storage, const char *path, + const char *name) +{ + struct dbox_storage *storage = (struct dbox_storage *)_storage; + struct mailbox *box; + mode_t mode; + gid_t gid; + + mailbox_list_get_dir_permissions(_storage->list, &mode, &gid); + if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) == 0) { + /* create indexes immediately with the dbox header */ + box = dbox_open(storage, name, MAILBOX_OPEN_KEEP_RECENT); + dbox_write_index_header(box); + mailbox_close(&box); + } else if (errno != EEXIST) { + if (!mail_storage_set_error_from_errno(_storage)) { + mail_storage_set_critical(_storage, + "mkdir(%s) failed: %m", path); + } + return -1; + } + return 0; +} + static bool dbox_cleanup_if_exists(struct mail_storage *storage, const char *path) { @@ -341,7 +382,7 @@ dbox_mailbox_open(struct mail_storage *_storage, const char *name, if (strcmp(name, "INBOX") == 0 && (_storage->ns->flags & NAMESPACE_FLAG_INBOX) != 0) { /* INBOX always exists, create it */ - if (create_dbox(_storage, path) < 0) + if (create_dbox(_storage, path, "INBOX") < 0) return NULL; return dbox_open(storage, name, flags); } @@ -393,7 +434,7 @@ static int dbox_mailbox_create(struct mail_storage *_storage, return -1; } - return create_dbox(_storage, path); + return create_dbox(_storage, path, name); } static int diff --git a/src/lib-storage/index/dbox/dbox-storage.h b/src/lib-storage/index/dbox/dbox-storage.h index 17d62856f3..3b4b464091 100644 --- a/src/lib-storage/index/dbox/dbox-storage.h +++ b/src/lib-storage/index/dbox/dbox-storage.h @@ -102,6 +102,7 @@ dbox_mail_alloc(struct mailbox_transaction_context *t, /* Get map_uid for wanted message. */ int dbox_mail_lookup(struct dbox_mailbox *mbox, struct mail_index_view *view, uint32_t seq, uint32_t *map_uid_r); +uint32_t dbox_get_uidvalidity_next(struct mail_storage *storage); struct mail_save_context * dbox_save_alloc(struct mailbox_transaction_context *_t); diff --git a/src/lib-storage/index/dbox/dbox-sync-rebuild.c b/src/lib-storage/index/dbox/dbox-sync-rebuild.c index 9d8e23b0b5..109a9efb74 100644 --- a/src/lib-storage/index/dbox/dbox-sync-rebuild.c +++ b/src/lib-storage/index/dbox/dbox-sync-rebuild.c @@ -2,7 +2,6 @@ #include "lib.h" #include "array.h" -#include "mailbox-uidvalidity.h" #include "dbox-storage.h" #include "maildir/maildir-uidlist.h" #include "maildir/maildir-keywords.h" @@ -35,16 +34,6 @@ struct dbox_sync_rebuild_context { unsigned int storage_rebuild:1; }; -static uint32_t dbox_get_uidvalidity_next(struct mail_storage *storage) -{ - const char *path; - - path = mailbox_list_get_path(storage->list, NULL, - MAILBOX_LIST_PATH_TYPE_CONTROL); - path = t_strconcat(path, "/"DBOX_UIDVALIDITY_FILE_NAME, NULL); - return mailbox_uidvalidity_next(path); -} - static void dbox_sync_set_uidvalidity(struct dbox_sync_rebuild_context *ctx) { struct mail_storage *storage = &ctx->mbox->storage->storage; diff --git a/src/lib-storage/index/dbox/dbox-sync.c b/src/lib-storage/index/dbox/dbox-sync.c index e4d6ea8c4d..4e206fcc90 100644 --- a/src/lib-storage/index/dbox/dbox-sync.c +++ b/src/lib-storage/index/dbox/dbox-sync.c @@ -264,6 +264,7 @@ int dbox_sync_begin(struct dbox_mailbox *mbox, enum dbox_sync_flags flags, if (!storage_rebuilt) { /* we'll need to rebuild storage too. try again from the beginning. */ + mbox->storage->sync_rebuild = TRUE; mail_index_sync_rollback(&ctx->index_sync_ctx); i_free(ctx); return dbox_sync_begin(mbox, flags, ctx_r);