]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Moved mail_index lookup cache from lib-storage to lib-index.
authorTimo Sirainen <tss@iki.fi>
Sun, 7 Feb 2010 02:50:40 +0000 (04:50 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 7 Feb 2010 02:50:40 +0000 (04:50 +0200)
Removed some code duplication as a result.

--HG--
branch : HEAD

16 files changed:
src/lib-index/Makefile.am
src/lib-index/mail-index-alloc-cache.c [new file with mode: 0644]
src/lib-index/mail-index-alloc-cache.h [new file with mode: 0644]
src/lib-index/mail-index.c
src/lib-storage/index/cydir/cydir-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/index-storage.h
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/index/raw/raw-storage.c
src/lib-storage/index/shared/shared-storage.c
src/lib-storage/mail-storage.c
src/lib-storage/mailbox-list.c
src/plugins/virtual/virtual-storage.c

index bc2fd4b95a19ebb49b0def2e5671da5db966f51c..4ea738d975714c46badcb4681183d548d25e4a47 100644 (file)
@@ -14,6 +14,7 @@ libindex_la_SOURCES = \
        mail-cache-transaction.c \
        mail-cache-sync-update.c \
         mail-index.c \
+        mail-index-alloc-cache.c \
         mail-index-dummy-view.c \
         mail-index-fsck.c \
         mail-index-lock.c \
@@ -48,6 +49,7 @@ headers = \
        mail-cache.h \
        mail-cache-private.h \
        mail-index.h \
+        mail-index-alloc-cache.h \
         mail-index-modseq.h \
        mail-index-private.h \
         mail-index-strmap.h \
diff --git a/src/lib-index/mail-index-alloc-cache.c b/src/lib-index/mail-index-alloc-cache.c
new file mode 100644 (file)
index 0000000..1f52b1a
--- /dev/null
@@ -0,0 +1,203 @@
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "module-context.h"
+#include "eacces-error.h"
+#include "mail-index-private.h"
+#include "mail-index-alloc-cache.h"
+
+#define MAIL_INDEX_ALLOC_CACHE_CONTEXT(obj) \
+       MODULE_CONTEXT(obj, mail_index_alloc_cache_index_module)
+
+/* How many seconds to keep index opened for reuse after it's been closed */
+#define INDEX_CACHE_TIMEOUT 10
+/* How many closed indexes to keep */
+#define INDEX_CACHE_MAX 3
+
+struct mail_index_alloc_cache_list {
+       union mail_index_module_context module_ctx;
+       struct mail_index_alloc_cache_list *next;
+
+       struct mail_index *index;
+       char *mailbox_path;
+       int refcount;
+
+       dev_t index_dir_dev;
+       ino_t index_dir_ino;
+
+       time_t destroy_time;
+};
+
+static MODULE_CONTEXT_DEFINE_INIT(mail_index_alloc_cache_index_module,
+                                 &mail_index_module_register);
+static struct mail_index_alloc_cache_list *indexes = NULL;
+static struct timeout *to_index = NULL;
+
+static struct mail_index_alloc_cache_list *
+mail_index_alloc_cache_add(struct mail_index *index,
+                          const char *mailbox_path, struct stat *st)
+{
+       struct mail_index_alloc_cache_list *list;
+
+       list = i_new(struct mail_index_alloc_cache_list, 1);
+       list->refcount = 1;
+       list->index = index;
+
+       list->mailbox_path = i_strdup(mailbox_path);
+       list->index_dir_dev = st->st_dev;
+       list->index_dir_ino = st->st_ino;
+
+       list->next = indexes;
+       indexes = list;
+
+       MODULE_CONTEXT_SET(index, mail_index_alloc_cache_index_module, list);
+       return list;
+}
+
+static void
+mail_index_alloc_cache_list_free(struct mail_index_alloc_cache_list *list)
+{
+       mail_index_free(&list->index);
+       i_free(list->mailbox_path);
+       i_free(list);
+}
+
+struct mail_index *
+mail_index_alloc_cache_get(const char *mailbox_path,
+                          const char *index_dir, const char *prefix)
+{
+       struct mail_index_alloc_cache_list **indexp, *rec, *match;
+       struct stat st, st2;
+       unsigned int destroy_count;
+
+       /* compare index_dir inodes so we don't break even with symlinks.
+          if index_dir doesn't exist yet or if using in-memory indexes, just
+          compare mailbox paths */
+       memset(&st, 0, sizeof(st));
+       if (index_dir == NULL) {
+               /* in-memory indexes */
+       } else if (stat(index_dir, &st) < 0) {
+               if (errno == ENOENT) {
+                       /* it'll be created later */
+               } else if (errno == EACCES) {
+                       i_error("%s", eacces_error_get("stat", index_dir));
+               } else {
+                       i_error("stat(%s) failed: %m", index_dir);
+               }
+       }
+
+       destroy_count = 0; match = NULL;
+       for (indexp = &indexes; *indexp != NULL;) {
+               rec = *indexp;
+
+               if (match != NULL) {
+                       /* already found the index. we're just going through
+                          the rest of them to drop 0 refcounts */
+               } else if (index_dir != NULL && rec->index_dir_ino != 0) {
+                       if (st.st_ino == rec->index_dir_ino &&
+                           CMP_DEV_T(st.st_dev, rec->index_dir_dev)) {
+                               /* make sure the directory still exists.
+                                  it might have been renamed and we're trying
+                                  to access it via its new path now. */
+                               if (stat(rec->index->dir, &st2) < 0 ||
+                                   st2.st_ino != st.st_ino ||
+                                   !CMP_DEV_T(st2.st_dev, st.st_dev))
+                                       rec->destroy_time = 0;
+                               else
+                                       match = rec;
+                       }
+               } else {
+                       if (strcmp(mailbox_path, rec->mailbox_path) == 0)
+                               match = rec;
+               }
+
+               if (rec->refcount == 0 && rec != match) {
+                       if (rec->destroy_time <= ioloop_time ||
+                           destroy_count >= INDEX_CACHE_MAX) {
+                               *indexp = rec->next;
+                               mail_index_alloc_cache_list_free(rec);
+                               continue;
+                       } else {
+                               destroy_count++;
+                       }
+               }
+
+                indexp = &(*indexp)->next;
+       }
+
+       if (match == NULL) {
+               struct mail_index *index = mail_index_alloc(index_dir, prefix);
+               match = mail_index_alloc_cache_add(index, mailbox_path, &st);
+       } else {
+               match->refcount++;
+       }
+       i_assert(match->index != NULL);
+       return match->index;
+}
+
+static void destroy_unrefed(bool all)
+{
+       struct mail_index_alloc_cache_list **list, *rec;
+
+       for (list = &indexes; *list != NULL;) {
+               rec = *list;
+
+               if (rec->refcount == 0 &&
+                   (all || rec->destroy_time <= ioloop_time)) {
+                       *list = rec->next;
+                       mail_index_alloc_cache_list_free(rec);
+               } else {
+                       list = &(*list)->next;
+               }
+       }
+
+       if (indexes == NULL && to_index != NULL)
+               timeout_remove(&to_index);
+}
+
+static void index_removal_timeout(void *context ATTR_UNUSED)
+{
+       destroy_unrefed(FALSE);
+}
+
+void mail_index_alloc_cache_unref(struct mail_index *index)
+{
+       struct mail_index_alloc_cache_list *list;
+
+       for (list = indexes; list != NULL; list = list->next) {
+               if (list->index == index)
+                       break;
+       }
+
+       i_assert(list != NULL);
+       i_assert(list->refcount > 0);
+
+       list->refcount--;
+       list->destroy_time = ioloop_time + INDEX_CACHE_TIMEOUT;
+       if (to_index == NULL) {
+               to_index = timeout_add(INDEX_CACHE_TIMEOUT*1000/2,
+                                      index_removal_timeout, NULL);
+       }
+}
+
+void mail_index_alloc_cache_destroy_unrefed(void)
+{
+       destroy_unrefed(TRUE);
+}
+
+void mail_index_alloc_cache_index_opened(struct mail_index *index)
+{
+       struct mail_index_alloc_cache_list *list =
+               MAIL_INDEX_ALLOC_CACHE_CONTEXT(index);
+       struct stat st;
+
+       if (list != NULL && list->index_dir_ino == 0 &&
+           !MAIL_INDEX_IS_IN_MEMORY(index)) {
+               /* newly created index directory. update its stat. */
+               if (stat(index->dir, &st) == 0) {
+                       list->index_dir_ino = st.st_ino;
+                       list->index_dir_dev = st.st_dev;
+               }
+       }
+}
diff --git a/src/lib-index/mail-index-alloc-cache.h b/src/lib-index/mail-index-alloc-cache.h
new file mode 100644 (file)
index 0000000..ea01d51
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef MAIL_INDEX_ALLOC_CACHE_H
+#define MAIL_INDEX_ALLOC_CACHE_H
+
+/* If using in-memory indexes, give index_dir=NULL. */
+struct mail_index *
+mail_index_alloc_cache_get(const char *mailbox_path,
+                          const char *index_dir, const char *prefix);
+void mail_index_alloc_cache_unref(struct mail_index *index);
+
+void mail_index_alloc_cache_destroy_unrefed(void);
+
+/* internal: */
+void mail_index_alloc_cache_index_opened(struct mail_index *index);
+
+#endif
index f57b65b9c3b7751aee17cbe3fd828ece7216a429..2d91da02b54af41ea6a7d6d01ec4c1d2b95620e2 100644 (file)
@@ -11,6 +11,7 @@
 #include "nfs-workarounds.h"
 #include "read-full.h"
 #include "write-full.h"
+#include "mail-index-alloc-cache.h"
 #include "mail-index-private.h"
 #include "mail-index-view-private.h"
 #include "mail-index-sync-private.h"
@@ -527,6 +528,7 @@ int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
 
        i_assert(index->map != NULL);
        index->opened = TRUE;
+       mail_index_alloc_cache_index_opened(index);
        return 1;
 }
 
