# HG changeset patch # User Timo Sirainen # Date 1492603279 -10800 # Node ID 040667a0b3bedd223e9d83a659190b6d77ccf980 # Parent 44eb00aedb431bb4e3d6007d28a90644d886a362 lib-storage: Allow mail_add_temp_wanted_fields() to be called before mail_set_seq*() Quota plugin was already doing this, but it didn't actually work. It was also crashing with imapc: Panic: file mail-cache-lookup.c: line 341 (mail_cache_field_exists): assertion failed: (seq > 0) diff -r 44eb00aedb43 -r 040667a0b3be src/lib-storage/index/imapc/imapc-mail.c --- a/src/lib-storage/index/imapc/imapc-mail.c Thu Apr 20 19:16:46 2017 +0300 +++ b/src/lib-storage/index/imapc/imapc-mail.c Wed Apr 19 15:01:19 2017 +0300 @@ -411,7 +411,8 @@ struct index_mail *mail = (struct index_mail *)_mail; index_mail_add_temp_wanted_fields(_mail, fields, headers); - imapc_mail_update_access_parts(mail); + if (_mail->seq != 0) + imapc_mail_update_access_parts(mail); } static void imapc_mail_close(struct mail *_mail) diff -r 44eb00aedb43 -r 040667a0b3be src/lib-storage/index/index-mail.c --- a/src/lib-storage/index/index-mail.c Thu Apr 20 19:16:46 2017 +0300 +++ b/src/lib-storage/index/index-mail.c Wed Apr 19 15:01:19 2017 +0300 @@ -68,6 +68,7 @@ just be moved here to the same struct. */ }; +static void index_mail_init_data(struct index_mail *mail); static int index_mail_parse_body(struct index_mail *mail, enum index_cache_field field); @@ -1562,6 +1563,7 @@ mail->mail.wanted_headers = wanted_headers; mailbox_header_lookup_ref(wanted_headers); } + index_mail_init_data(mail); } static void index_mail_close_streams_full(struct index_mail *mail, bool closing) @@ -1610,13 +1612,10 @@ index_mail_close_streams_full(mail, FALSE); } -static void index_mail_reset_data(struct index_mail *mail) +static void index_mail_init_data(struct index_mail *mail) { struct index_mail_data *data = &mail->data; - i_zero(data); - p_clear(mail->mail.data_pool); - data->virtual_size = (uoff_t)-1; data->physical_size = (uoff_t)-1; data->save_date = (time_t)-1; @@ -1629,6 +1628,14 @@ data->wanted_headers = mail->mail.wanted_headers; mailbox_header_lookup_ref(data->wanted_headers); } +} + +static void index_mail_reset_data(struct index_mail *mail) +{ + i_zero(&mail->data); + p_clear(mail->mail.data_pool); + + index_mail_init_data(mail); mail->mail.mail.seq = 0; mail->mail.mail.uid = 0; @@ -1645,6 +1652,16 @@ { struct index_mail *mail = (struct index_mail *)_mail; + if (mail->mail.mail.seq == 0) { + /* mail_set_seq*() hasn't been called yet, or is being called + right now. Don't reset anything yet. We especially don't + want to reset wanted_fields or wanted_headers so that + mail_add_temp_wanted_fields() can be called by plugins + before mail_set_seq_saving() for + mail_save_context.dest_mail. */ + return; + } + /* If uid == 0 but seq != 0, we came here from saving a (non-mbox) message. If that happens, don't bother checking if anything should be cached since it was already checked. Also by now the transaction @@ -1699,6 +1716,14 @@ const struct mail_cache_field *cache_fields = mail->ibox->cache_fields; struct mail_cache_view *cache_view = _mail->transaction->cache_view; + if (_mail->seq == 0) { + /* mail_add_temp_wanted_fields() called before mail_set_seq*(). + We'll allow this, since it can be useful for plugins to + call it for mail_save_context.dest_mail. This function + is called again in mail_set_seq*(). */ + return; + } + if ((data->wanted_fields & (MAIL_FETCH_NUL_STATE | MAIL_FETCH_IMAP_BODY | MAIL_FETCH_IMAP_BODYSTRUCTURE)) != 0 && @@ -1803,6 +1828,11 @@ const struct mail_index_header *hdr; struct istream *input; + if (_mail->seq == 0) { + /* see index_mail_update_access_parts_pre() */ + return; + } + /* when mail_prefetch_count>1, at this point we've started the prefetching to all the mails and we're now starting to access the first mail. */