Mercurial > dovecot > core-2.2
changeset 4109:988a8ef1deea HEAD
Some fixes to get dbox code working better. Still needs some work though..
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 30 Mar 2006 13:31:28 +0300 |
parents | e1774d677536 |
children | 9662de8fc649 |
files | src/lib-storage/index/dbox/dbox-sync-expunge.c src/lib-storage/index/dbox/dbox-sync.c src/lib-storage/index/dbox/dbox-sync.h src/lib-storage/index/dbox/dbox-uidlist.c |
diffstat | 4 files changed, 81 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox/dbox-sync-expunge.c Mon Mar 27 15:54:24 2006 +0300 +++ b/src/lib-storage/index/dbox/dbox-sync-expunge.c Thu Mar 30 13:31:28 2006 +0300 @@ -4,6 +4,8 @@ #include "array.h" #include "istream.h" #include "ostream.h" +#include "write-full.h" +#include "hex-dec.h" #include "seq-range-array.h" #include "dbox-storage.h" #include "dbox-uidlist.h" @@ -78,7 +80,7 @@ struct dotlock *dotlock; struct istream *input; struct ostream *output; - struct dbox_file_header hdr; + struct dbox_file *file; struct dbox_uidlist_entry dest_entry; const struct dbox_sync_rec *sync_recs; const char *path, *lock_path; @@ -142,12 +144,12 @@ dest_entry.file_seq = file_seq; /* write file header */ - dbox_file_header_init(&hdr); - if (o_stream_send(output, &hdr, sizeof(hdr)) != sizeof(hdr)) { - mail_storage_set_critical(STORAGE(mbox->storage), - "o_stream_send(%s) failed: %m", lock_path); + t_push(); + file = t_new(struct dbox_file, 1); + file->output = output; + if (dbox_file_write_header(mbox, file) < 0) // FIXME: leaks ret = -1; - } + t_pop(); while (ret > 0) { /* update mail's location in index */ @@ -216,13 +218,36 @@ if (ret <= 0) break; } - if (ret <= 0) + if (ret <= 0) { + if (ret == 0) { + /* we want to keep copying */ + ret = 1; + } break; + } if (mbox->file->seeked_uid < uid1 || uid1 == 0) break; } } + + if (ret == 0) { + struct dbox_file_header hdr; + + /* update append_offset in header */ + DEC2HEX(hdr.append_offset_hex, output->offset); + + o_stream_flush(output); + if (pwrite_full(fd, hdr.append_offset_hex, + sizeof(hdr.append_offset_hex), + offsetof(struct dbox_file_header, + append_offset_hex)) < 0) { + mail_storage_set_critical(STORAGE(mbox->storage), + "pwrite_full(%s) failed: %m", + lock_path); + ret = -1; + } + } o_stream_destroy(&output); if (ret < 0) { @@ -339,6 +364,15 @@ /* unexpected EOF -> already truncated */ } else { + /* file can no longer be appended to */ + if (pwrite_full(mbox->file->fd, "00000000EFFFFFFF", 16, + offsetof(struct dbox_file_header, + append_offset_hex)) < 0) { + mail_storage_set_critical(STORAGE(mbox->storage), + "pwrite_full(%s) failed: %m", mbox->path); + return -1; + } + if (ftruncate(mbox->file->fd, offset) < 0) { mail_storage_set_critical(STORAGE(mbox->storage), "ftruncate(%s) failed: %m", mbox->path); @@ -355,6 +389,9 @@ if (i > 0) range[i-1].seq2 = first_expunged_uid-1; + /* file can no longer be written to */ + entry->file_size = INT_MAX; + dbox_uidlist_sync_set_modified(ctx->uidlist_sync_ctx); return 0; }
--- a/src/lib-storage/index/dbox/dbox-sync.c Mon Mar 27 15:54:24 2006 +0300 +++ b/src/lib-storage/index/dbox/dbox-sync.c Thu Mar 30 13:31:28 2006 +0300 @@ -35,29 +35,27 @@ static int dbox_sync_add_seq(struct dbox_sync_context *ctx, uint32_t seq, const struct dbox_sync_rec *sync_rec) { - struct dbox_sync_file_entry *entry; + struct dbox_sync_rec new_sync_rec; + struct dbox_sync_file_entry *entry; + const uint32_t *file_seqs; + unsigned int i, count; uint32_t file_seq; uoff_t offset; if (dbox_sync_get_file_offset(ctx, seq, &file_seq, &offset) < 0) return -1; - if (ctx->prev_file_seq == file_seq) - return 0; /* already added in last sequence */ - ctx->prev_file_seq = file_seq; + file_seqs = array_get(&ctx->added_file_seqs, &count); + for (i = 0; i < count; i++) { + if (file_seqs[i] == file_seq) { + /* already added */ + return 0; + } + } + array_append(&ctx->added_file_seqs, &file_seq, 1); entry = hash_lookup(ctx->syncs, POINTER_CAST(file_seq)); - if (entry != NULL) { - /* check if it's already added */ - const struct dbox_sync_rec *sync_recs; - unsigned int count; - - sync_recs = array_get(&entry->sync_recs, &count); - i_assert(count > 0); - if (memcmp(&sync_recs[count-1], - sync_rec, sizeof(*sync_rec)) == 0) - return 0; /* already added */ - } else { + if (entry == NULL) { entry = p_new(ctx->pool, struct dbox_sync_file_entry, 1); entry->file_seq = file_seq; ARRAY_CREATE(&entry->sync_recs, ctx->pool, @@ -65,6 +63,8 @@ hash_insert(ctx->syncs, POINTER_CAST(file_seq), entry); } + new_sync_rec = *sync_rec; + new_sync_rec.seq1 = seq; array_append(&entry->sync_recs, sync_rec, 1); return 0; } @@ -114,7 +114,7 @@ } /* now, add the same sync_rec to each file_seq's entry */ - ctx->prev_file_seq = 0; + array_clear(&ctx->added_file_seqs); for (seq = seq1; seq <= seq2; seq++) { if (dbox_sync_add_seq(ctx, seq, &dbox_sync_rec) < 0) return -1; @@ -381,6 +381,7 @@ /* read all changes and sort them to file_seq order */ ctx->pool = pool_alloconly_create("dbox sync pool", 10240); ctx->syncs = hash_create(default_pool, ctx->pool, 0, NULL, NULL); + ARRAY_CREATE(&ctx->added_file_seqs, default_pool, uint32_t, 64); for (;;) { ret = mail_index_sync_next(ctx->index_sync_ctx, &sync_rec); if (ret <= 0) { @@ -393,6 +394,7 @@ break; } } + array_free(&ctx->added_file_seqs); iter = hash_iterate_init(ctx->syncs); while (hash_iterate(iter, &key, &value)) {
--- a/src/lib-storage/index/dbox/dbox-sync.h Mon Mar 27 15:54:24 2006 +0300 +++ b/src/lib-storage/index/dbox/dbox-sync.h Thu Mar 30 13:31:28 2006 +0300 @@ -38,7 +38,7 @@ pool_t pool; struct hash_table *syncs; /* struct dbox_sync_file_entry */ - uint32_t prev_file_seq; + array_t ARRAY_DEFINE(added_file_seqs, uint32_t); uint32_t dotlock_failed_file_seq;
--- a/src/lib-storage/index/dbox/dbox-uidlist.c Mon Mar 27 15:54:24 2006 +0300 +++ b/src/lib-storage/index/dbox/dbox-uidlist.c Thu Mar 30 13:31:28 2006 +0300 @@ -891,6 +891,7 @@ it's not completely trustworthy though. */ str = str_new(ctx->pool, 64); entries = array_get(&ctx->uidlist->entries, &count); +__again: for (i = 0;; i++) { file_seq = 0; for (; i < count; i++) { @@ -930,11 +931,9 @@ /* lock already exists, try next file */ } - save_file = p_new(ctx->pool, struct dbox_save_file, 1); - save_file->file = file = p_new(ctx->pool, struct dbox_file, 1); - save_file->dotlock = dotlock; + file = i_new(struct dbox_file, 1); file->file_seq = file_seq; - file->path = str_free_without_data(&str); + file->path = i_strdup(str_c(str)); file->fd = open(file->path, O_CREAT | O_RDWR, 0600); if (file->fd == -1) { @@ -963,6 +962,18 @@ dbox_file_close(file); return -1; } + + if (i < count) { + entries[i]->create_time = file->create_time; + entries[i]->file_size = file->append_offset; + } + + if (!DBOX_CAN_APPEND(mbox, file->create_time, + file->append_offset, + min_usable_timestamp)) { + dbox_file_close(file); + goto __again; + } } /* we'll always use CRLF linefeeds for mails (but not the header, @@ -973,6 +984,9 @@ o_stream_seek(file->output, file->append_offset); + save_file = p_new(ctx->pool, struct dbox_save_file, 1); + save_file->file = file; + save_file->dotlock = dotlock; save_file->dev = st.st_dev; save_file->ino = st.st_ino; ARRAY_CREATE(&save_file->seqs, ctx->pool, unsigned int, 8);