mail-index-compress.c revision 742111fa99a5b852c9645080573d5853be3907a7
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "write-full.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-index.h"
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen#include "mail-index-data.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-index-util.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-tree.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <stdio.h>
c99fe55d4535d839a6ad0735c4719e076a1adb2cTimo Sirainen#include <unistd.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint mail_index_truncate(struct mail_index *index)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uoff_t empty_space, truncate_threshold;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (index->mmap_full_length <= INDEX_FILE_MIN_SIZE || index->anon_mmap)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* really truncate the file only when it's almost empty */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen empty_space = index->mmap_full_length - index->mmap_used_length;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen truncate_threshold =
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->mmap_full_length / 100 * INDEX_TRUNCATE_PERCENTAGE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (empty_space > truncate_threshold) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->mmap_full_length = index->mmap_used_length +
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen (empty_space * INDEX_TRUNCATE_KEEP_PERCENTAGE / 100);
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* keep the size record-aligned */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index->mmap_full_length -= (index->mmap_full_length -
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen sizeof(struct mail_index_header)) %
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen sizeof(struct mail_index_record);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (index->mmap_full_length < INDEX_FILE_MIN_SIZE)
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen index->mmap_full_length = INDEX_FILE_MIN_SIZE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (ftruncate(index->fd, (off_t)index->mmap_full_length) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return index_set_syscall_error(index, "ftruncate()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->header->sync_id++;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint mail_index_compress(struct mail_index *index)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_index_record *rec, *hole_rec, *end_rec;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int idx;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int tree_fd;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (index->header->first_hole_records == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* we don't need to compress after all. shouldn't happen.. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->header->flags &= ~MAIL_INDEX_FLAG_COMPRESS;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!mail_index_verify_hole_range(index))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* if we get interrupted, the whole index is probably corrupted.
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen so keep rebuild-flag on while doing this */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->header->flags |= MAIL_INDEX_FLAG_REBUILD;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!mail_index_fmdatasync(index, sizeof(struct mail_index_header)))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* first actually compress the data */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen hole_rec = INDEX_RECORD_AT(index, index->header->first_hole_index);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen end_rec = INDEX_END_RECORD(index);
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen rec = hole_rec + index->header->first_hole_records;
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen while (rec < end_rec) {
0c22bef8f5b35c645de8affd8746307fc53bd222Timo Sirainen if (rec->uid != 0) {
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen memcpy(hole_rec, rec, sizeof(struct mail_index_record));
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen idx = INDEX_RECORD_INDEX(index, hole_rec);
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen if (!mail_tree_update(index->tree, rec->uid, idx))
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen return FALSE;
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen hole_rec++;
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen }
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen rec++;
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* truncate the file to get rid of the extra records */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->mmap_used_length = (size_t) ((char *) hole_rec -
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (char *) index->mmap_base);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->header->used_file_size = index->mmap_used_length;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!mail_index_truncate(index))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* update headers */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->header->first_hole_index = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->header->first_hole_records = 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* make sure the whole file is synced before removing rebuild-flag */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (!mail_tree_sync_file(index->tree, &tree_fd))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainen if (fdatasync(tree_fd) < 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index_file_set_syscall_error(index, index->tree->filepath,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "fdatasync()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!mail_index_fmdatasync(index, index->mmap_used_length))
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index->header->flags &= ~(MAIL_INDEX_FLAG_COMPRESS |
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MAIL_INDEX_FLAG_REBUILD);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return TRUE;
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen}
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainen
78fa3c578c14ee8a612f86cf73b6181c7f16463fTimo Sirainenstatic int mail_index_copy_data(struct mail_index *index,
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen int fd, const char *path)
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen{
7487ff578435377bbeefffdbfb78ca09ed1292dfTimo Sirainen struct mail_index_data_header data_hdr;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_index_data_record_header *rec_hdr;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct mail_index_record *rec;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned char *mmap_data;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen size_t mmap_data_size;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen uoff_t offset;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mmap_data = mail_index_data_get_mmaped(index->data, &mmap_data_size);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (mmap_data == NULL)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* write data header */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen memset(&data_hdr, 0, sizeof(data_hdr));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen data_hdr.indexid = index->indexid;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (write_full(fd, &data_hdr, sizeof(data_hdr)) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index_file_set_syscall_error(index, path, "write_full()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* now we'll begin the actual moving. keep rebuild-flag on
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen while doing it. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index->header->flags |= MAIL_INDEX_FLAG_REBUILD;
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen if (!mail_index_fmdatasync(index, sizeof(struct mail_index_header)))
c6335901c67a4c9365319190a111a2168f3b06f5Timo Sirainen return FALSE;
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen offset = sizeof(data_hdr);
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen rec = index->lookup(index, 1);
6d2b3ce2c6ef62334985ece4f0ab8b154e0e9560Timo Sirainen while (rec != NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (rec->data_position + sizeof(*rec_hdr) > mmap_data_size) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index_set_corrupted(index,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "data_position points outside file");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rec_hdr = (struct mail_index_data_record_header *)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (mmap_data + rec->data_position);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (rec->data_position + rec_hdr->data_size > mmap_data_size) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index_set_corrupted(index,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "data_size points outside file");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (write_full(fd, mmap_data + rec->data_position,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rec_hdr->data_size) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index_file_set_syscall_error(index, path,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "write_full()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rec->data_position = offset;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen offset += rec_hdr->data_size;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen rec = index->next(index, rec);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* update header */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen data_hdr.used_file_size = offset;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (lseek(fd, 0, SEEK_SET) < 0)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return index_file_set_syscall_error(index, path, "lseek()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (write_full(fd, &data_hdr, sizeof(data_hdr)) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index_file_set_syscall_error(index, path, "write_full()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint mail_index_compress_data(struct mail_index *index)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const char *temppath, *datapath;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen int fd, failed;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (index->anon_mmap)
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen return TRUE;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen /* write the data into temporary file updating the offsets in index
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen while doing it. if we fail (especially if out of disk space/quota)
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen we'll simply fail and index is rebuilt later */
17fe695b985e9d6e9dc39c05b24e6b3c3b7e1ba1Timo Sirainen if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd = mail_index_create_temp_file(index, &temppath);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (fd == -1)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen failed = !mail_index_copy_data(index, fd, temppath);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (fdatasync(fd) < 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen index_file_set_syscall_error(index, temppath, "fdatasync()");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen failed = TRUE;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (close(fd) < 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index_file_set_syscall_error(index, temppath, "close()");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen failed = TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!failed) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* now, rename the temp file to new data file. but before that
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen reset indexid to make sure that other processes know the
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen data file is closed. */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen (void)mail_index_data_mark_file_deleted(index->data);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_index_data_free(index->data);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen datapath = t_strconcat(index->filepath, DATA_FILE_PREFIX, NULL);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (rename(temppath, datapath) < 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (ENOSPACE(errno))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index->nodiskspace = TRUE;
7f13786e6a18a846376e46d77349528d99935871Timo Sirainen
7f13786e6a18a846376e46d77349528d99935871Timo Sirainen index_set_error(index, "rename(%s, %s) failed: %m",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen temppath, datapath);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen failed = TRUE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (failed) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (unlink(temppath) < 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index_file_set_syscall_error(index, temppath,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "unlink()");
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen }
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* make sure the whole file is synced before removing rebuild-flag */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!mail_index_fmdatasync(index, index->mmap_used_length))
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return FALSE;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen index->header->flags &= ~(MAIL_INDEX_FLAG_COMPRESS_DATA |
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen MAIL_INDEX_FLAG_REBUILD);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return mail_index_data_open(index);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen}
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen