]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Don't allocate index until mailbox_open()
authorTimo Sirainen <tss@iki.fi>
Sun, 5 Dec 2010 23:44:38 +0000 (23:44 +0000)
committerTimo Sirainen <tss@iki.fi>
Sun, 5 Dec 2010 23:44:38 +0000 (23:44 +0000)
src/lib-storage/index/cydir/cydir-storage.c
src/lib-storage/index/dbox-common/dbox-storage.c
src/lib-storage/index/dbox-multi/mdbox-storage.c
src/lib-storage/index/dbox-single/sdbox-storage.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c

index e6ce68667ec8ef06df3362dcf4273c76ddd02865..674107e6760a2594c061321f5b5c1e93473d1368 100644 (file)
@@ -55,10 +55,6 @@ cydir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
 
        index_storage_mailbox_alloc(&mbox->box, name, flags,
                                    CYDIR_INDEX_PREFIX);
-       mail_index_set_fsync_mode(mbox->box.index,
-                                 storage->set->parsed_fsync_mode,
-                                 MAIL_INDEX_SYNC_TYPE_APPEND |
-                                 MAIL_INDEX_SYNC_TYPE_EXPUNGE);
 
        ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
        ibox->save_commit_pre = cydir_transaction_save_commit_pre;
@@ -89,7 +85,13 @@ static int cydir_mailbox_open(struct mailbox *box)
                                          box_path);
                return -1;
        }
-       return index_storage_mailbox_open(box, FALSE);
+       if (index_storage_mailbox_open(box, FALSE) < 0)
+               return -1;
+       mail_index_set_fsync_mode(box->index,
+                                 box->storage->set->parsed_fsync_mode,
+                                 MAIL_INDEX_SYNC_TYPE_APPEND |
+                                 MAIL_INDEX_SYNC_TYPE_EXPUNGE);
+       return 0;
 }
 
 static int
