Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8303:d3b37327936e HEAD
Maildir: Re-read uidlist from the beginning before deciding it's corrupted.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 19 Oct 2008 14:38:09 +0300 |
parents | 0db37acdc59f |
children | ab22ace44190 |
files | src/lib-storage/index/maildir/maildir-uidlist.c |
diffstat | 1 files changed, 22 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Sun Oct 19 14:00:57 2008 +0300 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Sun Oct 19 14:38:09 2008 +0300 @@ -90,6 +90,7 @@ unsigned int initial_read:1; unsigned int initial_hdr_read:1; unsigned int initial_sync:1; + unsigned int retry_rewind:1; }; struct maildir_uidlist_sync_ctx { @@ -305,9 +306,17 @@ va_list args; va_start(args, fmt); - mail_storage_set_critical(storage, "Broken file %s line %u: %s", - uidlist->path, uidlist->read_line_count, - t_strdup_vprintf(fmt, args)); + if (uidlist->retry_rewind) { + mail_storage_set_critical(storage, + "Broken or unexpectedly changed file %s " + "line %u: %s - re-reading from beginning", + uidlist->path, uidlist->read_line_count, + t_strdup_vprintf(fmt, args)); + } else { + mail_storage_set_critical(storage, "Broken file %s line %u: %s", + uidlist->path, uidlist->read_line_count, + t_strdup_vprintf(fmt, args)); + } va_end(args); } @@ -405,7 +414,7 @@ } if (uid <= uidlist->prev_read_uid) { maildir_uidlist_set_corrupted(uidlist, - "UIDs not ordered (%u > %u)", + "UIDs not ordered (%u >= %u)", uid, uidlist->prev_read_uid); return FALSE; } @@ -627,16 +636,23 @@ uidlist->prev_read_uid = 0; uidlist->change_counter++; uidlist->read_records_count = 0; + uidlist->retry_rewind = last_read_offset != 0 && try_retry; ret = 1; while ((line = i_stream_read_next_line(input)) != NULL) { uidlist->read_records_count++; uidlist->read_line_count++; if (!maildir_uidlist_next(uidlist, line)) { - ret = 0; + if (!uidlist->retry_rewind) + ret = 0; + else { + ret = -1; + *retry_r = TRUE; + } break; } } + uidlist->retry_rewind = FALSE; if (input->stream_errno != 0) ret = -1; @@ -663,7 +679,7 @@ uidlist->fd_size = st.st_size; uidlist->last_read_offset = input->v_offset; maildir_uidlist_update_hdr(uidlist, &st); - } else { + } else if (!*retry_r) { /* I/O error */ if (input->stream_errno == ESTALE && try_retry) *retry_r = TRUE;