From: Timo Sirainen Date: Tue, 11 Jul 2017 11:14:47 +0000 (+0300) Subject: sdbox: Create missing mail directory on resync if index directory exists X-Git-Tag: 2.2.32.rc1~104 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d662a5ab26a6734ea0c070c1c0f76f94a868cdb8;p=thirdparty%2Fdovecot%2Fcore.git sdbox: Create missing mail directory on resync if index directory exists This problem should be visible only with ITERINDEX enabled. --- diff --git a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c index 6df07c2ba1..eb6281e65f 100644 --- a/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c +++ b/src/lib-storage/index/dbox-single/sdbox-sync-rebuild.c @@ -107,8 +107,7 @@ static int sdbox_sync_index_rebuild_dir(struct index_rebuild_context *ctx, /* 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); diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 7735516c40..6b0482f76d 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -1134,3 +1134,35 @@ void index_storage_save_abort_last(struct mail_save_context *ctx, uint32_t seq) 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; +} diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index f3d86fa5f1..b245117b2f 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -82,6 +82,8 @@ int index_storage_mailbox_delete_dir(struct mailbox *box, bool mailbox_deleted); 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);