dovecot: fsck the index while it's being mapped.
dovecot at dovecot.org
dovecot at dovecot.org
Sat Sep 15 10:06:00 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/fc2f5607108d
changeset: 6375:fc2f5607108d
user: Timo Sirainen <tss at iki.fi>
date: Sat Sep 15 09:22:16 2007 +0300
description:
fsck the index while it's being mapped.
diffstat:
3 files changed, 66 insertions(+), 84 deletions(-)
src/lib-index/mail-index-map.c | 51 ++++++++++--------
src/lib-index/mail-index-private.h | 1
src/lib-index/mail-index.c | 98 +++++++++++++-----------------------
diffs (254 lines):
diff -r 0a90044b42c9 -r fc2f5607108d src/lib-index/mail-index-map.c
--- a/src/lib-index/mail-index-map.c Sat Sep 15 09:21:47 2007 +0300
+++ b/src/lib-index/mail-index-map.c Sat Sep 15 09:22:16 2007 +0300
@@ -119,7 +119,7 @@ static int mail_index_parse_extensions(s
offset = MAIL_INDEX_HEADER_SIZE_ALIGN(map->hdr.base_header_size);
if (offset >= map->hdr.header_size && map->extension_pool == NULL) {
/* nothing to do, skip allocatations and all */
- return 1;
+ return 0;
}
old_count = array_count(&index->extensions);
@@ -206,7 +206,7 @@ static int mail_index_parse_extensions(s
offset += MAIL_INDEX_HEADER_SIZE_ALIGN(ext_hdr->hdr_size);
}
- return 1;
+ return 0;
}
static bool mail_index_check_header_compat(struct mail_index *index,
@@ -634,15 +634,14 @@ struct mail_index_map *mail_index_map_al
return mail_index_map_clone(&tmp_map);
}
-static int mail_index_map_latest_file(struct mail_index *index,
- struct mail_index_map **map)
-{
- struct mail_index_map *new_map;
+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;
- int ret;
+ int ret, try;
ret = mail_index_reopen_if_changed(index);
if (ret <= 0) {
@@ -685,20 +684,28 @@ static int mail_index_map_latest_file(st
ret = mail_index_read_map(new_map, file_size);
mail_index_unlock(index, &lock_id);
}
- if (ret > 0) {
+
+ for (try = 0; ret > 0 && try < 2; try++) {
/* make sure the header is ok before using this mapping */
ret = mail_index_map_check_header(new_map);
- if (ret >= 0) {
- ret = mail_index_parse_extensions(new_map);
- if (ret > 0) {
- if (mail_index_map_parse_keywords(new_map) < 0)
- ret = -1;
- }
- }
- if (ret == 0)
- index->fsck = TRUE;
- else if (ret < 0)
- ret = 0;
+ if (ret > 0) {
+ if (mail_index_parse_extensions(new_map) < 0)
+ ret = 0;
+ else if (mail_index_map_parse_keywords(new_map) < 0)
+ ret = 0;
+ }
+ if (ret != 0)
+ break;
+
+ /* fsck and try again */
+ old_map = index->map;
+ index->map = new_map;
+ ret = mail_index_fsck(index);
+
+ /* fsck cloned the map, so we'll have to update it */
+ mail_index_unmap(&new_map);
+ new_map = index->map;
+ index->map = old_map;
}
if (ret <= 0) {
mail_index_unmap(&new_map);
@@ -713,8 +720,8 @@ static int mail_index_map_latest_file(st
new_map->hdr.log_file_tail_offset;
index->last_read_stat = st;
- mail_index_unmap(map);
- *map = new_map;
+ mail_index_unmap(&index->map);
+ index->map = new_map;
return 1;
}
@@ -745,7 +752,7 @@ int mail_index_map(struct mail_index *in
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, &index->map);
+ (void)mail_index_map_latest_file(index);
/* if we're creating the index file, we don't have any
logs yet */
diff -r 0a90044b42c9 -r fc2f5607108d src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h Sat Sep 15 09:21:47 2007 +0300
+++ b/src/lib-index/mail-index-private.h Sat Sep 15 09:22:16 2007 +0300
@@ -209,7 +209,6 @@ struct mail_index {
unsigned int use_excl_dotlocks:1;
unsigned int nfs_flush:1;
unsigned int readonly:1;
- unsigned int fsck:1;
unsigned int mapping:1;
unsigned int need_recreate:1;
};
diff -r 0a90044b42c9 -r fc2f5607108d src/lib-index/mail-index.c
--- a/src/lib-index/mail-index.c Sat Sep 15 09:21:47 2007 +0300
+++ b/src/lib-index/mail-index.c Sat Sep 15 09:22:16 2007 +0300
@@ -399,8 +399,8 @@ int mail_index_create_tmp_file(struct ma
return fd;
}
-static bool mail_index_open_files(struct mail_index *index,
- enum mail_index_open_flags flags)
+static int mail_index_open_files(struct mail_index *index,
+ enum mail_index_open_flags flags)
{
int ret;
bool created = FALSE;
@@ -408,7 +408,7 @@ static bool mail_index_open_files(struct
ret = mail_transaction_log_open(index->log);
if (ret == 0) {
if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
- return FALSE;
+ return 0;
/* if dovecot.index exists, read it first so that we can get
the correct indexid and log sequence */
@@ -441,21 +441,21 @@ static bool mail_index_open_files(struct
if (ret < 0) {
/* open/create failed, fallback to in-memory indexes */
if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
- return FALSE;
+ return -1;
if (mail_index_move_to_memory(index) < 0)
- return FALSE;
+ return -1;
}
index->cache = created ? mail_cache_create(index) :
mail_cache_open_or_create(index);
- return TRUE;
+ return 1;
}
int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
enum file_lock_method lock_method)
{
- int i = 0, ret = 1;
+ int ret;
if (index->opened) {
if (index->map != NULL &&
@@ -473,61 +473,37 @@ int mail_index_open(struct mail_index *i
i_strdup("(in-memory index)") :
i_strconcat(index->dir, "/", index->prefix, NULL);
- for (;;) {
- index->shared_lock_count = 0;
- index->excl_lock_count = 0;
- index->lock_type = F_UNLCK;
- index->lock_id_counter = 2;
-
- index->readonly = FALSE;
- index->nodiskspace = FALSE;
- index->index_lock_timeout = FALSE;
- index->log_locked = FALSE;
- index->mmap_disable =
- (flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) != 0;
- index->use_excl_dotlocks =
- (flags & MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL) != 0;
- index->fsync_disable =
- (flags & MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE) != 0;
- index->nfs_flush =
- (flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0;
- index->lock_method = lock_method;
-
- if (index->nfs_flush && index->fsync_disable)
- i_fatal("nfs flush requires fsync_disable=no");
- if (index->nfs_flush && !index->mmap_disable)
- i_fatal("nfs flush requires mmap_disable=yes");
-
- i_assert(!index->opened);
- if (!mail_index_open_files(index, flags)) {
- /* doesn't exist and create flag not used */
- ret = 0;
- break;
- }
- i_assert(index->map != NULL);
-
- index->opened = TRUE;
- if (index->fsck) {
- index->fsck = FALSE;
- ret = mail_index_fsck(index);
- if (ret == 0) {
- /* completely broken, reopen */
- if (i++ < 3) {
- mail_index_close(index);
- continue;
- }
- /* too many tries */
- ret = -1;
- }
- }
- break;
- }
-
- if (ret <= 0)
+ index->shared_lock_count = 0;
+ index->excl_lock_count = 0;
+ index->lock_type = F_UNLCK;
+ index->lock_id_counter = 2;
+
+ index->readonly = FALSE;
+ index->nodiskspace = FALSE;
+ index->index_lock_timeout = FALSE;
+ index->log_locked = FALSE;
+ index->mmap_disable = (flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) != 0;
+ index->use_excl_dotlocks =
+ (flags & MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL) != 0;
+ index->fsync_disable =
+ (flags & MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE) != 0;
+ index->nfs_flush = (flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0;
+ index->lock_method = lock_method;
+
+ if (index->nfs_flush && index->fsync_disable)
+ i_fatal("nfs flush requires fsync_disable=no");
+ if (index->nfs_flush && !index->mmap_disable)
+ i_fatal("nfs flush requires mmap_disable=yes");
+
+ if ((ret = mail_index_open_files(index, flags)) <= 0) {
+ /* doesn't exist and create flag not used */
mail_index_close(index);
-
- i_assert(ret <= 0 || index->map != NULL);
- return ret;
+ return ret;
+ }
+
+ i_assert(index->map != NULL);
+ index->opened = TRUE;
+ return 1;
}
static void mail_index_close_file(struct mail_index *index)
More information about the dovecot-cvs
mailing list