]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
LAYOUT=index: Fix updating STATUS changes in mailbox list index
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 12 Dec 2017 16:10:40 +0000 (18:10 +0200)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 9 Feb 2018 13:22:44 +0000 (15:22 +0200)
Mailbox list index backend code was overriding sync_init and sync_deinit
methods, which STATUS handling had already already overridden. They both
used the same super struct, so STATUS's sync_* were never called.

src/lib-storage/list/mailbox-list-index-backend.c
src/lib-storage/list/mailbox-list-index-status.c
src/lib-storage/list/mailbox-list-index-storage.h
src/lib-storage/list/mailbox-list-index.c
src/lib-storage/list/mailbox-list-index.h

index b1b93d7bc79b11f92a42745eeceb17c86e32c0ae..1fa57e92dd7cdfa134846189b64e29db50778c18 100644 (file)
@@ -573,11 +573,9 @@ static int index_list_mailbox_open(struct mailbox *box)
        return 0;
 }
 
-static struct mailbox_sync_context *
-index_list_mailbox_sync_init(struct mailbox *box,
-                            enum mailbox_sync_flags flags)
+void mailbox_list_index_backend_sync_init(struct mailbox *box,
+                                         enum mailbox_sync_flags flags)
 {
-       struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
        struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list);
 
        if ((flags & MAILBOX_SYNC_FLAG_FORCE_RESYNC) != 0 &&
@@ -589,18 +587,12 @@ index_list_mailbox_sync_init(struct mailbox *box,
                /* try to rebuild list index only once - even if it failed */
                ilist->force_resynced = TRUE;
        }
-       return ibox->module_ctx.super.sync_init(box, flags);
 }
 
-static int
-index_list_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
-                              struct mailbox_sync_status *status_r)
+int mailbox_list_index_backend_sync_deinit(struct mailbox *box)
 {
-       struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(ctx->box);
-       struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(ctx->box->list);
+       struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list);
 