index 393aa04c0f17566159b8c75e8e313faec6c345bd..5d63d427c6816fba525a67c0445777b19a38a246 100644 (file)
@@ -202,12 +202,6 @@ cydir_list_delete_mailbox(struct mailbox_list *list, const char *name)
        struct stat st;
        const char *src;
 
-       /* Make sure the indexes are closed before trying to delete the
-          directory that contains them. It can still fail with some NFS
-          implementations if indexes are opened by another session, but
-          that can't really be helped. */
-       index_storage_destroy_unrefed();
-
        /* delete the index and control directories */
        if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
                return -1;
@@ -309,7 +303,7 @@ struct mail_storage cydir_storage = {
                NULL,
                cydir_storage_alloc,
                NULL,
-               index_storage_destroy,
+               NULL,
                cydir_storage_add_list,
                cydir_storage_get_list_settings,
                NULL,
index 32c1c0d85f0bcee916b3a7495a86063887920cee..fba15c34841be4adde79fc28a4d05d63929be948 100644 (file)
@@ -97,7 +97,6 @@ static void mdbox_storage_destroy(struct mail_storage *_storage)
        mdbox_files_free(storage);
        dbox_map_deinit(&storage->map);
        array_free(&storage->open_files);
-       index_storage_destroy(_storage);
 }
 
 struct mailbox *