index 1eaebb8578f1477d29aad474d2068af8778da0e5..d097c7d8d5e2b301b1a75a47a5c1fd6c3e32c496 100644 (file)
@@ -115,9 +115,9 @@ int dbox_mailbox_open(struct mailbox *box)
 {
        const char *box_path = mailbox_get_path(box);
 
-       if (dbox_cleanup_if_exists(box->list, box_path)) {
-               return index_storage_mailbox_open(box, FALSE);
-       else if (errno == ENOENT) {
+       if (dbox_cleanup_if_exists(box->list, box_path))
+               ;
+       else if (errno == ENOENT) {
                mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
                        T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
                return -1;
@@ -130,6 +130,14 @@ int dbox_mailbox_open(struct mailbox *box)
                                          "stat(%s) failed: %m", box_path);
                return -1;
        }
+
+       if (index_storage_mailbox_open(box, FALSE) < 0)
+               return -1;
+       mail_index_set_fsync_mode(box->index,
+                                 box->storage->set->parsed_fsync_mode,
+                                 MAIL_INDEX_SYNC_TYPE_APPEND |
+                                 MAIL_INDEX_SYNC_TYPE_EXPUNGE);
+       return 0;
 }
 
 static int dir_is_empty(struct mail_storage *storage, const char *path)
index afec30e3fedc56d833f64bbb72548bc148bb4b8e..b69eac3665c23d2db7e3a04ee3819cf7881e8e32 100644 (file)
@@ -101,10 +101,6 @@ mdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        mbox->box.mail_vfuncs = &mdbox_mail_vfuncs;
 
        index_storage_mailbox_alloc(&mbox->box, name, flags, DBOX_INDEX_PREFIX);
-       mail_index_set_fsync_mode(mbox->box.index,
-                                 storage->set->parsed_fsync_mode,
-                                 MAIL_INDEX_SYNC_TYPE_APPEND |
-                                 MAIL_INDEX_SYNC_TYPE_EXPUNGE);
 
        ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
        ibox->save_commit_pre = mdbox_transaction_save_commit_pre;
@@ -114,6 +110,16 @@ mdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
                MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
 
        mbox->storage = (struct mdbox_storage *)storage;
+       return &mbox->box;
+}
+
+static int mdbox_mailbox_open(struct mailbox *box)
+{
+       struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
+
+       if (dbox_mailbox_open(box) < 0)
+               return -1;
+
        mbox->ext_id =
                mail_index_ext_register(mbox->box.index, "mdbox", 0,
                                        sizeof(struct mdbox_mail_index_record),
@@ -124,7 +130,7 @@ mdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        mbox->guid_ext_id =
                mail_index_ext_register(mbox->box.index, "guid",
                                        0, MAIL_GUID_128_SIZE, 1);
-       return &mbox->box;
+       return 0;
 }
 
 static void mdbox_mailbox_close(struct mailbox *box)
@@ -389,7 +395,7 @@ struct mailbox mdbox_mailbox = {
                index_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
-               dbox_mailbox_open,
+               mdbox_mailbox_open,
                mdbox_mailbox_close,
                index_storage_mailbox_free,
                dbox_mailbox_create,
index 7344e8c82d5ba1b91d4203d1f7d757ae407a43b5..b15816b43c36322773851a16ab47676d81719189 100644 (file)
@@ -48,10 +48,6 @@ sdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        mbox->box.mail_vfuncs = &sdbox_mail_vfuncs;
 
        index_storage_mailbox_alloc(&mbox->box, name, flags, DBOX_INDEX_PREFIX);
-       mail_index_set_fsync_mode(mbox->box.index,
-                                 storage->set->parsed_fsync_mode,
-                                 MAIL_INDEX_SYNC_TYPE_APPEND |
-                                 MAIL_INDEX_SYNC_TYPE_EXPUNGE);
 
        ibox = INDEX_STORAGE_CONTEXT(&mbox->box);
        ibox->save_commit_pre = sdbox_transaction_save_commit_pre;
@@ -61,9 +57,6 @@ sdbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
                MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY;
 
        mbox->storage = (struct sdbox_storage *)storage;
-       mbox->hdr_ext_id =
-               mail_index_ext_register(mbox->box.index, "dbox-hdr",
-                                       sizeof(struct sdbox_index_header), 0, 0);
        return &mbox->box;
 }
 
@@ -226,6 +219,9 @@ static int sdbox_mailbox_open(struct mailbox *box)
 
        if (dbox_mailbox_open(box) < 0)
                return -1;
+       mbox->hdr_ext_id =
+               mail_index_ext_register(box->index, "dbox-hdr",
+                                       sizeof(struct sdbox_index_header), 0, 0);
 
        /* get/generate mailbox guid */
        if (sdbox_read_header(mbox, &hdr, FALSE) < 0) {
index 7a0ed4c175ac093fc571b0b2449c6eba1757c7a0..0c9335eb79fb07611f5551764c47243b8a8b576e 100644 (file)
 struct index_storage_module index_storage_module =
        MODULE_CONTEXT_INIT(&mail_storage_module_register);
 
-static struct mail_index *
-index_storage_alloc(struct mailbox_list *list, const char *name,
-                   enum mailbox_flags flags, const char *prefix)
-{
-       const char *index_dir, *mailbox_path;
-
-       mailbox_path = mailbox_list_get_path(list, name,
-                                            MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       index_dir = (flags & MAILBOX_FLAG_NO_INDEX_FILES) != 0 ? "" :
-               mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_INDEX);
-       if (*index_dir == '\0')
-               index_dir = NULL;
-
-       return mail_index_alloc_cache_get(mailbox_path, index_dir, prefix);
-}
-
 static void set_cache_decisions(const char *set, const char *fields,
                                enum mail_cache_decision_type dec)
 {
@@ -150,6 +134,23 @@ void index_storage_lock_notify_reset(struct mailbox *box)
        ibox->last_notify_type = MAILBOX_LOCK_NOTIFY_NONE;
 }
 
+static struct mail_index *
+index_mailbox_alloc_index(struct mailbox *box)
+{
+       const char *index_dir, *mailbox_path;
+
+       mailbox_path = mailbox_list_get_path(box->list, box->name,
+                                            MAILBOX_LIST_PATH_TYPE_MAILBOX);
+       index_dir = (box->flags & MAILBOX_FLAG_NO_INDEX_FILES) != 0 ? "" :
+               mailbox_list_get_path(box->list, box->name,
+                                     MAILBOX_LIST_PATH_TYPE_INDEX);
+       if (*index_dir == '\0')
+               index_dir = NULL;
+
+       return mail_index_alloc_cache_get(mailbox_path, index_dir,
+                                         box->index_prefix);
+}
+
 int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory)
 {
        struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
@@ -175,6 +176,13 @@ int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory)
                return -1;
        }
 
+       box->index = index_mailbox_alloc_index(box);
+       mail_index_set_fsync_mode(box->index,
+                                 box->storage->set->parsed_fsync_mode, 0);
+       mail_index_set_lock_method(box->index,
+               box->storage->set->parsed_lock_method,
+               mail_storage_get_lock_timeout(box->storage, -1U));
+
        /* make sure mail_index_set_permissions() has been called */
        (void)mailbox_get_permissions(box);
 
