# HG changeset patch # User Timo Sirainen # Date 1030418778 -10800 # Node ID d8ff9a34ed0326d219c8a6b01f8cc63e9bdcacd8 # Parent e399e33d033dca9e6bc929357dffef550e873eb8 Hash is now properly rebuilt if errors are noticed while opening it. diff -r e399e33d033d -r d8ff9a34ed03 src/lib-index/mail-hash.c --- a/src/lib-index/mail-hash.c Tue Aug 27 05:28:16 2002 +0300 +++ b/src/lib-index/mail-hash.c Tue Aug 27 06:26:18 2002 +0300 @@ -52,17 +52,8 @@ unsigned int modified:1; }; -static int mmap_update(MailHash *hash) +static int mmap_update_real(MailHash *hash) { - if (hash->fd == -1) - return FALSE; - - if (!hash->dirty_mmap) { - /* see if someone else modified it */ - if (hash->header->updateid == hash->updateid) - return TRUE; - } - if (hash->mmap_base != NULL) (void)munmap(hash->mmap_base, hash->mmap_length); @@ -76,6 +67,11 @@ return FALSE; } + return TRUE; +} + +static int hash_verify_header(MailHash *hash) +{ if (hash->mmap_length <= sizeof(MailHashHeader) || (hash->mmap_length - sizeof(MailHashHeader)) % sizeof(MailHashRecord) != 0) { @@ -88,9 +84,7 @@ return FALSE; } - hash->dirty_mmap = FALSE; hash->header = hash->mmap_base; - hash->updateid = hash->header->updateid; hash->size = (hash->mmap_length - sizeof(MailHashHeader)) / sizeof(MailHashRecord); @@ -102,9 +96,26 @@ "Invalid size %u", hash->filepath, hash->size); return FALSE; } + + hash->dirty_mmap = FALSE; return TRUE; } +static int mmap_update(MailHash *hash) +{ + if (hash->fd == -1) + return FALSE; + + if (!hash->dirty_mmap) { + /* see if someone else modified it */ + if (hash->header->updateid == hash->updateid) + return TRUE; + } + + return mmap_update_real(hash) && hash_verify_header(hash); + +} + static MailHash *mail_hash_new(MailIndex *index) { MailHash *hash; @@ -143,15 +154,16 @@ if (hash->fd == -1) return mail_hash_lock_and_rebuild(hash); - if (!mmap_update(hash)) { + if (!mmap_update_real(hash)) { /* mmap() failure is fatal */ mail_hash_free(hash); return FALSE; } - /* verify that this really is the hash file for wanted index */ - if (hash->header->indexid != index->indexid) { - /* mismatch - just recreate it */ + /* make sure the header looks fine */ + if (!hash_verify_header(hash) || + hash->header->indexid != hash->index->indexid) { + /* just recreate it */ (void)munmap(hash->mmap_base, hash->mmap_length); hash->mmap_base = NULL; hash->dirty_mmap = TRUE;