dovecot: Do a bit better job with fscking.
dovecot at dovecot.org
dovecot at dovecot.org
Sat Jun 16 01:09:30 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/0096aaf83731
changeset: 5754:0096aaf83731
user: Timo Sirainen <tss at iki.fi>
date: Sat Jun 16 01:09:26 2007 +0300
description:
Do a bit better job with fscking.
diffstat:
1 file changed, 50 insertions(+), 21 deletions(-)
src/lib-index/mail-index-fsck.c | 71 +++++++++++++++++++++++++++------------
diffs (132 lines):
diff -r 929cc98ac04e -r 0096aaf83731 src/lib-index/mail-index-fsck.c
--- a/src/lib-index/mail-index-fsck.c Sat Jun 16 01:02:57 2007 +0300
+++ b/src/lib-index/mail-index-fsck.c Sat Jun 16 01:09:26 2007 +0300
@@ -1,6 +1,7 @@
-/* Copyright (C) 2004 Timo Sirainen */
+/* Copyright (C) 2004-2007 Timo Sirainen */
#include "lib.h"
+#include "ioloop.h"
#include "mail-index-private.h"
#include "mail-transaction-log.h"
@@ -25,23 +26,45 @@ static void mail_index_fsck_error(struct
static int
mail_index_fsck_map(struct mail_index *index, struct mail_index_map *map,
- const char **error_r)
+ bool *lock, const char **error_r)
{
struct mail_index_header hdr;
const struct mail_index_record *rec;
+ uint32_t file_seq;
+ uoff_t file_offset;
uint32_t i, last_uid;
*error_r = NULL;
+ if (*lock) {
+ if (mail_transaction_log_sync_lock(index->log, &file_seq,
+ &file_offset) < 0) {
+ *lock = FALSE;
+ return -1;
+ }
+ } else {
+ mail_transaction_log_get_head(index->log, &file_seq,
+ &file_offset);
+ }
+
/* locking already does the most important sanity checks for header */
hdr = map->hdr;
- if (hdr.uid_validity == 0 && hdr.next_uid != 1) {
- *error_r = "uid_validity = 0 && next_uid != 1";
- return 0;
- }
+ if (hdr.uid_validity == 0 && hdr.next_uid != 1)
+ hdr.uid_validity = ioloop_time;
hdr.flags &= ~MAIL_INDEX_HDR_FLAG_FSCK;
+
+ if (hdr.log_file_seq != file_seq) {
+ hdr.log_file_seq = file_seq;
+ hdr.log_file_head_offset = hdr.log_file_tail_offset =
+ sizeof(struct mail_transaction_log_header);
+ } else {
+ if (hdr.log_file_head_offset > file_offset)
+ hdr.log_file_head_offset = file_offset;
+ if (hdr.log_file_tail_offset > hdr.log_file_head_offset)
+ hdr.log_file_tail_offset = hdr.log_file_head_offset;
+ }
hdr.messages_count = 0;
hdr.recent_messages_count = 0;
@@ -94,6 +117,11 @@ mail_index_fsck_map(struct mail_index *i
if (hdr.first_deleted_uid_lowwater == 0)
hdr.first_deleted_uid_lowwater = hdr.next_uid;
+ CHECK(log_file_seq, !=);
+ CHECK(log_file_head_offset, !=);
+ CHECK(log_file_tail_offset, !=);
+
+ CHECK(uid_validity, !=);
CHECK(messages_count, !=);
CHECK(recent_messages_count, !=);
CHECK(seen_messages_count, !=);
@@ -101,7 +129,7 @@ mail_index_fsck_map(struct mail_index *i
CHECK(first_recent_uid_lowwater, <);
CHECK(first_unseen_uid_lowwater, <);
- CHECK(first_deleted_uid_lowwater, <);
+ CHECK(first_deleted_uid_lowwater, <);
map->hdr = hdr;
return 1;
@@ -109,26 +137,24 @@ mail_index_fsck_map(struct mail_index *i
int mail_index_fsck(struct mail_index *index)
{
- const char *error;
- unsigned int lock_id;
+ const char *error = NULL;
+ struct mail_index_map *map;
+ bool lock = !index->log_locked;
int ret;
i_warning("fscking index file %s", index->filepath);
- // FIXME: should we be fscking a given map instead? anyway we probably
- // want to rewrite the main index after fsck is finished.
- error = NULL;
- ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD, &lock_id);
+ map = mail_index_map_clone(index->map);
+ mail_index_unmap(index, &index->map);
+ index->map = map;
+
+ ret = mail_index_fsck_map(index, map, &lock, &error);
if (ret > 0) {
- ret = mail_index_fsck_map(index, index->map, &error);
- if (ret > 0) {
- if (mail_index_write_base_header(index,
- &index->map->hdr) < 0)
- ret = -1;
- }
+ map->write_base_header = TRUE;
+ map->write_atomic = TRUE;
+
+ mail_index_write(index, FALSE);
}
-
- mail_index_unlock(index, lock_id);
if (error != NULL) {
mail_index_set_error(index, "Corrupted index file %s: %s",
@@ -136,5 +162,8 @@ int mail_index_fsck(struct mail_index *i
}
if (ret == 0)
mail_index_mark_corrupted(index);
+
+ if (lock)
+ mail_transaction_log_sync_unlock(index->log);
return ret;
}
More information about the dovecot-cvs
mailing list