changeset 22328:a86e10e8e8a3

sdbox: Create missing mail directory on resync if index directory exists This problem should be visible only with ITERINDEX enabled.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 11 Jul 2017 14:14:47 +0300
parents dc4a976b82a6
children f2e7b5010810
files src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h
diffstat 3 files changed, 35 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c	Wed Jul 12 17:54:44 2017 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c	Tue Jul 11 14:14:47 2017 +0300
@@ -107,8 +107,7 @@
 				/* alt directory doesn't exist, ignore */
 				return 0;
 			}
-			mailbox_set_deleted(ctx->box);
-			return -1;
+			return index_mailbox_fix_inconsistent_existence(ctx->box, path);
 		}
 		mail_storage_set_critical(storage,
 			"opendir(%s) failed: %m", path);
--- a/src/lib-storage/index/index-storage.c	Wed Jul 12 17:54:44 2017 +0300
+++ b/src/lib-storage/index/index-storage.c	Tue Jul 11 14:14:47 2017 +0300
@@ -1134,3 +1134,35 @@
 	   specific record, so we'll reset the whole cache transaction. */
 	mail_cache_transaction_reset(ctx->transaction->cache_trans);
 }
+
+int index_mailbox_fix_inconsistent_existence(struct mailbox *box,
+					     const char *path)
+{
+	const char *index_path;
+	struct stat st;
+
+	/* Could be a race condition or could be because ITERINDEX is used
+	   and the index directory exists, but the storage directory doesn't.
+	   Handle the existence inconsistency by creating this directory if
+	   the index directory exists (don't bother checking if ITERINDEX is
+	   set or not - it doesn't matter since either both dirs should exist
+	   or not). */
+	if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX,
+				&index_path) < 0)
+		return -1;
+
+	if (strcmp(index_path, path) == 0) {
+		/* there's no separate index path - mailbox was just deleted */
+	} else if (stat(index_path, &st) == 0) {
+		/* inconsistency - create also the mail directory */
+		return mailbox_mkdir(box, path, MAILBOX_LIST_PATH_TYPE_MAILBOX);
+	} else if (errno == ENOENT) {
+		/* race condition - mailbox was just deleted */
+	} else {
+		mail_storage_set_critical(box->storage,
+			"stat(%s) failed: %m", index_path);
+		return -1;
+	}
+	mailbox_set_deleted(box);
+	return -1;
+}
--- a/src/lib-storage/index/index-storage.h	Wed Jul 12 17:54:44 2017 +0300
+++ b/src/lib-storage/index/index-storage.h	Tue Jul 11 14:14:47 2017 +0300
@@ -82,6 +82,8 @@
 int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest);
 
 int index_mailbox_update_last_temp_file_scan(struct mailbox *box);
+int index_mailbox_fix_inconsistent_existence(struct mailbox *box,
+					     const char *path);
 
 bool index_storage_is_readonly(struct mailbox *box);
 bool index_storage_is_inconsistent(struct mailbox *box);