@@ -232,7 +240,9 @@ void index_storage_mailbox_alloc(struct mailbox *box, const char *name,
        vname = t_str_new(128);
        mail_namespace_get_vname(box->list->ns, vname, name);
        box->vname = p_strdup(box->pool, str_c(vname));
+
        box->flags = flags;
+       box->index_prefix = p_strdup(box->pool, index_prefix);
 
        p_array_init(&box->search_results, box->pool, 16);
        array_create(&box->module_contexts,
@@ -244,16 +254,10 @@ void index_storage_mailbox_alloc(struct mailbox *box, const char *name,
        ibox->next_lock_notify = time(NULL) + LOCK_NOTIFY_INTERVAL;
        MODULE_CONTEXT_SET(box, index_storage_module, ibox);
 
-       box->index = index_storage_alloc(box->list, name, flags, index_prefix);
        box->inbox_user = strcmp(name, "INBOX") == 0 &&
                (box->list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0;
        box->inbox_any = strcmp(name, "INBOX") == 0 &&
                (box->list->ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0;
-       mail_index_set_fsync_mode(box->index,
-                                 box->storage->set->parsed_fsync_mode, 0);
-       mail_index_set_lock_method(box->index,
-               box->storage->set->parsed_lock_method,
-               mail_storage_get_lock_timeout(box->storage, -1U));
 }
 
 int index_storage_mailbox_enable(struct mailbox *box,
@@ -295,7 +299,8 @@ void index_storage_mailbox_close(struct mailbox *box)
 
 void index_storage_mailbox_free(struct mailbox *box)
 {
-       mail_index_alloc_cache_unref(&box->index);
+       if (box->index != NULL)
+               mail_index_alloc_cache_unref(&box->index);
 }
 
 void index_storage_mailbox_update_cache_fields(struct mailbox *box,
@@ -499,6 +504,8 @@ bool index_keyword_is_valid(struct mailbox *box, const char *keyword,
 {
        unsigned int i, idx;
 
+       i_assert(box->opened);
+
        /* if it already exists, skip validity checks */
        if (mail_index_keyword_lookup(box->index, keyword, &idx))
                return TRUE;
@@ -549,6 +556,8 @@ int index_keywords_create(struct mailbox *box, const char *const keywords[],
        const char *error;
        unsigned int i;
 
+       i_assert(box->opened);
+
        for (i = 0; keywords[i] != NULL; i++) {
                if (mailbox_keyword_is_valid(box, keywords[i], &error))
                        continue;
@@ -571,10 +580,12 @@ int index_keywords_create(struct mailbox *box, const char *const keywords[],
 }
 
 struct mail_keywords *
-index_keywords_create_from_indexes(struct mailbox *_box,
+index_keywords_create_from_indexes(struct mailbox *box,
                                   const ARRAY_TYPE(keyword_indexes) *idx)
 {
-       return mail_index_keywords_create_from_indexes(_box->index, idx);
+       i_assert(box->opened);
+
+       return mail_index_keywords_create_from_indexes(box->index, idx);
 }
 
 void index_keywords_ref(struct mail_keywords *keywords)
index 1fcab41c8b2853fe5c39ddb345909132b4074870..9d9d7f23e4d6e80d5088ab378554a17b7fadb544 100644 (file)
@@ -286,9 +286,6 @@ maildir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        ibox->save_rollback = maildir_transaction_save_rollback;
 
        mbox->storage = (struct maildir_storage *)storage;
-       mbox->maildir_ext_id =
-               mail_index_ext_register(mbox->box.index, "maildir",
-                                       sizeof(mbox->maildir_hdr), 0, 0);
        return &mbox->box;
 }
 
@@ -316,7 +313,13 @@ static int maildir_mailbox_open_existing(struct mailbox *box)
        if (access(t_strconcat(box_path, "/cur", NULL), W_OK) < 0 &&
            errno == EACCES)
                mbox->box.backend_readonly = TRUE;
-       return index_storage_mailbox_open(box, FALSE);
+       if (index_storage_mailbox_open(box, FALSE) < 0)
+               return -1;
+
+       mbox->maildir_ext_id =
+               mail_index_ext_register(mbox->box.index, "maildir",
+                                       sizeof(mbox->maildir_hdr), 0, 0);
+       return 0;
 }
 
 static int maildir_mailbox_open(struct mailbox *box)
index f683af98633b2ccae9f2b60733a205dd13ae3d2c..52a60504ebe75be66252c51905f43ac305218f29 100644 (file)
@@ -369,13 +369,6 @@ mbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        mbox->storage = (struct mbox_storage *)storage;
        mbox->mbox_fd = -1;
        mbox->mbox_lock_type = F_UNLCK;
-       mbox->mbox_ext_idx =
-               mail_index_ext_register(mbox->box.index, "mbox",
-                                       sizeof(mbox->mbox_hdr),
-                                       sizeof(uint64_t), sizeof(uint64_t));
-       mbox->md5hdr_ext_idx =
-               mail_index_ext_register(mbox->box.index, "header-md5",
-                                       0, 16, 1);
 
        if ((storage->flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0)
                mbox->mbox_save_md5 = TRUE;
@@ -387,6 +380,22 @@ static void mbox_lock_touch_timeout(struct mbox_mailbox *mbox)
        mbox_dotlock_touch(mbox);
 }
 
+static int
+mbox_mailbox_open_finish(struct mbox_mailbox *mbox, bool move_to_memory)
+{
+       if (index_storage_mailbox_open(&mbox->box, move_to_memory) < 0)
+               return -1;
+
+       mbox->mbox_ext_idx =
+               mail_index_ext_register(mbox->box.index, "mbox",
+                                       sizeof(mbox->mbox_hdr),
+                                       sizeof(uint64_t), sizeof(uint64_t));
+       mbox->md5hdr_ext_idx =
+               mail_index_ext_register(mbox->box.index, "header-md5",
+                                       0, 16, 1);
+       return 0;
+}
+
 static int mbox_mailbox_open_existing(struct mbox_mailbox *mbox)
 {
        struct mailbox *box = &mbox->box;
@@ -420,7 +429,7 @@ static int mbox_mailbox_open_existing(struct mbox_mailbox *mbox)
                                            mbox_lock_touch_timeout, mbox);
                }
        }
-       return index_storage_mailbox_open(box, move_to_memory);
+       return mbox_mailbox_open_finish(mbox, move_to_memory);
 }
 
 static int mbox_mailbox_open(struct mailbox *box)
@@ -434,7 +443,7 @@ static int mbox_mailbox_open(struct mailbox *box)
                mbox->mbox_file_stream = box->input;
                mbox->box.backend_readonly = TRUE;
                mbox->no_mbox_file = TRUE;
-               return index_storage_mailbox_open(box, FALSE);
+               return mbox_mailbox_open_finish(mbox, FALSE);
        }
 
        ret = stat(mailbox_get_path(box), &st);
index df5bf1d97f8461c3182d1ed7599d03cb9054b398..db4d515bc7d7c81471ffc9dd74e636b3b48d389f 100644 (file)
@@ -230,10 +230,14 @@ struct mailbox_permissions {
        gid_t file_create_gid;
        /* origin (e.g. path) where the file_create_gid was got from */
        const char *file_create_gid_origin;
+
+       bool mail_index_permissions_set;
 };
 
 struct mailbox {
        const char *name;
+       /* mailbox's virtual name (from mail_namespace_get_vname()) */
+       const char *vname;
        struct mail_storage *storage;
        struct mailbox_list *list;
 
@@ -253,9 +257,8 @@ struct mailbox {
        /* default vfuncs for new struct mails. */
        const struct mail_vfuncs *mail_vfuncs;
 
-       /* mailbox's virtual name (from mail_namespace_get_vname()) */
-       const char *vname;
        struct istream *input;
+       const char *index_prefix;
        enum mailbox_flags flags;
        unsigned int transaction_count;
        enum mailbox_feature enabled_features;
index bdc679d3a9ab0693f02a9237b485f479afa72996..aaa141e149dcca5081eae8b8d40653a6ef961a4a 100644 (file)
@@ -1470,32 +1470,42 @@ const char *mailbox_get_path(struct mailbox *box)
        return box->_path;
 }
 
-const struct mailbox_permissions *mailbox_get_permissions(struct mailbox *box)
+static void mailbox_get_permissions_if_not_set(struct mailbox *box)
 {
        const char *origin, *dir_origin;
        gid_t dir_gid;
 
        if (box->_perm.file_create_mode != 0)
-               return &box->_perm;
+               return;
 
        if (box->input != NULL) {
                box->_perm.file_create_mode = 0600;
                box->_perm.dir_create_mode = 0700;
                box->_perm.file_create_gid = (gid_t)-1;
                box->_perm.file_create_gid_origin = "defaults";
-               return &box->_perm;
+               return;
        }
 
        mailbox_list_get_permissions(box->list, box->name,
                                     &box->_perm.file_create_mode,
                                     &box->_perm.file_create_gid, &origin);
-       mail_index_set_permissions(box->index, box->_perm.file_create_mode,
-                                  box->_perm.file_create_gid, origin);
-
        box->_perm.file_create_gid_origin = p_strdup(box->pool, origin);
        mailbox_list_get_dir_permissions(box->list, box->name,
                                         &box->_perm.dir_create_mode,
                                         &dir_gid, &dir_origin);
+}
+
+const struct mailbox_permissions *mailbox_get_permissions(struct mailbox *box)
+{
+       mailbox_get_permissions_if_not_set(box);
+
+       if (!box->_perm.mail_index_permissions_set && box->index != NULL) {
+               box->_perm.mail_index_permissions_set = TRUE;
+               mail_index_set_permissions(box->index,
+                                          box->_perm.file_create_mode,
+                                          box->_perm.file_create_gid,
+                                          box->_perm.file_create_gid_origin);
+       }
        return &box->_perm;
 }