From: Timo Sirainen Date: Mon, 30 Mar 2020 12:13:56 +0000 (+0300) Subject: lib-index: mail_cache_*lock() - Handle syscall errors correctly X-Git-Tag: 2.3.11.2~400 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a616d36650035dfd9930c4ac4a3a8416f1e89eb7;p=thirdparty%2Fdovecot%2Fcore.git lib-index: mail_cache_*lock() - Handle syscall errors correctly If reading a cache file failed because of some temporary syscall error, it was treated the same as if the cache was corrupted. This could have caused compression to lose cached data. --- diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index c3cab5f6dc..25759488cd 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -699,14 +699,21 @@ mail_cache_lock_full(struct mail_cache *cache, bool nonblock) index. */ i_assert(!cache->index->mapping || cache->index->log_sync_locked); - if (!cache->opened) - (void)mail_cache_open_and_verify(cache); - - if (MAIL_CACHE_IS_UNUSABLE(cache) || - MAIL_INDEX_IS_IN_MEMORY(cache->index) || + if (MAIL_INDEX_IS_IN_MEMORY(cache->index) || cache->index->readonly) return 0; + /* Make sure at least some cache file is opened. Usually it's the + latest one, so delay until it's locked to check whether a newer + cache file exists. */ + if ((ret = mail_cache_open_and_verify(cache)) < 0) + return -1; + if (ret == 0) { + /* Cache doesn't exist or it was just found to be corrupted and + was unlinked. Cache compression will create it back. */ + return 0; + } + for (;;) { if (mail_cache_lock_file(cache, nonblock) <= 0) return -1; @@ -715,9 +722,9 @@ mail_cache_lock_full(struct mail_cache *cache, bool nonblock) /* locked the latest file */ break; } - if (mail_cache_reopen(cache) <= 0) { + if ((ret = mail_cache_reopen(cache)) <= 0) { i_assert(cache->file_lock == NULL); - return -1; + return ret; } i_assert(cache->file_lock == NULL); /* okay, so it was just compressed. try again. */