mail-index-write.c revision 39087f589d24f3072f220c2ed4528ee323f129ff
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2003-2015 Dovecot authors, see the included COPYING file */
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen/* if we're updating >= count-n messages, recreate the index */
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen#define MAIL_INDEX_MAX_OVERWRITE_NEG_SEQ_COUNT 10
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic int mail_index_create_backup(struct mail_index *index)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* we very much want to avoid creating a backup file that
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen hasn't been written to disk yet */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen mail_index_set_error(index, "fdatasync(%s) failed: %m",
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen backup_path = t_strconcat(index->filepath, ".backup", NULL);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen tmp_backup_path = t_strconcat(backup_path, ".tmp", NULL);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (unlink(tmp_backup_path) < 0 && errno != ENOENT) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_set_error(index, "unlink(%s) failed: %m",
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* no dovecot.index file, ignore */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mail_index_set_error(index, "link(%s, %s) failed: %m",
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (rename(tmp_backup_path, backup_path) < 0) {
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen mail_index_set_error(index, "rename(%s, %s) failed: %m",
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenstatic int mail_index_recreate(struct mail_index *index)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen fd = mail_index_create_tmp_file(index, index->filepath, &path);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen output = o_stream_create_fd_file(fd, 0, FALSE);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen base_size = I_MIN(map->hdr.base_header_size, sizeof(map->hdr));
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen o_stream_nsend(output, CONST_PTR_OFFSET(map->hdr_base, base_size),
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen map->rec_map->records_count * map->hdr.record_size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_file_set_syscall_error(index, path, "write()");
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (ret == 0 && index->fsync_mode != FSYNC_MODE_NEVER) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_file_set_syscall_error(index, path,
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen "fdatasync()");
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen mail_index_file_set_syscall_error(index, path, "close()");
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS) != 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0 && rename(path, index->filepath) < 0) {
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen mail_index_set_error(index, "rename(%s, %s) failed: %m",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_write(struct mail_index *index, bool want_rotate)
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen const struct mail_index_header *hdr = &map->hdr;
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen index->last_read_log_file_seq = hdr->log_file_seq;
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen index->last_read_log_file_head_offset = hdr->log_file_head_offset;
4b41116563110d00330896a568eff1078c382827Timo Sirainen index->last_read_log_file_tail_offset = hdr->log_file_tail_offset;
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen hdr->log_file_seq == index->log->head->hdr.file_seq &&
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen hdr->log_file_tail_offset == hdr->log_file_head_offset)