mail-transaction-log.c revision 6f807c51cc3715884a3d12f25969f0b71eb5bf3b
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (C) 2003-2007 Timo Sirainen */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen/* this lock should never exist for a long time.. */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenmail_transaction_log_set_head(struct mail_transaction_log *log,
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen i_assert(log->files->next != NULL || log->files == file);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenmail_transaction_log_alloc(struct mail_index *index)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen log->dotlock_settings.use_excl_lock = index->use_excl_dotlocks;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen log->dotlock_settings.timeout = LOG_DOTLOCK_TIMEOUT;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen log->dotlock_settings.stale_timeout = LOG_DOTLOCK_STALE_TIMEOUT;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen log->new_dotlock_settings = log->dotlock_settings;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen log->new_dotlock_settings.lock_suffix = LOG_NEW_DOTLOCK_SUFFIX;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenstatic void mail_transaction_log_2_unlink_old(struct mail_transaction_log *log)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (st.st_mtime + MAIL_TRANSACTION_LOG2_STALE_SECS <= ioloop_time) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenint mail_transaction_log_open(struct mail_transaction_log *log)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_transaction_log_file_free(&log->open_file);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen file = mail_transaction_log_file_alloc(log, path);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if ((ret = mail_transaction_log_file_open(file, FALSE)) <= 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* leave the file for _create() */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenint mail_transaction_log_create(struct mail_transaction_log *log)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen file = mail_transaction_log_file_alloc_in_memory(log);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen file = mail_transaction_log_file_alloc(log, path);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen /* remember what file we tried to open. if someone else created
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen a new file, use it instead of recreating it */
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen file->last_mtime = log->open_file->last_mtime;
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_transaction_log_file_free(&log->open_file);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen if (mail_transaction_log_file_create(file, FALSE) < 0) {
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_transaction_log_close(struct mail_transaction_log *log)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_transaction_log_file_free(&log->open_file);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_transaction_log_free(struct mail_transaction_log **_log)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_transaction_log_move_to_memory(struct mail_transaction_log *log)
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainen mail_transaction_log_file_move_to_memory(log->head);
0c17af9d3f9323136a94e66605776ed4462a172dTimo Sirainenvoid mail_transaction_log_indexid_changed(struct mail_transaction_log *log)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (file = log->files; file != NULL; file = file->next) {
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen if (file->hdr.indexid != log->index->indexid) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "indexid changed: %u -> %u",
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen log->head->hdr.indexid != log->index->indexid) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_transaction_logs_clean(struct mail_transaction_log *log)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_file *file, *next;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (file = log->files; file != NULL; file = next) {
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen i_assert(log->head == NULL || log->files != NULL);
b9b48aaaebf6f72dfab567cda073cde8a7b26598Timo Sirainen (((file)->sync_offset > MAIL_TRANSACTION_LOG_ROTATE_MIN_SIZE && \
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen ioloop_time - MAIL_TRANSACTION_LOG_ROTATE_TIME) || \
992a9e2d6c6ee45d87089ac54267e0198a7802c3Timo Sirainen ((file)->sync_offset > MAIL_TRANSACTION_LOG_ROTATE_MAX_SIZE))
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenbool mail_transaction_log_want_rotate(struct mail_transaction_log *log)
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainenint mail_transaction_log_rotate(struct mail_transaction_log *log, bool reset)
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen file = mail_transaction_log_file_alloc_in_memory(log);
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen /* we're locked, we shouldn't need to worry about ESTALE
6bf1543bb7af03324c04e8f9ac8e430f395989aeTimo Sirainen problems in here. */
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen file = mail_transaction_log_file_alloc(log, path);
44dc970b18c4e2d06f34cb908924152156e4a45bTimo Sirainen if (mail_transaction_log_file_create(file, reset) < 0) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic int mail_transaction_log_refresh(struct mail_transaction_log *log)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(log->head))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_file_set_syscall_error(log->index, path,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* the file should always exist at this point. if it doesn't,
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen someone deleted it manually while the index was open. try to
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen handle this nicely by creating a new log file. */
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainen /* same file */
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen file = mail_transaction_log_file_alloc(log, path);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen if (mail_transaction_log_file_open(file, FALSE) <= 0) {
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenvoid mail_transaction_log_get_mailbox_sync_pos(struct mail_transaction_log *log,
4b43f50117630aa12b3cfd0cbd05ae22ba27fec1Timo Sirainenvoid mail_transaction_log_set_mailbox_sync_pos(struct mail_transaction_log *log,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen i_assert(file_seq == log->head->hdr.file_seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(file_offset >= log->head->saved_tail_offset);
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainen if (file_offset >= log->head->max_tail_offset)
6925fd9cd70c30884406d50f1d85efb6561e776cTimo Sirainenint mail_transaction_log_find_file(struct mail_transaction_log *log,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen /* see if the .log file has been recreated */
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen /* transaction log is locked. there's no way a newer
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen file exists. */
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen for (file = log->files; file != NULL; file = file->next) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* see if we have it in log.2 file */
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen file = mail_transaction_log_file_alloc(log, path);
b66a7b7ab0db2c9ad425912d3f21a36fcf76d876Timo Sirainen if ((ret = mail_transaction_log_file_open(file, TRUE)) <= 0)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen /* but is it what we expected? */
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainenint mail_transaction_log_lock_head(struct mail_transaction_log *log)
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen /* we want to get the head file locked. this is a bit racy,
4dc8837ab37c1a606add1067e21ed868754db4e3Timo Sirainen since by the time we have it locked a new log file may have been
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen creating new log file requires locking the head file, so if we
8e5fedd9ada47735be8ac0f8af2a66e8528bd776Timo Sirainen can lock it and don't see another file, we can be sure no-one is
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen creating a new log at the moment */
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen /* success */
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainen /* try again */
d77c309fccbc6a7594f8cb08fb01009fa613c568Timo Sirainenint mail_transaction_log_sync_lock(struct mail_transaction_log *log,
7bd6001d84ecc1792ddfd54fe8efa63c509d90b1Timo Sirainen /* update sync_offset */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_file_map(log->head, log->head->sync_offset,
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainenvoid mail_transaction_log_sync_unlock(struct mail_transaction_log *log)
d61a5e0e4ff58d1aa613f0d51161e5bb0f092514Timo Sirainenvoid mail_transaction_log_get_head(struct mail_transaction_log *log,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenbool mail_transaction_log_is_head_prev(struct mail_transaction_log *log,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return log->head->hdr.prev_file_seq == file_seq &&