]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Add mail_cache_unlock() that doesn't flush any headers
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 30 Mar 2020 14:28:41 +0000 (17:28 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 15 Apr 2020 09:41:42 +0000 (12:41 +0300)
src/lib-index/mail-cache-private.h
src/lib-index/mail-cache.c

index b063622ddb3980aae024db895ffe3a5b7a2c563c..93ff789e2219355ced7fddad0a9b65c1d08cfc3c 100644 (file)
@@ -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);
index 1e4149225f3fa0b930d0aa5bee2850063aa7f594..ab5c310b3430601c64701fa9beb5e31e620c958b 100644 (file)
@@ -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,