From: Timo Sirainen Date: Mon, 30 Mar 2020 14:12:50 +0000 (+0300) Subject: lib-index: mail_cache_lookup_offset() - Use mail_cache_sync_reset_id() X-Git-Tag: 2.3.11.2~395 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a50b4e22c6dd1e2de6e4c2f0610fccac38865f3b;p=thirdparty%2Fdovecot%2Fcore.git lib-index: mail_cache_lookup_offset() - Use mail_cache_sync_reset_id() This avoids race conditions where cache fields aren't found during cache compression. --- diff --git a/src/lib-index/mail-cache-lookup.c b/src/lib-index/mail-cache-lookup.c index b42a2cbb40..8b49cfa052 100644 --- a/src/lib-index/mail-cache-lookup.c +++ b/src/lib-index/mail-cache-lookup.c @@ -80,32 +80,31 @@ static int mail_cache_lookup_offset(struct mail_cache *cache, struct mail_index_view *view, uint32_t seq, uint32_t *offset_r) { - uint32_t offset, reset_id; - int i, ret; + uint32_t offset, reset_id, reset_id2; + int ret; offset = mail_cache_lookup_cur_offset(view, seq, &reset_id); if (offset == 0) return 0; - /* reset_id must match file_seq or the offset is for a different cache - file. if this happens, try if reopening the cache helps. if not, - it was probably for an old cache file that's already lost by now. */ - i = 0; while (cache->hdr->file_seq != reset_id) { - if (++i == 2 || reset_id < cache->hdr->file_seq) - return 0; + /* reset_it doesn't match - sync the index/cache */ + if ((ret = mail_cache_sync_reset_id(cache)) <= 0) + return ret; - if (cache->locked) { - /* we're probably compressing */ + /* lookup again after syncing */ + offset = mail_cache_lookup_cur_offset(view, seq, &reset_id2); + if (offset == 0) return 0; - } - - if (!mail_cache_need_reopen(cache)) + if (cache->hdr->file_seq == reset_id2) + break; /* match - all good */ + if (reset_id == reset_id2) { + /* reset_id didn't change after sync. This means it's + pointing to an old already deleted cache file. */ return 0; - else if ((ret = mail_cache_reopen(cache)) <= 0) { - /* error / corrupted */ - return ret; } + /* reset_id changed - try again */ + reset_id = reset_id2; } *offset_r = offset;