]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Check if maximum cache file size has reached only after locking
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 27 Mar 2020 16:26:23 +0000 (18:26 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 15 Apr 2020 09:41:42 +0000 (12:41 +0300)
This avoids race conditions.

src/lib-index/mail-cache-transaction.c

index 8e8224cbc314b9ee3c164719dfc074312ea39692..0fe554058364e6ca13f0be4d436dd7658d09d92d 100644 (file)
@@ -199,17 +199,6 @@ static int mail_cache_transaction_lock(struct mail_cache_transaction_ctx *ctx)
                cache->index->optimization_set.cache.max_size;
        int ret;
 
-       (void)mail_cache_open_and_verify(cache);
-       if (!ctx->tried_compression && ctx->cache_data != NULL &&
-           cache->last_stat_size + ctx->cache_data->used >= cache_max_size) {
-               /* Looks like cache file is becoming too large. Try to compress
-                  it to free up some space. */
-               if (!MAIL_CACHE_IS_UNUSABLE(cache) &&
-                   (cache->hdr->continued_record_count > 0 ||
-                    cache->hdr->deleted_record_count > 0))
-                       (void)mail_cache_transaction_compress(ctx);
-       }
-
        if ((ret = mail_cache_lock(cache)) <= 0) {
                if (ret < 0)
                        return -1;
@@ -224,6 +213,18 @@ static int mail_cache_transaction_lock(struct mail_cache_transaction_ctx *ctx)
        }
        i_assert(!MAIL_CACHE_IS_UNUSABLE(cache));
 
+       if (!ctx->tried_compression && ctx->cache_data != NULL &&
+           cache->last_stat_size + ctx->cache_data->used >= cache_max_size) {
+               /* Looks like cache file is becoming too large. Try to compress
+                  it to free up some space. */
+               if (cache->hdr->continued_record_count > 0 ||
+                   cache->hdr->deleted_record_count > 0) {
+                       (void)mail_cache_unlock(cache);
+                       (void)mail_cache_transaction_compress(ctx);
+                       return mail_cache_transaction_lock(ctx);
+               }
+       }
+
        if (ctx->cache_file_seq == 0)
                ctx->cache_file_seq = cache->hdr->file_seq;
        else if (ctx->cache_file_seq != cache->hdr->file_seq) {