bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen#include "lib.h"
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen#include "str.h"
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen#include "strescape.h"
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen#include "net.h"
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen#include "write-full.h"
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen#include "mail-search-build.h"
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen#include "index-storage.h"
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen#include "index-mailbox-size.h"
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen/*
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen Saving new mails: After transaction is committed and synced, trigger
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen vsize updating. Lock vsize updates. Check if the message count +
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen last-indexed-uid are still valid. If they are, add all the missing new
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mails. Unlock.
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen Fetching vsize: Lock vsize updates. Check if the message count +
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen last-indexed-uid are still valid. If not, set them to zero. Add all
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen the missing mails. Unlock.
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen Expunging mails: Check if syncing would expunge any mails. If so, lock the
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen vsize updates before locking syncing (to avoid deadlocks). Check if the
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen message count + last-indexed-uid are still valid. If not, unlock vsize and
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen do nothing else. Otherwise, for each expunged mail whose UID <=
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen last-indexed-uid, decrease the message count and the vsize in memory. After
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen syncing is successfully committed, write the changes to header. Unlock.
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen Note that the final expunge handling with some mailbox formats is done while
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen syncing is no longer locked. Because of this we need to have the vsize
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen locking. The final vsize header update requires committing a transaction,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen which internally is the same as a sync lock. So to avoid deadlocks we always
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen need to lock vsize updates before sync.
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen*/
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9cc53ac30c33f403964cc3f4f51456301dc044bcAki Tuomi#define VSIZE_LOCK_SUFFIX "dovecot-vsize.lock"
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen#define VSIZE_UPDATE_MAX_LOCK_SECS 10
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen#define INDEXER_SOCKET_NAME "indexer"
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen#define INDEXER_HANDSHAKE "VERSION\tindexer\t1\t0\n"
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenstruct mailbox_vsize_update {
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox *box;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mail_index_view *view;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_index_vsize vsize_hdr, orig_vsize_hdr;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct file_lock *lock;
181e90a1e5bedeb8d5584b488d4b0eb64cab7f8eTimo Sirainen bool lock_failed;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen bool rebuild;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen bool written;
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen bool finish_in_background;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen};
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenstatic void vsize_header_refresh(struct mailbox_vsize_update *update)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen const void *data;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen size_t size;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->view != NULL)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mail_index_view_close(&update->view);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen (void)mail_index_refresh(update->box->index);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->view = mail_index_view_open(update->box->index);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mail_index_get_header_ext(update->view, update->box->vsize_hdr_ext_id,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen &data, &size);
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen if (size > 0) {
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen memcpy(&update->orig_vsize_hdr, data,
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen I_MIN(size, sizeof(update->orig_vsize_hdr)));
6d404348751c19ac37cfb42375abdd3c5f298e30Timo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (size == sizeof(update->vsize_hdr))
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen memcpy(&update->vsize_hdr, data, sizeof(update->vsize_hdr));
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen else {
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (size != 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(update->box,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen "vsize-hdr has invalid size: %"PRIuSIZE_T,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen size);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->rebuild = TRUE;
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update->vsize_hdr);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenstatic void
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenindex_mailbox_vsize_check_rebuild(struct mailbox_vsize_update *update)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen uint32_t seq1, seq2;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->vsize_hdr.highest_uid == 0)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (!mail_index_lookup_seq_range(update->view, 1,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->vsize_hdr.highest_uid,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen &seq1, &seq2))
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen seq2 = 0;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->vsize_hdr.message_count != seq2) {
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->vsize_hdr.message_count < seq2) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(update->box,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen "vsize-hdr has invalid message-count (%u < %u)",
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->vsize_hdr.message_count, seq2);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen } else {
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen /* some messages have been expunged, rescan */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update->vsize_hdr);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->rebuild = TRUE;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenstruct mailbox_vsize_update *
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenindex_mailbox_vsize_update_init(struct mailbox *box)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_vsize_update *update;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
c9ac17980cf2eec9575f891a566841d0c7902ee9Timo Sirainen i_assert(box->opened);
c9ac17980cf2eec9575f891a566841d0c7902ee9Timo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update = i_new(struct mailbox_vsize_update, 1);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->box = box;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen vsize_header_refresh(update);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return update;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainenstatic bool vsize_update_lock_full(struct mailbox_vsize_update *update,
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen unsigned int lock_secs)
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen{
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen struct mailbox *box = update->box;
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen const char *error;
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen int ret;
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen if (update->lock != NULL)
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen return TRUE;
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen if (update->lock_failed)
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen return FALSE;
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(box->index))
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen return FALSE;
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen
bd94a2a86e27f4809d087a8269bc4ccdd5f4ede3Timo Sirainen ret = mailbox_lock_file_create(box, VSIZE_LOCK_SUFFIX, lock_secs,
bd94a2a86e27f4809d087a8269bc4ccdd5f4ede3Timo Sirainen &update->lock, &error);
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen if (ret <= 0) {
99e9dc500f54366263d1de804d933030df0385a2Timo Sirainen /* don't log lock timeouts, because we're somewhat expecting
99e9dc500f54366263d1de804d933030df0385a2Timo Sirainen them. Especially when lock_secs is 0. */
2864ce8150abac6890408c77aad10dd522633ff4Timo Sirainen if (ret < 0)
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box, "%s", error);
181e90a1e5bedeb8d5584b488d4b0eb64cab7f8eTimo Sirainen update->lock_failed = TRUE;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return FALSE;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->rebuild = FALSE;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen vsize_header_refresh(update);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen index_mailbox_vsize_check_rebuild(update);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return TRUE;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenbool index_mailbox_vsize_update_try_lock(struct mailbox_vsize_update *update)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return vsize_update_lock_full(update, 0);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenbool index_mailbox_vsize_update_wait_lock(struct mailbox_vsize_update *update)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return vsize_update_lock_full(update, VSIZE_UPDATE_MAX_LOCK_SECS);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenbool index_mailbox_vsize_want_updates(struct mailbox_vsize_update *update)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return update->vsize_hdr.highest_uid > 0;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenstatic void
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenindex_mailbox_vsize_update_write(struct mailbox_vsize_update *update)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mail_index_transaction *trans;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->written)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->written = TRUE;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
ede2466e3f1b7fdf1ceb35909a5fd4182a06c56bAki Tuomi if (update->rebuild == FALSE &&
ede2466e3f1b7fdf1ceb35909a5fd4182a06c56bAki Tuomi memcmp(&update->orig_vsize_hdr, &update->vsize_hdr,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen sizeof(update->vsize_hdr)) == 0) {
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen /* no changes */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen trans = mail_index_transaction_begin(update->view,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mail_index_update_header_ext(trans, update->box->vsize_hdr_ext_id,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen 0, &update->vsize_hdr,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen sizeof(update->vsize_hdr));
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen (void)mail_index_transaction_commit(&trans);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainenstatic void index_mailbox_vsize_notify_indexer(struct mailbox *box)
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen{
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen string_t *str = t_str_new(256);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen const char *path;
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen int fd;
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen path = t_strconcat(box->storage->user->set->base_dir,
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen "/"INDEXER_SOCKET_NAME, NULL);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen fd = net_connect_unix(path);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen if (fd == -1) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box,
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen "Can't start vsize building on background: "
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen "net_connect_unix(%s) failed: %m", path);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen return;
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen }
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen str_append(str, INDEXER_HANDSHAKE);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen str_append(str, "APPEND\t0\t");
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen str_append_tabescaped(str, box->storage->user->username);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen str_append_c(str, '\t');
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen str_append_tabescaped(str, box->vname);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen str_append_c(str, '\n');
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen if (write_full(fd, str_data(str), str_len(str)) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(box,
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen "Can't start vsize building on background: "
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen "write(%s) failed: %m", path);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen }
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen i_close_fd(&fd);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen}
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenvoid index_mailbox_vsize_update_deinit(struct mailbox_vsize_update **_update)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_vsize_update *update = *_update;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen *_update = NULL;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->lock != NULL || update->rebuild)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen index_mailbox_vsize_update_write(update);
5109f00ce0cf7c89be9ab20a488a93a59212ff2eJosef 'Jeff' Sipek file_lock_free(&update->lock);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen if (update->finish_in_background)
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen index_mailbox_vsize_notify_indexer(update->box);
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mail_index_view_close(&update->view);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen i_free(update);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenvoid index_mailbox_vsize_hdr_expunge(struct mailbox_vsize_update *update,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen uint32_t uid, uoff_t vsize)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen i_assert(update->lock != NULL);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (uid > update->vsize_hdr.highest_uid)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->vsize_hdr.message_count == 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(update->box,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen "vsize-hdr's message_count shrank below 0");
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update->vsize_hdr);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->vsize_hdr.message_count--;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->vsize_hdr.vsize < vsize) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi mailbox_set_critical(update->box,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen "vsize-hdr's vsize shrank below 0");
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&update->vsize_hdr);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->vsize_hdr.vsize -= vsize;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainenstatic int
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainenindex_mailbox_vsize_hdr_add_missing(struct mailbox_vsize_update *update,
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen bool require_result)
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_index_vsize *vsize_hdr = &update->vsize_hdr;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen struct mailbox_transaction_context *trans;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen struct mail_search_context *search_ctx;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen struct mail_search_args *search_args;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_status status;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen struct mail *mail;
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen unsigned int mails_left;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen uint32_t seq1, seq2;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen uoff_t vsize;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen int ret = 0;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mailbox_get_open_status(update->box, STATUS_UIDNEXT, &status);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (vsize_hdr->highest_uid + 1 >= status.uidnext) {
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen /* nothing to do - we should have usually caught this already
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen before locking */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return 0;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen }
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen /* note that update->view may be more up-to-date than box->view.
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen we'll just add whatever new mails are in box->view. if we'll notice
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen that some of the new mails are missing, we'll need to stop there
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen since that expunge will be applied later on to the vsize header. */
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen search_args = mail_search_build_init();
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (!mail_index_lookup_seq_range(update->box->view,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen vsize_hdr->highest_uid + 1,
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen status.uidnext-1, &seq1, &seq2)) {
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen /* nothing existed, but update uidnext */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen vsize_hdr->highest_uid = status.uidnext - 1;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mail_search_args_unref(&search_args);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen return 0;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen mail_search_build_add_seqset(search_args, seq1, seq2);
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi trans = mailbox_transaction_begin(update->box, 0, "vsize update");
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen search_ctx = mailbox_search_init(trans, search_args, NULL,
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen MAIL_FETCH_VIRTUAL_SIZE, NULL);
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen if (!require_result)
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen mails_left = 0;
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen else if (update->box->storage->set->mail_vsize_bg_after_count == 0)
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen mails_left = UINT_MAX;
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen else
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen mails_left = update->box->storage->set->mail_vsize_bg_after_count;
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen while (mailbox_search_next(search_ctx, &mail)) {
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen if (mails_left == 0) {
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen /* if there are any more mails whose vsize can't be
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen looked up from cache, abort and finish on
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen background. */
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE;
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen }
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen ret = mail_get_virtual_size(mail, &vsize);
4d690a42c4dd10d6508e499c5bab58c45a49d1f3Timo Sirainen mail->lookup_abort = MAIL_LOOKUP_ABORT_NEVER;
4d690a42c4dd10d6508e499c5bab58c45a49d1f3Timo Sirainen
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen if (ret < 0 &&
a0cd302bcb827678f9c9c2ca1d0a3f0d3c0b3563Timo Sirainen mailbox_get_last_mail_error(update->box) == MAIL_ERROR_LOOKUP_ABORTED) {
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen /* abort and finish on background */
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen i_assert(mails_left == 0);
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen mail_storage_set_error(update->box->storage, MAIL_ERROR_INUSE,
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen "Finishing vsize calculation on background");
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen if (require_result)
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen update->finish_in_background = TRUE;
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen break;
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen }
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen if (mail->mail_stream_opened || mail->mail_metadata_accessed) {
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen /* slow vsize lookup */
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen i_assert(mails_left > 0);
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen mails_left--;
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen }
ca004511f36c090b07c6f097cf237ce836d8faf6Timo Sirainen
a758be690d736655ed7c1e3dfb46d3aaf4dd5db2Timo Sirainen if (ret < 0) {
abc063522f0285b2fc5128f26f4e2e5172a00e5cTimo Sirainen if (mail->expunged)
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen continue;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen ret = -1;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen break;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen }
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen vsize_hdr->vsize += vsize;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen vsize_hdr->highest_uid = mail->uid;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen vsize_hdr->message_count++;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen }
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen if (mailbox_search_deinit(&search_ctx) < 0)
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen ret = -1;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen mail_search_args_unref(&search_args);
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen if (ret == 0) {
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen /* success, cache all */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen vsize_hdr->highest_uid = status.uidnext - 1;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen } else {
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen /* search failed, cache only up to highest seen uid */
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen }
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen (void)mailbox_transaction_commit(&trans);
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen return ret;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen}
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainenint index_mailbox_get_virtual_size(struct mailbox *box,
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen struct mailbox_metadata *metadata_r)
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_vsize_update *update;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen struct mailbox_status status;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen int ret;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen mailbox_get_open_status(box, STATUS_MESSAGES | STATUS_UIDNEXT, &status);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update = index_mailbox_vsize_update_init(box);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen if (update->vsize_hdr.highest_uid + 1 == status.uidnext &&
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update->vsize_hdr.message_count == status.messages) {
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen /* up to date */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen metadata_r->virtual_size = update->vsize_hdr.vsize;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen index_mailbox_vsize_update_deinit(&update);
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen return 0;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen /* we need to update it - lock it if possible. if not, update it
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen anyway internally even though we won't be saving the result. */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen (void)index_mailbox_vsize_update_wait_lock(update);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
abd812f275c5366feea20f25081d1c9296e552efTimo Sirainen ret = index_mailbox_vsize_hdr_add_missing(update, TRUE);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen metadata_r->virtual_size = update->vsize_hdr.vsize;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen index_mailbox_vsize_update_deinit(&update);
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen return ret;
2c759e5193bb1013513eb96768f43693d2ffc963Timo Sirainen}
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainenint index_mailbox_get_physical_size(struct mailbox *box,
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen struct mailbox_metadata *metadata_r)
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen{
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen struct mailbox_transaction_context *trans;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen struct mail_search_context *ctx;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen struct mail *mail;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen struct mail_search_args *search_args;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen uoff_t size;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen int ret = 0;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen /* if physical size = virtual size always for the storage, we can
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen use the optimized vsize code for this */
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen if (box->mail_vfuncs->get_physical_size ==
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen box->mail_vfuncs->get_virtual_size) {
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen if (index_mailbox_get_virtual_size(box, metadata_r) < 0)
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen return -1;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen metadata_r->physical_size = metadata_r->virtual_size;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen return 0;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen }
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen /* do it the slow way (we could implement similar logic as for vsize,
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen but for now it's not really needed) */
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen return -1;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi trans = mailbox_transaction_begin(box, 0, "mailbox physical size");
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen search_args = mail_search_build_init();
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen mail_search_build_add_all(search_args);
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen ctx = mailbox_search_init(trans, search_args, NULL,
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen MAIL_FETCH_PHYSICAL_SIZE, NULL);
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen mail_search_args_unref(&search_args);
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen metadata_r->physical_size = 0;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen while (mailbox_search_next(ctx, &mail)) {
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen if (mail_get_physical_size(mail, &size) == 0)
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen metadata_r->physical_size += size;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen else {
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen const char *errstr;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen enum mail_error error;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi errstr = mailbox_get_last_internal_error(box, &error);
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen if (error != MAIL_ERROR_EXPUNGED) {
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen i_error("Couldn't get size of mail UID %u in %s: %s",
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen mail->uid, box->vname, errstr);
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen ret = -1;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen break;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen }
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen }
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen }
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen if (mailbox_search_deinit(&ctx) < 0) {
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen i_error("Listing mails in %s failed: %s",
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi box->vname, mailbox_get_last_internal_error(box, NULL));
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen ret = -1;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen }
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen (void)mailbox_transaction_commit(&trans);
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen return ret;
dae42444ac716f397a41f6f72c2581f304bb6e5bTimo Sirainen}
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainenvoid index_mailbox_vsize_update_appends(struct mailbox *box)
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen{
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_vsize_update *update;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen struct mailbox_status status;
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen update = index_mailbox_vsize_update_init(box);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen /* update here only if we don't need to rebuild the whole vsize. */
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen index_mailbox_vsize_check_rebuild(update);
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen if (index_mailbox_vsize_want_updates(update)) {
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen /* Get the UIDNEXT only after checking that vsize updating is
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen even potentially wanted for this mailbox. We especially
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen don't want to do this with imapc, because it could trigger
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen a remote STATUS (UIDNEXT) call. */
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen mailbox_get_open_status(update->box, STATUS_UIDNEXT, &status);
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen if (update->vsize_hdr.highest_uid + 1 != status.uidnext &&
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen index_mailbox_vsize_update_try_lock(update))
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen (void)index_mailbox_vsize_hdr_add_missing(update, FALSE);
0b45d816c73e0bfba55d84fb50005ba2714ac0faTimo Sirainen }
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen index_mailbox_vsize_update_deinit(&update);
9963bef626fd9ea227fb606e8b1694cdb1ab39aaTimo Sirainen}