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