dovecot-1.1: If index file's header shows that it's unusable (e....
dovecot at dovecot.org
dovecot at dovecot.org
Sun May 25 04:19:53 EEST 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/baf21d1db4e5
changeset: 7547:baf21d1db4e5
user: Timo Sirainen <tss at iki.fi>
date: Sun May 25 04:19:49 2008 +0300
description:
If index file's header shows that it's unusable (e.g. major version change
or CPU arch change), make sure they're not tried to be used and handle the
rebuilding nicely.
diffstat:
1 file changed, 33 insertions(+), 16 deletions(-)
src/lib-index/mail-index-map.c | 49 ++++++++++++++++++++++++++--------------
diffs (101 lines):
diff -r 7940ff8ecd13 -r baf21d1db4e5 src/lib-index/mail-index-map.c
--- a/src/lib-index/mail-index-map.c Sun May 25 04:18:42 2008 +0300
+++ b/src/lib-index/mail-index-map.c Sun May 25 04:19:49 2008 +0300
@@ -808,13 +808,15 @@ struct mail_index_map *mail_index_map_al
return mail_index_map_clone(&tmp_map);
}
+/* returns -1 = error, 0 = index files are unusable,
+ 1 = index files are usable or at least repairable */
static int mail_index_map_latest_file(struct mail_index *index)
{
struct mail_index_map *old_map, *new_map;
struct stat st;
unsigned int lock_id;
uoff_t file_size;
- bool use_mmap;
+ bool use_mmap, unusable = FALSE;
int ret, try;
ret = mail_index_reopen_if_changed(index);
@@ -824,7 +826,7 @@ static int mail_index_map_latest_file(st
/* the index file is lost/broken. let's hope that we can
build it from the transaction log. */
- return 0;
+ return 1;
}
/* the index file is still open, lock it */
@@ -857,6 +859,10 @@ static int mail_index_map_latest_file(st
} else {
ret = mail_index_read_map(new_map, file_size, &lock_id);
mail_index_unlock(index, &lock_id);
+ }
+ if (ret == 0) {
+ /* the index files are unusable */
+ unusable = TRUE;
}
for (try = 0; ret > 0; try++) {
@@ -868,8 +874,13 @@ static int mail_index_map_latest_file(st
else if (mail_index_map_parse_keywords(new_map) < 0)
ret = 0;
} T_END;
- if (ret != 0 || try == 2)
+ if (ret != 0 || try == 2) {
+ if (ret < 0) {
+ unusable = TRUE;
+ ret = 0;
+ }
break;
+ }
/* fsck and try again */
old_map = index->map;
@@ -885,7 +896,7 @@ static int mail_index_map_latest_file(st
}
if (ret <= 0) {
mail_index_unmap(&new_map);
- return ret;
+ return ret < 0 ? -1 : (unusable ? 0 : 1);
}
i_assert(new_map->rec_map->records != NULL);
@@ -924,18 +935,24 @@ int mail_index_map(struct mail_index *in
}
if (ret == 0) {
- /* try to open and read the latest index. if it fails for
- any reason, we'll fallback to updating the existing mapping
- from transaction logs (which we'll also do even if the
- reopening succeeds) */
- (void)mail_index_map_latest_file(index);
-
- /* if we're creating the index file, we don't have any
- logs yet */
- if (index->log->head != NULL && index->indexid != 0) {
- /* and update the map with the latest changes from
- transaction log */
- ret = mail_index_sync_map(&index->map, type, TRUE);
+ /* try to open and read the latest index. if it fails, we'll
+ fallback to updating the existing mapping from transaction
+ logs (which we'll also do even if the reopening succeeds).
+ if index files are unusable (e.g. major version change)
+ don't even try to use the transaction log. */
+ if (mail_index_map_latest_file(index) == 0) {
+ /* make sure we don't try to open the file again */
+ if (unlink(index->filepath) < 0 && errno != ENOENT)
+ mail_index_set_syscall_error(index, "unlink()");
+ } else {
+ /* if we're creating the index file, we don't have any
+ logs yet */
+ if (index->log->head != NULL && index->indexid != 0) {
+ /* and update the map with the latest changes
+ from transaction log */
+ ret = mail_index_sync_map(&index->map, type,
+ TRUE);
+ }
}
}
More information about the dovecot-cvs
mailing list