changeset 22814:2d409988e1c8

LAYOUT=index: Fix updating STATUS changes in mailbox list index 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.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 12 Dec 2017 18:10:40 +0200
parents 4fe2e5822180
children 880bd0712ef1
files 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
diffstat 5 files changed, 61 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-index-backend.c	Tue Feb 06 12:37:34 2018 +0200
+++ b/src/lib-storage/list/mailbox-list-index-backend.c	Tue Dec 12 18:10:40 2017 +0200
@@ -573,11 +573,9 @@
 	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 @@
 		/* 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 @@
 	}
 };
 
-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;
 }
--- a/src/lib-storage/list/mailbox-list-index-status.c	Tue Feb 06 12:37:34 2018 +0200
+++ b/src/lib-storage/list/mailbox-list-index-status.c	Tue Dec 12 18:10:40 2017 +0200
@@ -747,8 +747,7 @@
 	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 @@
 	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 @@
 	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 @@
 	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;
 }
 
--- a/src/lib-storage/list/mailbox-list-index-storage.h	Tue Feb 06 12:37:34 2018 +0200
+++ b/src/lib-storage/list/mailbox-list-index-storage.h	Tue Dec 12 18:10:40 2017 +0200
@@ -11,6 +11,8 @@
 
 	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,
--- a/src/lib-storage/list/mailbox-list-index.c	Tue Feb 06 12:37:34 2018 +0200
+++ b/src/lib-storage/list/mailbox-list-index.c	Tue Dec 12 18:10:40 2017 +0200
@@ -936,6 +936,36 @@
 		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 @@
 	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 = {
--- a/src/lib-storage/list/mailbox-list-index.h	Tue Feb 06 12:37:34 2018 +0200
+++ b/src/lib-storage/list/mailbox-list-index.h	Tue Dec 12 18:10:40 2017 +0200
@@ -204,8 +204,15 @@
 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