mail-transaction-log-private.h revision 8e361d2906b0e44f7175a20981f8d2280645b58b
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen#ifndef MAIL_TRANSACTION_LOG_VIEW_H
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#define MAIL_TRANSACTION_LOG_VIEW_H
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "buffer.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "file-dotlock.h"
3343a61404603b21c246783a7963b77833095f31Timo Sirainen#include "mail-transaction-log.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen/* Synchronization can take a while sometimes, especially when copying lots of
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mails. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#define MAIL_TRANSCATION_LOG_LOCK_TIMEOUT (3*60)
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen#define MAIL_TRANSCATION_LOG_LOCK_CHANGE_TIMEOUT (3*60)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen/* Rotate when log is older than ROTATE_TIME and larger than MIN_SIZE */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#define MAIL_TRANSACTION_LOG_ROTATE_MIN_SIZE (1024*32)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen/* If log is larger than MAX_SIZE, rotate regardless of the time */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#define MAIL_TRANSACTION_LOG_ROTATE_MAX_SIZE (1024*1024)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#define MAIL_TRANSACTION_LOG_ROTATE_TIME (60*5)
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen/* Delete .log.2 files older than this many seconds */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen#define MAIL_TRANSACTION_LOG2_STALE_SECS (60*30)
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen#define MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file) ((file)->fd == -1)
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen#define LOG_FILE_MODSEQ_CACHE_SIZE 10
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstruct modseq_cache {
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uoff_t offset;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uint64_t highest_modseq;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen};
3f190f4cbb9233a3a6830956cb5c7ae56a577b79Timo Sirainen
3f190f4cbb9233a3a6830956cb5c7ae56a577b79Timo Sirainenstruct mail_transaction_log_file {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct mail_transaction_log *log;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct mail_transaction_log_file *next;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* refcount=0 is a valid state. files start that way, and they're
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen freed only when mail_transaction_logs_clean() is called. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen int refcount;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen char *filepath;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen int fd;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ino_t st_ino;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen dev_t st_dev;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen time_t last_mtime;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uoff_t last_size;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct mail_transaction_log_header hdr;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen buffer_t mmap_buffer;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen buffer_t *buffer;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uoff_t buffer_offset;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen void *mmap_base;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen size_t mmap_size;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* points to the next uncommitted transaction. usually same as EOF. */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uoff_t sync_offset;
0d16525a729011f4fced989a3da74d755ea49e6dTimo Sirainen /* highest modseq at sync_offset */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uint64_t sync_highest_modseq;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* saved_tail_offset is the offset that was last written to transaction
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen log. max_tail_offset is what should be written to the log the next
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen time a transaction is written. transaction log handling may update
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen max_tail_offset automatically by making it skip external transactions
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen after the last saved offset (to avoid re-reading them unneededly). */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uoff_t saved_tail_offset, max_tail_offset;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* don't give warnings about saved_tail_offset shrinking if
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen sync_offset is less than this. */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen uoff_t saved_tail_sync_offset;
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen struct modseq_cache modseq_cache[LOG_FILE_MODSEQ_CACHE_SIZE];
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen struct file_lock *file_lock;
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen unsigned int locked:1;
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen unsigned int corrupted:1;
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen};
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainenstruct mail_transaction_log {
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen struct mail_index *index;
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen struct mail_transaction_log_view *views;
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen /* files is a linked list of all the opened log files. the list is
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen sorted by the log file sequence, so that transaction views can use
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen them easily. head contains a pointer to the newest log file. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct mail_transaction_log_file *files, *head;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* open_file is used temporarily while opening the log file.
ed63764502561bbeb12fe03878fb33a82b89bf27Timo Sirainen if _open() failed, it's left there for _create(). */
ed63764502561bbeb12fe03878fb33a82b89bf27Timo Sirainen struct mail_transaction_log_file *open_file;
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen unsigned int dotlock_count;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct dotlock_settings dotlock_settings, new_dotlock_settings;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct dotlock *dotlock;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen};
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenvoid
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenmail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen const char *fmt, ...)
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen ATTR_FORMAT(2, 3);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen
c5d71ca49b93e18ffbf197d89239d63678e881d7Timo Sirainenstruct mail_transaction_log_file *
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenmail_transaction_log_file_alloc_in_memory(struct mail_transaction_log *log);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenstruct mail_transaction_log_file *
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenmail_transaction_log_file_alloc(struct mail_transaction_log *log,
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen const char *path);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenvoid mail_transaction_log_file_free(struct mail_transaction_log_file **file);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenint mail_transaction_log_file_open(struct mail_transaction_log_file *file,
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen bool check_existing);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenint mail_transaction_log_file_create(struct mail_transaction_log_file *file,
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen bool reset);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenint mail_transaction_log_file_lock(struct mail_transaction_log_file *file);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenint mail_transaction_log_find_file(struct mail_transaction_log *log,
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen uint32_t file_seq, bool nfs_flush,
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen struct mail_transaction_log_file **file_r);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen/* Returns 1 if ok, 0 if file is corrupted or offset range is invalid,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen -1 if I/O error */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenint mail_transaction_log_file_map(struct mail_transaction_log_file *file,
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen uoff_t start_offset, uoff_t end_offset);
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainenvoid mail_transaction_log_file_move_to_memory(struct mail_transaction_log_file
0a601ada15c7fe82f0db895fc2068b71b3a5243cTimo Sirainen *file);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenvoid mail_transaction_logs_clean(struct mail_transaction_log *log);
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenbool mail_transaction_log_want_rotate(struct mail_transaction_log *log);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenint mail_transaction_log_rotate(struct mail_transaction_log *log, bool reset);
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainenint mail_transaction_log_lock_head(struct mail_transaction_log *log);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenvoid mail_transaction_log_file_unlock(struct mail_transaction_log_file *file);
424236b2b88a5a7bbde5cf6a6b32189ca3437629Timo Sirainen
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainenbool
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenmail_transaction_header_has_modseq(const struct mail_transaction_header *hdr,
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen const void *data,
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainen uint64_t cur_modseq);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenint mail_transaction_log_file_get_highest_modseq_at(
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen struct mail_transaction_log_file *file,
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen uoff_t offset, uint64_t *highest_modseq_r);
1b5366b2234892f8930a29351da06b193e385150Timo Sirainenint mail_transaction_log_file_get_modseq_next_offset(
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen struct mail_transaction_log_file *file,
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen uint64_t modseq, uoff_t *next_offset_r);
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen#endif
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen