mail-transaction-log-private.h revision 2f8da04d700cc23fcd6630226a4866e828b761bd
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef MAIL_TRANSACTION_LOG_VIEW_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define MAIL_TRANSACTION_LOG_VIEW_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-transaction-log.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bdd7a96c363346f7c38f389791be1487ca08775bTimo Sirainenstruct dotlock_settings;
bdd7a96c363346f7c38f389791be1487ca08775bTimo Sirainen
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen/* Synchronization can take a while sometimes, especially when copying lots of
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen mails. */
97cb20eb77d486ef67eac50567e3080faca025c1Timo Sirainen#define MAIL_TRANSACTION_LOG_LOCK_TIMEOUT (3*60)
97cb20eb77d486ef67eac50567e3080faca025c1Timo Sirainen#define MAIL_TRANSACTION_LOG_LOCK_CHANGE_TIMEOUT (3*60)
cc833a7a4e2258afdc834ace4bfe6579820a1df3Timo Sirainen
7e235b3a5f622813121cd18f351e036650aaf8f8Timo Sirainen/* Rotate when log is older than ROTATE_TIME and larger than MIN_SIZE */
366eb7178f2c90d97134e0c2d1958f93fcdaba12Timo Sirainen#define MAIL_TRANSACTION_LOG_ROTATE_MIN_SIZE (1024*32)
7e235b3a5f622813121cd18f351e036650aaf8f8Timo Sirainen/* If log is larger than MAX_SIZE, rotate regardless of the time */
7e235b3a5f622813121cd18f351e036650aaf8f8Timo Sirainen#define MAIL_TRANSACTION_LOG_ROTATE_MAX_SIZE (1024*1024)
fadd878cd6098f5b873c21c121209a922679dae4Timo Sirainen#define MAIL_TRANSACTION_LOG_ROTATE_TIME (60*5)
fadd878cd6098f5b873c21c121209a922679dae4Timo Sirainen
863ea896fb31a16d1baec31e57650243b5547db6Timo Sirainen/* Delete .log.2 files older than this many seconds. Don't be too eager,
863ea896fb31a16d1baec31e57650243b5547db6Timo Sirainen older files are useful for QRESYNC and dsync. */
863ea896fb31a16d1baec31e57650243b5547db6Timo Sirainen#define MAIL_TRANSACTION_LOG2_STALE_SECS (60*60*24*2)
471e447023ab73a73f0f78da2afc0c55905330ddTimo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen#define MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file) ((file)->fd == -1)
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen#define LOG_FILE_MODSEQ_CACHE_SIZE 10
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenstruct modseq_cache {
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen uoff_t offset;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen uint64_t highest_modseq;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen};
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_log_file {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log *log;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_file *next;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen /* refcount=0 is a valid state. files start that way, and they're
bbce20cb4e5739e9a06058cf8ee1f38a7f6884f6Timo Sirainen freed only when mail_transaction_logs_clean() is called. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int refcount;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char *filepath;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ino_t st_ino;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dev_t st_dev;
55a210942dc7da58b2fd0b11bed8da6b030af5c1Timo Sirainen time_t last_mtime;
fc7b17677ac1a5fa3f7fe13d5ef7dcfea8d9b4a1Timo Sirainen uoff_t last_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_transaction_log_header hdr;
8e361d2906b0e44f7175a20981f8d2280645b58bTimo Sirainen buffer_t mmap_buffer;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_t *buffer;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t buffer_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen void *mmap_base;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t mmap_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* points to the next uncommitted transaction. usually same as EOF. */
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen uoff_t sync_offset;
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen /* highest modseq at sync_offset */
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen uint64_t sync_highest_modseq;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen /* saved_tail_offset is the offset that was last written to transaction
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen log. max_tail_offset is what should be written to the log the next
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen time a transaction is written. transaction log handling may update
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen max_tail_offset automatically by making it skip external transactions
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen after the last saved offset (to avoid re-reading them unneededly). */
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen uoff_t saved_tail_offset, max_tail_offset;
88b8aea03a24ef7a9efc30399080487b7eb03537Timo Sirainen /* don't give warnings about saved_tail_offset shrinking if
88b8aea03a24ef7a9efc30399080487b7eb03537Timo Sirainen sync_offset is less than this. */
88b8aea03a24ef7a9efc30399080487b7eb03537Timo Sirainen uoff_t saved_tail_sync_offset;
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen /* if we've seen _INDEX_[UN9DELETED transaction in this file,
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen this is the offset. otherwise (uoff_t)-1 */
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen uoff_t index_deleted_offset, index_undeleted_offset;
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen struct modseq_cache modseq_cache[LOG_FILE_MODSEQ_CACHE_SIZE];
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen struct file_lock *file_lock;
d9fda7e3a0fa5551547ac3e3054b837fc77f4bfbTimo Sirainen time_t lock_created;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen unsigned int locked:1;
07e80e04c8876b6bf3f95266f48b41e1a681e445Timo Sirainen unsigned int locked_sync_offset_updated:1;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen unsigned int corrupted:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_log {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index *index;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_view *views;
029cfcdce65b284d5230adf1c920a5f526b03b5cTimo Sirainen char *filepath, *filepath2;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
45e62043058738e294f89504c319d852e25943ccTimo Sirainen /* files is a linked list of all the opened log files. the list is
45e62043058738e294f89504c319d852e25943ccTimo Sirainen sorted by the log file sequence, so that transaction views can use
45e62043058738e294f89504c319d852e25943ccTimo Sirainen them easily. head contains a pointer to the newest log file. */
45e62043058738e294f89504c319d852e25943ccTimo Sirainen struct mail_transaction_log_file *files, *head;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* open_file is used temporarily while opening the log file.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if _open() failed, it's left there for _create(). */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_transaction_log_file *open_file;
d5960ce1c0adda5c9e259bc429123ebc29c60baeTimo Sirainen
d5960ce1c0adda5c9e259bc429123ebc29c60baeTimo Sirainen unsigned int dotlock_count;
13c6532dc104d23061e6901783ceb1ff8872c206Timo Sirainen struct dotlock *dotlock;
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen unsigned int nfs_flush:1;
96975ce7b258b4ed09040bd1dc9a453106dee581Timo Sirainen unsigned int log_2_unlink_checked:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
6eb30032b4a50c383dea4c9c74342d906de6ad36Timo Sirainen const char *fmt, ...)
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen ATTR_FORMAT(2, 3);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bdd7a96c363346f7c38f389791be1487ca08775bTimo Sirainenvoid mail_transaction_log_get_dotlock_set(struct mail_transaction_log *log,
bdd7a96c363346f7c38f389791be1487ca08775bTimo Sirainen struct dotlock_settings *set_r);
bdd7a96c363346f7c38f389791be1487ca08775bTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstruct mail_transaction_log_file *
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenmail_transaction_log_file_alloc_in_memory(struct mail_transaction_log *log);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenstruct mail_transaction_log_file *
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenmail_transaction_log_file_alloc(struct mail_transaction_log *log,
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen const char *path);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_transaction_log_file_free(struct mail_transaction_log_file **file);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
b222354c9553cd60b7dd418885e10c0473f73985Timo Sirainenint mail_transaction_log_file_open(struct mail_transaction_log_file *file);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenint mail_transaction_log_file_create(struct mail_transaction_log_file *file,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen bool reset);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainenint mail_transaction_log_file_lock(struct mail_transaction_log_file *file);
4bc96ba6f1d67a90a75fa131bcd2cd508ea5a05aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_transaction_log_find_file(struct mail_transaction_log *log,
f537e7efaec891d6b3320ca94331d09ca8c4a4dbTimo Sirainen uint32_t file_seq, bool nfs_flush,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_file **file_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen/* Returns 1 if ok, 0 if file is corrupted or offset range is invalid,
2e99f3f3bb35715ce5e0a75a2f2a9bac3ab4224bTimo Sirainen -1 if I/O error */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_transaction_log_file_map(struct mail_transaction_log_file *file,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t start_offset, uoff_t end_offset);
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainenvoid mail_transaction_log_file_move_to_memory(struct mail_transaction_log_file
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainen *file);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_transaction_logs_clean(struct mail_transaction_log *log);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenbool mail_transaction_log_want_rotate(struct mail_transaction_log *log);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenint mail_transaction_log_rotate(struct mail_transaction_log *log, bool reset);
b87a4156eca6dcf6b29c504eb0cb9be2fdb11b63Timo Sirainenint mail_transaction_log_lock_head(struct mail_transaction_log *log);
2f8da04d700cc23fcd6630226a4866e828b761bdTimo Sirainenvoid mail_transaction_log_file_unlock(struct mail_transaction_log_file *file,
2f8da04d700cc23fcd6630226a4866e828b761bdTimo Sirainen const char *lock_reason);
b87a4156eca6dcf6b29c504eb0cb9be2fdb11b63Timo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainenvoid mail_transaction_update_modseq(const struct mail_transaction_header *hdr,
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen const void *data, uint64_t *cur_modseq);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenint mail_transaction_log_file_get_highest_modseq_at(
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen struct mail_transaction_log_file *file,
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen uoff_t offset, uint64_t *highest_modseq_r);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenint mail_transaction_log_file_get_modseq_next_offset(
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen struct mail_transaction_log_file *file,
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen uint64_t modseq, uoff_t *next_offset_r);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#endif