Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4056:caddc57d1f61 HEAD
Fixes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 24 Feb 2006 18:06:51 +0200 |
parents | f7ff79c3189b |
children | f4807accc1d5 |
files | src/lib-storage/index/dbox/dbox-file.c src/lib-storage/index/dbox/dbox-mail.c src/lib-storage/index/dbox/dbox-storage.h src/lib-storage/index/dbox/dbox-sync-expunge.c src/lib-storage/index/dbox/dbox-sync.c src/lib-storage/index/dbox/dbox-uidlist.c |
diffstat | 6 files changed, 55 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox/dbox-file.c Fri Feb 24 16:36:35 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-file.c Fri Feb 24 18:06:51 2006 +0200 @@ -116,7 +116,7 @@ mbox->file->path = i_strdup_printf("%s/"DBOX_MAILDIR_NAME"/" - DBOX_MAIL_FILE_PREFIX"%x", + DBOX_MAIL_FILE_FORMAT, mbox->path, file_seq); }
--- a/src/lib-storage/index/dbox/dbox-mail.c Fri Feb 24 16:36:35 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-mail.c Fri Feb 24 18:06:51 2006 +0200 @@ -119,7 +119,7 @@ } mail_storage_set_critical(STORAGE(mbox->storage), - "Cached message offset lost for seq %u in " + "Cached message offset broken for seq %u in " "dbox file %s", seq, mbox->path); return -1; }
--- a/src/lib-storage/index/dbox/dbox-storage.h Fri Feb 24 16:36:35 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-storage.h Fri Feb 24 18:06:51 2006 +0200 @@ -5,6 +5,7 @@ #define DBOX_INDEX_PREFIX "dovecot.index" #define DBOX_MAILDIR_NAME "Mails" #define DBOX_MAIL_FILE_PREFIX "msg." +#define DBOX_MAIL_FILE_FORMAT DBOX_MAIL_FILE_PREFIX"%u" #define DBOX_KEYWORD_COUNT 64 #define DBOX_KEYWORD_NAMES_RESERVED_SPACE (2048-sizeof(struct dbox_file_header))
--- a/src/lib-storage/index/dbox/dbox-sync-expunge.c Fri Feb 24 16:36:35 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-sync-expunge.c Fri Feb 24 18:06:51 2006 +0200 @@ -86,17 +86,22 @@ unsigned int sync_count; int ret, fd; + /* skip mails until we find the first we don't want expunged */ ret = dbox_file_seek(mbox, orig_entry->file_seq, orig_offset); while (ret > 0) { ret = dbox_file_seek_next_nonexpunged(mbox); - if (ret <= 0) - break; - if (mbox->file->seeked_uid >= first_nonexpunged_uid) break; } - if (ret < 0) - return -1; + + if (ret <= 0) { + if (ret == 0) { + mail_storage_set_critical(STORAGE(mbox->storage), + "%s: Expunging lost UID %u from file", + mbox->path, first_nonexpunged_uid); + } + return ret; + } sync_recs = array_get(&sync_entry->sync_recs, &sync_count); if (sync_idx == sync_count) @@ -110,7 +115,7 @@ file_seq = dbox_uidlist_get_new_file_seq(mbox->uidlist); path = t_strdup_printf("%s/"DBOX_MAILDIR_NAME"/" - DBOX_MAIL_FILE_PREFIX"%u", + DBOX_MAIL_FILE_FORMAT, mbox->path, file_seq); fd = file_dotlock_open(&new_file_dotlock_set, path, 0, &dotlock); if (fd < 0) @@ -124,7 +129,11 @@ /* write file header */ dbox_file_header_init(&hdr); - ret = o_stream_send(output, &hdr, sizeof(hdr)); + if (o_stream_send(output, &hdr, sizeof(hdr)) != sizeof(hdr)) { + mail_storage_set_critical(STORAGE(mbox->storage), + "o_stream_send(%s) failed: %m", path); + ret = -1; + } while (ret > 0) { /* update mail's location in index */ @@ -339,7 +348,7 @@ /* we need to have the file locked in case another process is appending there already. */ path = t_strdup_printf("%s/"DBOX_MAILDIR_NAME"/" - DBOX_MAIL_FILE_PREFIX"%u", + DBOX_MAIL_FILE_FORMAT, ctx->mbox->path, entry->file_seq); ret = file_dotlock_create(&new_file_dotlock_set, path, DOTLOCK_CREATE_FLAG_NONBLOCK,
--- a/src/lib-storage/index/dbox/dbox-sync.c Fri Feb 24 16:36:35 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-sync.c Fri Feb 24 18:06:51 2006 +0200 @@ -466,6 +466,8 @@ &uid_validity, sizeof(uid_validity), TRUE); } if (hdr->next_uid != next_uid) { + i_assert(next_uid > hdr->next_uid || + hdr->uid_validity != uid_validity); mail_index_update_header(ctx.trans, offsetof(struct mail_index_header, next_uid), &next_uid, sizeof(next_uid), FALSE);
--- a/src/lib-storage/index/dbox/dbox-uidlist.c Fri Feb 24 16:36:35 2006 +0200 +++ b/src/lib-storage/index/dbox/dbox-uidlist.c Fri Feb 24 18:06:51 2006 +0200 @@ -117,7 +117,7 @@ uidlist->mtime = -1; uidlist->lock_fd = -1; uidlist->entry_pool = - pool_alloconly_create("uidlist entry pool", 10240); + pool_alloconly_create("uidlist entry pool", 1024*32); uidlist->path = i_strconcat(mbox->path, "/"DBOX_MAILDIR_NAME"/" DBOX_UIDLIST_FILENAME, NULL); @@ -170,36 +170,33 @@ { struct dbox_uidlist_entry *dest_entry, **entries, **pos; const struct seq_range *range; - unsigned int i, count; + unsigned int i, idx, count; + entries = array_get_modifyable(&uidlist->entries, &count); if (src_entry->file_seq > uidlist->entry_last_file_seq) { /* append new file sequence */ + idx = count; + } else { + pos = bsearch_insert_pos(&src_entry->file_seq, entries, count, + sizeof(*entries), + dbox_uidlist_entry_cmp); + idx = pos - entries; + } + + if (idx == count || entries[idx]->file_seq != src_entry->file_seq) { + /* new entry */ dest_entry = p_new(uidlist->entry_pool, struct dbox_uidlist_entry, 1); *dest_entry = *src_entry; - array_append(&uidlist->entries, &dest_entry, 1); + array_insert(&uidlist->entries, idx, &dest_entry, 1); uidlist->entry_last_file_seq = src_entry->file_seq; if (src_entry->file_seq > uidlist->last_file_seq) uidlist->last_file_seq = src_entry->file_seq; } else { - /* merge to existing entry. they're written in order, so we - don't try to handle non-merging inserting. */ - entries = array_get_modifyable(&uidlist->entries, &count); - pos = bsearch(&src_entry->file_seq, entries, count, - sizeof(*entries), dbox_uidlist_entry_cmp); - if (pos == NULL) { - mail_storage_set_critical( - STORAGE(uidlist->mbox->storage), - "%s: File sequences not ordered (%u < %u)", - uidlist->path, src_entry->file_seq, - uidlist->entry_last_file_seq); - return FALSE; - } - - /* now, do the merging. UIDs must be growing since only new - mails are appended */ - dest_entry = *pos; + /* merge to existing entry. UIDs must be growing since only + new mails are appended */ + dest_entry = entries[idx]; if (src_entry->create_time > dest_entry->create_time) dest_entry->create_time = src_entry->create_time; if (src_entry->file_size > dest_entry->file_size) @@ -233,13 +230,19 @@ struct seq_range, 8); /* get uid list */ - range.seq1 = 0; + range.seq1 = range.seq2 = 0; for (digit = 0; *line != '\0'; line++) { if (*line >= '0' && *line <= '9') digit = digit * 10 + *line-'0'; else { - if (range.seq1 == 0) + if (range.seq1 == 0) { + if (digit <= range.seq2) { + /* broken */ + array_clear(&entry->uid_list); + break; + } range.seq1 = digit; + } if (*line == ',' || *line == ' ') { if (range.seq1 > digit) { /* broken */ @@ -248,6 +251,7 @@ } range.seq2 = digit; array_append(&entry->uid_list, &range, 1); + range.seq1 = 0; if (digit > uidlist->last_uid) { /* last_uid isn't up to date */ @@ -558,7 +562,7 @@ if (st2.st_mtime <= st.st_mtime) { struct utimbuf ut; - st2.st_mtime = ++st.st_mtime; + st2.st_mtime = st.st_mtime + 1; ut.actime = ioloop_time; ut.modtime = st2.st_mtime; @@ -647,6 +651,7 @@ int ret = 0; i_assert(ctx->uidlist->fd != -1); + i_assert(ctx->uidlist->lock_fd != -1); if (lseek(ctx->uidlist->fd, 0, SEEK_END) < 0) { mail_storage_set_critical(STORAGE(ctx->uidlist->mbox->storage), @@ -745,6 +750,7 @@ if (dbox_uidlist_write_append_offsets(ctx) < 0) ret = -1; else { + ctx->uidlist->need_full_rewrite = TRUE; // FIXME if (ctx->uidlist->need_full_rewrite) { dbox_uidlist_update_changes(ctx); ret = dbox_uidlist_full_rewrite(ctx->uidlist); @@ -906,7 +912,7 @@ /* try locking the file. */ str_truncate(str, 0); str_printfa(str, "%s/"DBOX_MAILDIR_NAME"/" - DBOX_MAIL_FILE_PREFIX"%u", mbox->path, file_seq); + DBOX_MAIL_FILE_FORMAT, mbox->path, file_seq); ret = file_dotlock_create(&dbox_file_dotlock_set, str_c(str), DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock); @@ -1123,6 +1129,8 @@ struct dbox_uidlist_entry *new_entry; unsigned int count; + i_assert(array_count(&entry->uid_list) > 0); + new_entry = p_new(ctx->uidlist->entry_pool, struct dbox_uidlist_entry, 1); *new_entry = *entry; @@ -1154,7 +1162,7 @@ i_assert(entry != NULL); path = t_strdup_printf("%s/"DBOX_MAILDIR_NAME"/" - DBOX_MAIL_FILE_PREFIX"%u", + DBOX_MAIL_FILE_FORMAT, ctx->uidlist->mbox->path, entry->file_seq); if (unlink(path) < 0) { mail_storage_set_critical(STORAGE(ctx->uidlist->mbox->storage),