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