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