-       if (ibox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
-               return -1;
        if (ilist->force_resync_failed) {
                /* fail this only once */
                ilist->force_resync_failed = FALSE;
@@ -882,15 +874,18 @@ struct mailbox_list index_mailbox_list = {
        }
 };
 
-void mailbox_list_index_backend_init_mailbox(struct mailbox *box,
+bool mailbox_list_index_backend_init_mailbox(struct mailbox *box,
                                             struct mailbox_vfuncs *v)
 {
        if (strcmp(box->list->name, MAILBOX_LIST_NAME_INDEX) != 0)
-               return;
+               return TRUE;
+
+       /* NOTE: this is using the same v as
+          mailbox_list_index_status_init_mailbox(), so don't have them
+          accidentally override each others. */
        v->create_box = index_list_mailbox_create;
        v->update_box = index_list_mailbox_update;
        v->exists = index_list_mailbox_exists;
        v->open = index_list_mailbox_open;
-       v->sync_init = index_list_mailbox_sync_init;
-       v->sync_deinit = index_list_mailbox_sync_deinit;
+       return FALSE;
 }
index de2b8b30a97f520c46031af12ddf06ca87d95cf9..cf83772e78cef0ed6158e193fef789acd031438b 100644 (file)
@@ -747,8 +747,7 @@ void mailbox_list_index_update_mailbox_index(struct mailbox *box,
        mail_index_view_close(&list_view);
 }
 
-static struct mailbox_sync_context *
-index_list_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
+void mailbox_list_index_status_sync_init(struct mailbox *box)
 {
        struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
        const struct mail_index_header *hdr;
@@ -756,29 +755,21 @@ index_list_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
        hdr = mail_index_get_header(box->view);
        ibox->pre_sync_log_file_seq = hdr->log_file_seq;
        ibox->pre_sync_log_file_head_offset = hdr->log_file_head_offset;
-
-       return ibox->module_ctx.super.sync_init(box, flags);
 }
 
-static int index_list_sync_deinit(struct mailbox_sync_context *ctx,
-                                 struct mailbox_sync_status *status_r)
+void mailbox_list_index_status_sync_deinit(struct mailbox *box)
 {
-       struct mailbox *box = ctx->box;
        struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
        struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(box->list);
        const struct mail_index_header *hdr;
 
-       if (ibox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
-               return -1;
-       ctx = NULL;
-
        hdr = mail_index_get_header(box->view);
        if (!ilist->opened &&
            ibox->pre_sync_log_file_head_offset == hdr->log_file_head_offset &&
            ibox->pre_sync_log_file_seq == hdr->log_file_seq) {
                /* List index isn't open and sync changed nothing.
                   Don't bother opening the list index. */
-               return 0;
+               return;
        }
 
        /* it probably doesn't matter much here if we push/pop the error,
@@ -786,7 +777,6 @@ static int index_list_sync_deinit(struct mailbox_sync_context *ctx,
        mail_storage_last_error_push(mailbox_get_storage(box));
        (void)index_list_update_mailbox(box);
        mail_storage_last_error_pop(mailbox_get_storage(box));
-       return 0;
 }
 
 static int
@@ -855,8 +845,6 @@ void mailbox_list_index_status_init_mailbox(struct mailbox_vfuncs *v)
        v->exists = index_list_exists;
        v->get_status = index_list_get_status;
        v->get_metadata = index_list_get_metadata;
-       v->sync_init = index_list_sync_init;
-       v->sync_deinit = index_list_sync_deinit;
        v->transaction_commit = index_list_transaction_commit;
 }
 
index 99943e74033bbc9677e8e0d39d5b45614dcbaa3b..dd7d19ca11bd2c1a913b5f03276ba81f7dd7c705 100644 (file)
@@ -11,6 +11,8 @@ struct index_list_mailbox {
 
        uint32_t pre_sync_log_file_seq;
        uoff_t pre_sync_log_file_head_offset;
+
+       bool have_backend:1;
 };
 
 extern MODULE_CONTEXT_DEFINE(index_list_storage_module,
index ba2b108cfd373c210be453941a406f7f9ba0650a..49c0ac0c7b5254d34421b35cbe69e4e124926e8b 100644 (file)
@@ -936,6 +936,36 @@ mailbox_list_index_namespaces_added(struct mail_namespace *namespaces)
                mailbox_list_index_init_finish(ns->list);
 }
 
+static struct mailbox_sync_context *
+mailbox_list_index_sync_init(struct mailbox *box,
+                            enum mailbox_sync_flags flags)
+{
+       struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
+
+       mailbox_list_index_status_sync_init(box);
+       if (ibox->have_backend)
+               mailbox_list_index_backend_sync_init(box, flags);
+       return ibox->module_ctx.super.sync_init(box, flags);
+}
+
+static int
+mailbox_list_index_sync_deinit(struct mailbox_sync_context *ctx,
+                              struct mailbox_sync_status *status_r)
+{
+       struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(ctx->box);
+       struct mailbox *box = ctx->box;
+
+       if (ibox->module_ctx.super.sync_deinit(ctx, status_r) < 0)
+               return -1;
+       ctx = NULL;
+
+       mailbox_list_index_status_sync_deinit(box);
+       if (ibox->have_backend)
+               return mailbox_list_index_backend_sync_deinit(box);
+       else
+               return 0;
+}
+
 static void mailbox_list_index_mailbox_allocated(struct mailbox *box)
 {
        struct mailbox_vfuncs *v = box->vlast;
@@ -955,8 +985,14 @@ static void mailbox_list_index_mailbox_allocated(struct mailbox *box)
        v->create_box = mailbox_list_index_create_mailbox;
        v->update_box = mailbox_list_index_update_mailbox;
 
+       /* These are used by both status and backend code, but they can't both
+          be overriding the same function pointer since they share the
+          super pointer. */
+       v->sync_init = mailbox_list_index_sync_init;
+       v->sync_deinit = mailbox_list_index_sync_deinit;
+
        mailbox_list_index_status_init_mailbox(v);
-       mailbox_list_index_backend_init_mailbox(box, v);
+       ibox->have_backend = mailbox_list_index_backend_init_mailbox(box, v);
 }
 
 static struct mail_storage_hooks mailbox_list_index_hooks = {
index e4b042ab215c3069cdccc99f5e52a2586099efc0..8a1ecdf2ace888b895cd7ba63d13f5e4890f02b3 100644 (file)
@@ -204,8 +204,15 @@ void mailbox_list_index_notify_wait(struct mailbox_list_notify *notify,
 void mailbox_list_index_notify_flush(struct mailbox_list_notify *notify);
 
 void mailbox_list_index_status_init_mailbox(struct mailbox_vfuncs *v);
-void mailbox_list_index_backend_init_mailbox(struct mailbox *box,
+bool mailbox_list_index_backend_init_mailbox(struct mailbox *box,
                                             struct mailbox_vfuncs *v);
 void mailbox_list_index_status_init_finish(struct mailbox_list *list);
 
+void mailbox_list_index_status_sync_init(struct mailbox *box);
+void mailbox_list_index_status_sync_deinit(struct mailbox *box);
+
+void mailbox_list_index_backend_sync_init(struct mailbox *box,
+                                         enum mailbox_sync_flags flags);
+int mailbox_list_index_backend_sync_deinit(struct mailbox *box);
+
 #endif