]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dbox: Create usable indexes when mailboxes are created.
authorTimo Sirainen <tss@iki.fi>
Mon, 23 Mar 2009 22:15:50 +0000 (18:15 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 23 Mar 2009 22:15:50 +0000 (18:15 -0400)
--HG--
branch : HEAD

src/lib-storage/index/dbox/dbox-save.c
src/lib-storage/index/dbox/dbox-storage-rebuild.c
src/lib-storage/index/dbox/dbox-storage.c
src/lib-storage/index/dbox/dbox-storage.h
src/lib-storage/index/dbox/dbox-sync-rebuild.c
src/lib-storage/index/dbox/dbox-sync.c

index 31e62b074cfae14a987fdd7d7a290488ba44cce6..8af6e21c27304b4292a4f60811d47e3f6fe7b071 100644 (file)
@@ -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++) {
index 5c4a45e43141638574ae362fe742da3cf316ebf1..8c2b56e697f6511c59c07e40f2c4c7228aa168fc 100644 (file)
@@ -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);
index 3ef8b27d3aecd85cafb2640768bc2fd3aff2bf93..495db9baad0fbd85b4e0b0032fa29de9d2563cc8 100644 (file)
@@ -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
index 17d62856f3ecea9915c403da951d305e8b7d2e22..3b4b464091e0ecdcd3a643fd974b02fd312a30b6 100644 (file)
@@ -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);
index 9d8e23b0b59480859aa1364f1280078df23b2456..109a9efb74f94c906fb6d64e9402fa4366e82e3f 100644 (file)
@@ -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;
index e4d6ea8c4d75548992a8f0195084f36fe678d0e9..4e206fcc90699d8df1652fb99be2b543a7e7672d 100644 (file)
@@ -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);