@@ -358,12 +357,6 @@ mdbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
        const char *trash_dest;
        int ret;
 
-       /* Make sure the indexes are closed before trying to delete the
-          directory that contains them. It can still fail with some NFS
-          implementations if indexes are opened by another session, but
-          that can't really be helped. */
-       index_storage_destroy_unrefed();
-
        /* delete the index and control directories */
        if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
                return -1;
index ab0f5727a877d0f6013adef48e3c3edb321fc164..17742c93e6fb46de775246e2fc07bc5ca5a602b3 100644 (file)
@@ -237,12 +237,6 @@ sdbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
        const char *trash_dest;
        int ret;
 
-       /* Make sure the indexes are closed before trying to delete the
-          directory that contains them. It can still fail with some NFS
-          implementations if indexes are opened by another session, but
-          that can't really be helped. */
-       index_storage_destroy_unrefed();
-
        /* delete the index and control directories */
        if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
                return -1;
@@ -291,7 +285,7 @@ struct mail_storage dbox_storage = {
                 NULL,
                sdbox_storage_alloc,
                NULL,
-               index_storage_destroy,
+               NULL,
                sdbox_storage_add_list,
                dbox_storage_get_list_settings,
                NULL,
index 84eef027f93fdac52d42eccba1b627d0cc839310..100b20c832f63b6aff27c07a225a27b2e88c4912 100644 (file)
@@ -7,6 +7,7 @@
 #include "str.h"
 #include "imap-parser.h"
 #include "mkdir-parents.h"
+#include "mail-index-alloc-cache.h"
 #include "mail-index-private.h"
 #include "mail-index-modseq.h"
 #include "mailbox-list-private.h"
 #include <unistd.h>
 #include <sys/stat.h>
 
-/* How many seconds to keep index opened for reuse after it's been closed */
-#define INDEX_CACHE_TIMEOUT 10
-/* How many closed indexes to keep */
-#define INDEX_CACHE_MAX 3
-
 #define LOCK_NOTIFY_INTERVAL 30
 
-struct index_list {
-       union mail_index_module_context module_ctx;
-       struct index_list *next;
-
-       struct mail_index *index;
-       char *mailbox_path;
-       int refcount;
-
-       dev_t index_dir_dev;
-       ino_t index_dir_ino;
-
-       time_t destroy_time;
-};
-
-static struct index_list *indexes = NULL;
-static struct timeout *to_index = NULL;
-
-static struct index_list *
-index_storage_add(struct mail_index *index,
-                 const char *mailbox_path, struct stat *st)
-{
-       struct index_list *list;
-
-       list = i_new(struct index_list, 1);
-       list->refcount = 1;
-       list->index = index;
-
-       list->mailbox_path = i_strdup(mailbox_path);
-       list->index_dir_dev = st->st_dev;
-       list->index_dir_ino = st->st_ino;
-
-       list->next = indexes;
-       indexes = list;
-
-       MODULE_CONTEXT_SET(index, mail_storage_mail_index_module, list);
-       return list;
-}
-
-static void index_list_free(struct index_list *list)
-{
-       mail_index_free(&list->index);
-       i_free(list->mailbox_path);
-       i_free(list);
-}
-
 int index_list_create_missing_index_dir(struct mailbox_list *list,
                                        const char *name)
 {
@@ -113,159 +64,20 @@ int index_list_create_missing_index_dir(struct mailbox_list *list,
        return 0;
 }
 
-static const char *
-get_index_dir(struct mailbox_list *list, const char *name,
-             enum mailbox_flags flags, struct stat *st_r)
-{
-       const char *index_dir;
-
-       index_dir = (flags & MAILBOX_FLAG_NO_INDEX_FILES) != 0 ? "" :
-               mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_INDEX);
-       if (*index_dir == '\0') {
-               /* disabled */
-               return NULL;
-       }
-
-       if (stat(index_dir, st_r) < 0) {
-               if (errno == ENOENT) {
-                       /* it'll be created later */
-                       memset(st_r, 0, sizeof(*st_r));
-                       return index_dir;
-               }
-               if (errno == EACCES) {
-                       mailbox_list_set_critical(list, "%s",
-                               mail_error_eacces_msg("stat", index_dir));
-                       return NULL;
-               }
-
-               mailbox_list_set_critical(list, "stat(%s) failed: %m",
-                                         index_dir);
-               return NULL;
-       }
-       return index_dir;
-}
-
 static struct mail_index *
 index_storage_alloc(struct mailbox_list *list, const char *name,
                    enum mailbox_flags flags, const char *prefix)
 {
-       struct index_list **indexp, *rec, *match;
-       struct stat st, st2;
        const char *index_dir, *mailbox_path;
-       int destroy_count;
 
        mailbox_path = mailbox_list_get_path(list, name,
                                             MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       index_dir = get_index_dir(list, name, flags, &st);
-
-       if (index_dir == NULL)
-               memset(&st, 0, sizeof(st));
-
-       /* compare index_dir inodes so we don't break even with symlinks.
-          if index_dir doesn't exist yet or if using in-memory indexes, just
-          compare mailbox paths */
-       destroy_count = 0; match = NULL;
-       for (indexp = &indexes; *indexp != NULL;) {
-               rec = *indexp;
-
-               if (match != NULL) {
-                       /* already found the index. we're just going through
-                          the rest of them to drop 0 refcounts */
-               } else if (index_dir != NULL && rec->index_dir_ino != 0) {
-                       if (st.st_ino == rec->index_dir_ino &&
-                           CMP_DEV_T(st.st_dev, rec->index_dir_dev)) {
-                               /* make sure the directory still exists.
-                                  it might have been renamed and we're trying
-                                  to access it via its new path now. */
-                               if (stat(rec->index->dir, &st2) < 0 ||
-                                   st2.st_ino != st.st_ino ||
-                                   !CMP_DEV_T(st2.st_dev, st.st_dev))
-                                       rec->destroy_time = 0;
-                               else
-                                       match = rec;
-                       }
-               } else {
-                       if (strcmp(mailbox_path, rec->mailbox_path) == 0)
-                               match = rec;
-               }
-
-               if (rec->refcount == 0 && rec != match) {
-                       if (rec->destroy_time <= ioloop_time ||
-                           destroy_count >= INDEX_CACHE_MAX) {
-                               *indexp = rec->next;
-                               index_list_free(rec);
-                               continue;
-                       } else {
-                               destroy_count++;
-                       }
-               }
-
-                indexp = &(*indexp)->next;
-       }
-
-       if (match == NULL) {
-               match = index_storage_add(mail_index_alloc(index_dir, prefix),
-                                         mailbox_path, &st);
-       } else {
-               match->refcount++;
-       }
-       i_assert(match->index != NULL);
-       return match->index;
-}
-
-static void destroy_unrefed(bool all)
-{
-       struct index_list **list, *rec;
-
-       for (list = &indexes; *list != NULL;) {
-               rec = *list;
-
-               if (rec->refcount == 0 &&
-                   (all || rec->destroy_time <= ioloop_time)) {
-                       *list = rec->next;
-                       index_list_free(rec);
-               } else {
-                       list = &(*list)->next;
-               }
-       }
-
-       if (indexes == NULL && to_index != NULL)
-               timeout_remove(&to_index);
-}
-
-static void index_removal_timeout(void *context ATTR_UNUSED)
-{
-       destroy_unrefed(FALSE);
-}
-
-void index_storage_unref(struct mail_index *index)
-{
-       struct index_list *list;
-
-       for (list = indexes; list != NULL; list = list->next) {
-               if (list->index == index)
-                       break;
-       }
-
-       i_assert(list != NULL);
-       i_assert(list->refcount > 0);
-
-       list->refcount--;
-       list->destroy_time = ioloop_time + INDEX_CACHE_TIMEOUT;
-       if (to_index == NULL) {
-               to_index = timeout_add(INDEX_CACHE_TIMEOUT*1000/2,
-                                      index_removal_timeout, NULL);
-       }
-}
-
-void index_storage_destroy_unrefed(void)
-{
-       destroy_unrefed(TRUE);
-}
+       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;
 
-void index_storage_destroy(struct mail_storage *storage ATTR_UNUSED)
-{
-       index_storage_destroy_unrefed();
+       return mail_index_alloc_cache_get(mailbox_path, index_dir, prefix);
 }
 
 static void set_cache_decisions(const char *set, const char *fields,
@@ -374,12 +186,9 @@ void index_storage_lock_notify_reset(struct index_mailbox *ibox)
 int index_storage_mailbox_open(struct mailbox *box)
 {
        struct index_mailbox *ibox = (struct index_mailbox *)box;
-       struct index_list *list = MAIL_STORAGE_CONTEXT(ibox->index);
        enum file_lock_method lock_method =
                box->storage->set->parsed_lock_method;
        enum mail_index_open_flags index_flags;
-       const char *index_dir;
-       struct stat st;
        int ret;
 
        i_assert(!box->opened);
@@ -401,16 +210,6 @@ int index_storage_mailbox_open(struct mailbox *box)
                return -1;
        }
 
-       index_dir = mailbox_list_get_path(box->list, box->name,
-                                         MAILBOX_LIST_PATH_TYPE_INDEX);
-       if (list->index_dir_ino == 0 && *index_dir != '\0') {
-               /* newly created index directory. update its stat. */
-               if (stat(index_dir, &st) == 0) {
-                       list->index_dir_ino = st.st_ino;
-                       list->index_dir_dev = st.st_dev;
-               }
-       }
-
        ret = mail_index_open(ibox->index, index_flags, lock_method);
        if (ret <= 0 || ibox->move_to_memory) {
                if ((index_flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0) {
@@ -526,7 +325,7 @@ void index_storage_mailbox_close(struct mailbox *box)
        if (ibox->box.input != NULL)
                i_stream_unref(&ibox->box.input);
        if (ibox->index != NULL)
-               index_storage_unref(ibox->index);
+               mail_index_alloc_cache_unref(ibox->index);
        if (array_is_created(&ibox->recent_flags))
                array_free(&ibox->recent_flags);
        i_free(ibox->cache_fields);
index 75232a4b0b911169b727b44d0b6b6640e1cb3013..c8c63dd9ce11bdf29c5683f3763cc99f64224b00 100644 (file)
@@ -73,10 +73,6 @@ void index_storage_lock_notify(struct index_mailbox *ibox,
                               unsigned int secs_left);
 void index_storage_lock_notify_reset(struct index_mailbox *ibox);
 
-void index_storage_unref(struct mail_index *index);
-void index_storage_destroy_unrefed(void);
-void index_storage_destroy(struct mail_storage *storage ATTR_UNUSED);
-
 void index_storage_mailbox_alloc(struct index_mailbox *ibox, const char *name,
                                 struct istream *input,
                                 enum mailbox_flags flags,
index 4ff20e9628db10e4981761a778253edf19024623..e09b20c30a73beb6d46899f799cdc0937465ebb4 100644 (file)
@@ -705,12 +705,6 @@ maildir_list_delete_mailbox(struct mailbox_list *list, const char *name)
 
        mailbox_get_guid(list, name, mailbox_guid);
 
-       /* Make sure the indexes are closed before trying to delete the
-          directory that contains them. It can still fail with some NFS
-          implementations if indexes are opened by another session, but
-          that can't really be helped. */
-       index_storage_destroy_unrefed();
-
        /* delete the index and control directories */
        if (mlist->super.delete_mailbox(list, name) < 0)
                return -1;
@@ -1034,7 +1028,7 @@ struct mail_storage maildir_storage = {
                 maildir_get_setting_parser_info,
                maildir_storage_alloc,
                maildir_storage_create,
-               index_storage_destroy,
+               NULL,
                maildir_storage_add_list,
                maildir_storage_get_list_settings,
                maildir_storage_autodetect,
index b513b7ec8e4a64744ff4d956125ec0b2d79366a1..387b5b412a509968f5a57d05b62400abbbdfbf55 100644 (file)
@@ -757,7 +757,6 @@ static int mbox_list_delete_mailbox(struct mailbox_list *list,
        }
 
        /* delete index / control files first */
-       index_storage_destroy_unrefed();
        if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
                return -1;
 
@@ -858,7 +857,7 @@ struct mail_storage mbox_storage = {
                 mbox_get_setting_parser_info,
                mbox_storage_alloc,
                mbox_storage_create,
-               index_storage_destroy,
+               NULL,
                mbox_storage_add_list,
                mbox_storage_get_list_settings,
                mbox_storage_autodetect,
index f412d9e367ef9463c7ce47ba62ba9310c47d6c7d..a145acc06495fc80f8d7cea4ac4059709c5b61f2 100644 (file)
@@ -178,7 +178,7 @@ struct mail_storage raw_storage = {
                NULL,
                raw_storage_alloc,
                NULL,
-               index_storage_destroy,
+               NULL,
                raw_storage_add_list,
                raw_storage_get_list_settings,
                NULL,
index 572ae0def72a7740fc861c796a133e17bb9fd7c4..d70d8ca0929217f84927754878aa63bf7428aee6 100644 (file)
@@ -296,7 +296,7 @@ struct mail_storage shared_storage = {
                NULL,
                shared_storage_alloc,
                shared_storage_create,
-               index_storage_destroy,
+               NULL,
                NULL,
                shared_storage_get_list_settings,
                NULL,
index 283bd7b1eb4b7dfacbca838f5698b3cdb6a73489..6986b10e84dc4278f7d4d16c305721283a0092c6 100644 (file)
@@ -8,6 +8,7 @@
 #include "mkdir-parents.h"
 #include "var-expand.h"
 #include "mail-index-private.h"
+#include "mail-index-alloc-cache.h"
 #include "mailbox-list-private.h"
 #include "mail-storage-private.h"
 #include "mail-storage-settings.h"
@@ -328,6 +329,8 @@ void mail_storage_unref(struct mail_storage **_storage)
                storage->v.destroy(storage);
        i_free(storage->error_string);
        pool_unref(&storage->pool);
+
+       mail_index_alloc_cache_destroy_unrefed();
 }
 
 void mail_storage_clear_error(struct mail_storage *storage)
index 8538f9e2b9084d9e5fd23018a3462ecdbc60f771..a978c2ae53a17c3627051322d0a2dcf44957ff61 100644 (file)
@@ -15,6 +15,7 @@
 #include "unlink-directory.h"
 #include "imap-match.h"
 #include "imap-utf7.h"
+#include "mail-index-alloc-cache.h"
 #include "mailbox-log.h"
 #include "mailbox-tree.h"
 #include "mail-storage-private.h"
@@ -744,6 +745,13 @@ int mailbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
                                       "INBOX can't be deleted.");
                return -1;
        }
+
+       /* Make sure the indexes are closed before trying to delete the
+          directory that contains them. It can still fail with some NFS
+          implementations if indexes are opened by another session, but
+          that can't really be helped. */
+       mail_index_alloc_cache_destroy_unrefed();
+
        return list->v.delete_mailbox(list, name);
 }
 
index f0860a749981ca34db0a3effd827d64d87b23d6e..2d54ba2fe2d71c7b0c8fb6ce9f5767e7bb05c526 100644 (file)
@@ -382,12 +382,6 @@ virtual_list_delete_mailbox(struct mailbox_list *list, const char *name)
        struct stat st;
        const char *src;
 
-       /* Make sure the indexes are closed before trying to delete the
-          directory that contains them. It can still fail with some NFS
-          implementations if indexes are opened by another session, but
-          that can't really be helped. */
-       index_storage_destroy_unrefed();
-
        /* delete the index and control directories */
        if (mlist->module_ctx.super.delete_mailbox(list, name) < 0)
                return -1;
@@ -569,7 +563,7 @@ struct mail_storage virtual_storage = {
                NULL,
                virtual_storage_alloc,
                NULL,
-               index_storage_destroy,
+               NULL,
                virtual_storage_add_list,
                virtual_storage_get_list_settings,
                NULL,