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