struct event_passthrough *e =
mail_cache_decision_changed_event(
cache, ctx->event, i)->
- add_str("reason", "purge")->
add_str("old_decision", "yes")->
add_str("new_decision", "temp");
e_debug(e->event(), "Purge changes field %s "
static int
mail_cache_copy(struct mail_cache *cache, struct mail_index_transaction *trans,
- struct event *event, int fd, uint32_t *file_seq_r,
- uoff_t *file_size_r, uint32_t *max_uid_r,
+ struct event *event, int fd, const char *reason,
+ uint32_t *file_seq_r, uoff_t *file_size_r, uint32_t *max_uid_r,
ARRAY_TYPE(uint32_t) *ext_offsets)
{
struct mail_cache_copy_context ctx;
unsigned int i, used_fields_count, orig_fields_count, record_count;
time_t max_drop_time;
+ i_assert(reason != NULL);
+
*max_uid_r = 0;
/* get the latest info on fields */
hdr.file_seq = get_next_file_seq(cache);
o_stream_nsend(output, &hdr, sizeof(hdr));
+ event_add_str(event, "reason", reason);
event_add_int(event, "file_seq", hdr.file_seq);
event_set_name(event, "mail_cache_purge_started");
- e_debug(event, "Purging (new file_seq=%u)", hdr.file_seq);
+ e_debug(event, "Purging (new file_seq=%u): %s", hdr.file_seq, reason);
i_zero(&ctx);
ctx.cache = cache;
static int
mail_cache_purge_write(struct mail_cache *cache,
struct mail_index_transaction *trans,
- int fd, const char *temp_path, bool *unlock)
+ int fd, const char *temp_path, const char *
+ reason, bool *unlock)
{
struct event *event;
struct stat st;
event_add_int(event, "prev_file_size", prev_file_size);
event_add_int(event, "prev_deleted_records", prev_deleted_records);
- if (mail_cache_copy(cache, trans, event, fd, &file_seq, &file_size,
- &max_uid, &ext_offsets) < 0)
+ if (mail_cache_copy(cache, trans, event, fd, reason,
+ &file_seq, &file_size, &max_uid, &ext_offsets) < 0)
return -1;
if (fstat(fd, &st) < 0) {
static int mail_cache_purge_locked(struct mail_cache *cache,
uint32_t purge_file_seq,
struct mail_index_transaction *trans,
- bool *unlock)
+ const char *reason, bool *unlock)
{
const char *temp_path;
int fd, ret;
fd = mail_index_create_tmp_file(cache->index, cache->filepath, &temp_path);
if (fd == -1)
return -1;
- if (mail_cache_purge_write(cache, trans, fd, temp_path, unlock) < 0) {
+ if (mail_cache_purge_write(cache, trans, fd, temp_path, reason, unlock) < 0) {
i_close_fd(&fd);
i_unlink(temp_path);
return -1;
static int
mail_cache_purge_full(struct mail_cache *cache,
struct mail_index_transaction *trans,
- uint32_t purge_file_seq)
+ uint32_t purge_file_seq, const char *reason)
{
bool unlock = FALSE;
int ret;
unlock = TRUE;
}
cache->purging = TRUE;
- ret = mail_cache_purge_locked(cache, purge_file_seq, trans, &unlock);
+ ret = mail_cache_purge_locked(cache, purge_file_seq, trans, reason, &unlock);
cache->purging = FALSE;
if (unlock)
mail_cache_unlock(cache);
int mail_cache_purge_with_trans(struct mail_cache *cache,
struct mail_index_transaction *trans,
- uint32_t purge_file_seq)
+ uint32_t purge_file_seq, const char *reason)
{
- return mail_cache_purge_full(cache, trans, purge_file_seq);
+ return mail_cache_purge_full(cache, trans, purge_file_seq, reason);
}
-int mail_cache_purge(struct mail_cache *cache, uint32_t purge_file_seq)
+int mail_cache_purge(struct mail_cache *cache, uint32_t purge_file_seq,
+ const char *reason)
{
struct mail_index_view *view;
struct mail_index_transaction *trans;
MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
if (ret < 0)
;
- else if ((ret = mail_cache_purge_full(cache, trans, purge_file_seq)) < 0)
+ else if ((ret = mail_cache_purge_full(cache, trans, purge_file_seq,
+ reason)) < 0)
mail_index_transaction_rollback(&trans);
else {
if (mail_index_transaction_commit(&trans) < 0)
}
static int
-mail_cache_transaction_purge(struct mail_cache_transaction_ctx *ctx)
+mail_cache_transaction_purge(struct mail_cache_transaction_ctx *ctx,
+ const char *reason)
{
struct mail_cache *cache = ctx->cache;
uint32_t purge_file_seq =
MAIL_CACHE_IS_UNUSABLE(cache) ? 0 : cache->hdr->file_seq;
- int ret = mail_cache_purge(cache, purge_file_seq);
+ int ret = mail_cache_purge(cache, purge_file_seq, reason);
/* already written cache records must be forgotten, but records in
memory can still be written to the new cache file */
mail_cache_transaction_forget_flushed(ctx, TRUE);
return -1;
if (!ctx->tried_purging) {
- if (mail_cache_transaction_purge(ctx) < 0)
+ if (mail_cache_transaction_purge(ctx, "creating cache") < 0)
return -1;
return mail_cache_transaction_lock(ctx);
} else {
if (cache->hdr->continued_record_count > 0 ||
cache->hdr->deleted_record_count > 0) {
mail_cache_unlock(cache);
- (void)mail_cache_transaction_purge(ctx);
+ (void)mail_cache_transaction_purge(ctx, "cache is too large");
return mail_cache_transaction_lock(ctx);
}
}