Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6375:fc2f5607108d HEAD
fsck the index while it's being mapped.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 15 Sep 2007 09:22:16 +0300 |
parents | 0a90044b42c9 |
children | 9b9436231ce0 |
files | src/lib-index/mail-index-map.c src/lib-index/mail-index-private.h src/lib-index/mail-index.c |
diffstat | 3 files changed, 61 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ 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 @@ 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 @@ return mail_index_map_clone(&tmp_map); } -static int mail_index_map_latest_file(struct mail_index *index, - struct mail_index_map **map) +static int mail_index_map_latest_file(struct mail_index *index) { - struct mail_index_map *new_map; + 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 @@ 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) { + 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) - index->fsck = TRUE; - else if (ret < 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 @@ 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 @@ 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 */
--- 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 @@ 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; };
--- 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 @@ 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 @@ 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 @@ 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 @@ 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; + index->shared_lock_count = 0; + index->excl_lock_count = 0; + index->lock_type = F_UNLCK; + index->lock_id_counter = 2; - 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->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; - 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 (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); + return ret; } - if (ret <= 0) - mail_index_close(index); - - i_assert(ret <= 0 || index->map != NULL); - return ret; + i_assert(index->map != NULL); + index->opened = TRUE; + return 1; } static void mail_index_close_file(struct mail_index *index)