From: Timo Sirainen Date: Mon, 30 Mar 2020 14:28:41 +0000 (+0300) Subject: lib-index: Add mail_cache_unlock() that doesn't flush any headers X-Git-Tag: 2.3.11.2~392 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=20c2c2cce4bebc4f9e247dd2c37f1efbd8f75b12;p=thirdparty%2Fdovecot%2Fcore.git lib-index: Add mail_cache_unlock() that doesn't flush any headers --- diff --git a/src/lib-index/mail-cache-private.h b/src/lib-index/mail-cache-private.h index b063622ddb..93ff789e22 100644 --- a/src/lib-index/mail-cache-private.h +++ b/src/lib-index/mail-cache-private.h @@ -211,8 +211,11 @@ struct mail_cache_lookup_iterate_ctx { 1 if ok, 0 if cache is broken/doesn't exist */ int mail_cache_lock(struct mail_cache *cache); int mail_cache_try_lock(struct mail_cache *cache); -/* Returns -1 if cache is / just got corrupted, 0 if ok. */ +/* Flush pending header updates and unlock. Returns -1 if cache is / just got + corrupted, 0 if ok. */ int mail_cache_flush_and_unlock(struct mail_cache *cache); +/* Unlock the cache without any header updates. */ +void mail_cache_unlock(struct mail_cache *cache); int mail_cache_write(struct mail_cache *cache, const void *data, size_t size, uoff_t offset); diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index 1e4149225f..ab5c310b34 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -851,10 +851,11 @@ int mail_cache_flush_and_unlock(struct mail_cache *cache) if (cache->field_header_write_pending) ret = mail_cache_header_fields_update(cache); + /* Cache may become unusable during for various reasons, e.g. + mail_cache_map(). Also the above mail_cache_header_fields_update() + call can make it unusable, so check this after it. */ if (MAIL_CACHE_IS_UNUSABLE(cache)) { - /* we found it to be broken during the lock. just clean up. */ - cache->hdr_modified = FALSE; - cache->locked = FALSE; + mail_cache_unlock(cache); return -1; } @@ -867,14 +868,24 @@ int mail_cache_flush_and_unlock(struct mail_cache *cache) mail_cache_update_need_compress(cache); } - if (cache->index->fsync_mode == FSYNC_MODE_ALWAYS) { + mail_cache_unlock(cache); + return ret; +} + +void mail_cache_unlock(struct mail_cache *cache) +{ + i_assert(cache->locked); + + if (MAIL_CACHE_IS_UNUSABLE(cache)) { + /* we found it to be broken during the lock. just clean up. */ + cache->hdr_modified = FALSE; + } else if (cache->index->fsync_mode == FSYNC_MODE_ALWAYS) { if (fdatasync(cache->fd) < 0) mail_cache_set_syscall_error(cache, "fdatasync()"); } cache->locked = FALSE; mail_cache_unlock_file(cache); - return ret; } int mail_cache_write(struct mail_cache *cache, const void *data, size_t size,