From: Timo Sirainen Date: Mon, 21 Jun 2004 14:44:47 +0000 (+0300) Subject: Cache doesn't crash anymore if we're asking it about messages that exist X-Git-Tag: 1.1.alpha1~3885 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b44a50ea4123f21dfc8e1b6c602f690fd9721b67;p=thirdparty%2Fdovecot%2Fcore.git Cache doesn't crash anymore if we're asking it about messages that exist only in uncommitted transactions. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-cache-lookup.c b/src/lib-index/mail-cache-lookup.c index 628f98b44d..8ad0050c02 100644 --- a/src/lib-index/mail-cache-lookup.c +++ b/src/lib-index/mail-cache-lookup.c @@ -175,7 +175,11 @@ mail_cache_lookup(struct mail_cache_view *view, uint32_t seq, if (view->cache->disabled) return NULL; - /* FIXME: check cache_offset in transaction */ + if (seq > mail_index_view_get_message_count(view->view)) { + /* it's being appended in some transaction */ + return NULL; + } + if (mail_index_lookup_full(view->view, seq, &map, &rec) < 0) return NULL; diff --git a/src/lib-index/mail-cache-transaction.c b/src/lib-index/mail-cache-transaction.c index a0ddd24369..3c63de017c 100644 --- a/src/lib-index/mail-cache-transaction.c +++ b/src/lib-index/mail-cache-transaction.c @@ -220,7 +220,7 @@ static int mail_cache_write(struct mail_cache_transaction_ctx *ctx) struct mail_cache_record *cache_rec, *next; const struct mail_index_record *rec; struct mail_index_map *map; - uint32_t write_offset, update_offset; + uint32_t messages_count, write_offset, update_offset; const void *buf; size_t size, buf_size; int ret; @@ -230,9 +230,15 @@ static int mail_cache_write(struct mail_cache_transaction_ctx *ctx) size = sizeof(*cache_rec) + buf_size; ctx->cache_rec.size = uint32_to_nbo(size); - // FIXME: check cache_offset in transaction - ret = mail_index_lookup_full(ctx->view->view, ctx->prev_seq, - &map, &rec); + messages_count = mail_index_view_get_message_count(ctx->view->view); + if (ctx->prev_seq <= messages_count) { + ret = mail_index_lookup_full(ctx->view->view, ctx->prev_seq, + &map, &rec); + } else { + ret = mail_index_transaction_lookup(ctx->trans, + ctx->prev_seq, &rec); + map = cache->index->map; + } if (ret < 0) return -1; diff --git a/src/lib-index/mail-index-sync.c b/src/lib-index/mail-index-sync.c index b21ba2a790..1bc89ecfbc 100644 --- a/src/lib-index/mail-index-sync.c +++ b/src/lib-index/mail-index-sync.c @@ -6,6 +6,7 @@ #include "mail-index-sync-private.h" #include "mail-transaction-log.h" #include "mail-transaction-util.h" +#include "mail-cache.h" #include diff --git a/src/lib-index/mail-index-transaction.c b/src/lib-index/mail-index-transaction.c index b4da4bd478..35a003990a 100644 --- a/src/lib-index/mail-index-transaction.c +++ b/src/lib-index/mail-index-transaction.c @@ -136,6 +136,30 @@ void mail_index_transaction_rollback(struct mail_index_transaction *t) mail_index_transaction_free(t); } +static struct mail_index_record * +mail_index_lookup_append(struct mail_index_transaction *t, uint32_t seq) +{ + size_t pos; + + i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq); + + pos = (seq - t->first_new_seq) * t->view->index->record_size; + return buffer_get_space_unsafe(t->appends, pos, + t->view->index->record_size); +} + +int mail_index_transaction_lookup(struct mail_index_transaction *t, + uint32_t seq, + const struct mail_index_record **rec_r) +{ + if (t->first_new_seq != 0 && seq >= t->first_new_seq) { + *rec_r = mail_index_lookup_append(t, seq); + return 1; + } else { + return mail_index_lookup(t->view, seq, rec_r); + } +} + void mail_index_append(struct mail_index_transaction *t, uint32_t uid, uint32_t *seq_r) { @@ -161,18 +185,6 @@ void mail_index_append(struct mail_index_transaction *t, uint32_t uid, rec->uid = uid; } -static struct mail_index_record * -mail_index_lookup_append_rec(struct mail_index_transaction *t, uint32_t seq) -{ - size_t pos; - - i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq); - - pos = (seq - t->first_new_seq) * t->view->index->record_size; - return buffer_get_space_unsafe(t->appends, pos, - t->view->index->record_size); -} - void mail_index_expunge(struct mail_index_transaction *t, uint32_t seq) { struct mail_transaction_expunge exp, *data; @@ -303,7 +315,7 @@ void mail_index_update_flags(struct mail_index_transaction *t, uint32_t seq, if (t->first_new_seq != 0 && seq >= t->first_new_seq) { /* just appended message, modify it directly */ - rec = mail_index_lookup_append_rec(t, seq); + rec = mail_index_lookup_append(t, seq); mail_index_record_modify_flags(rec, modify_type, flags, keywords); return; @@ -487,7 +499,7 @@ void mail_index_update_cache(struct mail_index_transaction *t, if (t->first_new_seq != 0 && seq >= t->first_new_seq) { /* just appended message, modify it directly */ - rec = mail_index_lookup_append_rec(t, seq); + rec = mail_index_lookup_append(t, seq); rec->cache_offset = offset; } else { mail_index_update_seq_buffer(&t->cache_updates, seq, @@ -507,7 +519,7 @@ void mail_index_update_extra_rec(struct mail_index_transaction *t, if (t->first_new_seq != 0 && seq >= t->first_new_seq) { /* just appended message, modify it directly */ /* FIXME: do data_id mapping conversion */ - rec = mail_index_lookup_append_rec(t, seq); + rec = mail_index_lookup_append(t, seq); memcpy(PTR_OFFSET(rec, index->extra_records[data_id].offset), data, index->extra_records[data_id].size); } else { @@ -528,9 +540,3 @@ void mail_index_update_header(struct mail_index_transaction *t, for (; size > 0; size--) t->hdr_mask[offset++] = 1; } - -const struct mail_index_record * -mail_index_lookup_append(struct mail_index_transaction *t, uint32_t seq) -{ - return mail_index_lookup_append_rec(t, seq); -} diff --git a/src/lib-index/mail-index.h b/src/lib-index/mail-index.h index 0067da8de6..e6aad4b0a1 100644 --- a/src/lib-index/mail-index.h +++ b/src/lib-index/mail-index.h @@ -278,10 +278,11 @@ void mail_index_update_header(struct mail_index_transaction *t, void mail_index_update_extra_rec(struct mail_index_transaction *t, uint32_t seq, uint32_t data_id, const void *data); -/* Returns given appended message, with all updates that have been done - to it since the append. */ -const struct mail_index_record * -mail_index_lookup_append(struct mail_index_transaction *t, uint32_t seq); +/* Like mail_index_lookup(), but if seq > view's message count, it's referring + to message appended with given transaction. */ +int mail_index_transaction_lookup(struct mail_index_transaction *t, + uint32_t seq, + const struct mail_index_record **rec_r); /* Returns the last error code. */ enum mail_index_error mail_index_get_last_error(struct mail_index *index); diff --git a/src/lib-storage/index/mbox/mbox-save.c b/src/lib-storage/index/mbox/mbox-save.c index 3060cd47ad..a65bfe96bb 100644 --- a/src/lib-storage/index/mbox/mbox-save.c +++ b/src/lib-storage/index/mbox/mbox-save.c @@ -345,7 +345,8 @@ int mbox_save(struct mailbox_transaction_context *_t, if (mail_r != NULL) { const struct mail_index_record *rec; - rec = mail_index_lookup_append(ctx->trans, seq); + if (mail_index_transaction_lookup(ctx->trans, seq, &rec) < 0) + return -1; if (index_mail_next(&ctx->mail, rec, seq, FALSE) <= 0) return -1; *mail_r = &ctx->mail.mail;