mail-index-private.h revision 45b0d8d0b97be14d10e3a3c12c169e4b352b2aac
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#ifndef MAIL_INDEX_PRIVATE_H
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_PRIVATE_H
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#include "file-lock.h"
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen#include "mail-index.h"
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#include "mail-index-util.h"
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#include "mail-index-view-private.h"
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#include "mail-index-transaction-private.h"
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#include <sys/stat.h>
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenstruct mail_transaction_header;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenstruct mail_transaction_log_view;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenstruct mail_index_sync_map_ctx;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen/* How large index files to mmap() instead of reading to memory. */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_MMAP_MIN_SIZE (1024*64)
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen/* How many times to retry opening index files if read/fstat returns ESTALE.
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen This happens with NFS when the file has been deleted (ie. index file was
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen rewritten by another computer than us). */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_ESTALE_RETRY_COUNT NFS_ESTALE_RETRY_COUNT
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen/* Large extension header sizes are probably caused by file corruption, so
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen try to catch them by limiting the header size. */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_EXT_HEADER_MAX_SIZE (1024*1024*16-1)
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen/* Write to main index file when bytes-to-be-read-from-log is between these
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen values. */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_MIN_WRITE_BYTES (1024*8)
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_MAX_WRITE_BYTES (1024*128)
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_IS_IN_MEMORY(index) \
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen ((index)->dir == NULL)
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen ((map)->rec_map->mmap_base == NULL)
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_MAP_IDX(map, idx) \
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen ((struct mail_index_record *) \
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen PTR_OFFSET((map)->rec_map->records, (idx) * (map)->hdr.record_size))
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_REC_AT_SEQ(map, seq) \
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen ((struct mail_index_record *) \
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen PTR_OFFSET((map)->rec_map->records, ((seq)-1) * (map)->hdr.record_size))
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u) \
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen ((((u)->add_flags | (u)->remove_flags) & MAIL_INDEX_FLAGS_MASK) == 0 && \
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen (u)->modseq_inc_flag == 0)
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen#define MAIL_INDEX_EXT_KEYWORDS "keywords"
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainentypedef int mail_index_expunge_handler_t(struct mail_index_sync_map_ctx *ctx,
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t seq, const void *data,
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen void **sync_context, void *context);
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainentypedef int mail_index_sync_handler_t(struct mail_index_sync_map_ctx *ctx,
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen uint32_t seq, void *old_data,
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen const void *new_data, void **context);
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainentypedef void mail_index_sync_lost_handler_t(struct mail_index *index);
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen#define MAIL_INDEX_HEADER_SIZE_ALIGN(size) \
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen (((size) + 7) & ~7)
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenstruct mail_index_ext {
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen const char *name;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t index_idx; /* index ext_id */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t reset_id;
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint32_t ext_offset; /* points to beginning of mail_index_ext_header */
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint32_t hdr_offset; /* points to mail_index_ext_header.data[] */
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint16_t record_offset;
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint16_t record_size;
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint16_t record_align;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen};
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainenstruct mail_index_ext_header {
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t hdr_size; /* size of data[] */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t reset_id;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint16_t record_offset;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint16_t record_size;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint16_t record_align;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint16_t name_size;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen /* unsigned char name[name_size] */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen /* unsigned char data[hdr_size] (starting 64bit aligned) */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen};
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenstruct mail_index_keyword_header {
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t keywords_count;
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen /* struct mail_index_keyword_header_rec[] */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen /* char name[][] */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen};
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainenstruct mail_index_keyword_header_rec {
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint32_t unused; /* for backwards compatibility */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t name_offset; /* relative to beginning of name[] */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen};
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenenum mail_index_sync_handler_type {
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen MAIL_INDEX_SYNC_HANDLER_FILE = 0x01,
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen MAIL_INDEX_SYNC_HANDLER_HEAD = 0x02,
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen MAIL_INDEX_SYNC_HANDLER_VIEW = 0x04
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen};
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenstruct mail_index_sync_handler {
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen mail_index_sync_handler_t *callback;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen enum mail_index_sync_handler_type type;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen};
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenstruct mail_index_registered_ext {
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen const char *name;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t index_idx; /* index ext_id */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint16_t record_size;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint16_t record_align;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index_sync_handler sync_handler;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen mail_index_expunge_handler_t *expunge_handler;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen void *expunge_context;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int expunge_handler_call_always:1;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen};
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenstruct mail_index_record_map {
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen ARRAY(struct mail_index_map *) maps;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen void *mmap_base;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen size_t mmap_size, mmap_used_size;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen buffer_t *buffer;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen void *records; /* struct mail_index_record[] */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int records_count;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index_map_modseq *modseq;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint32_t last_appended_uid;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen};
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenstruct mail_index_map {
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index *index;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen int refcount;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index_header hdr;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen const void *hdr_base;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen buffer_t *hdr_copy_buf;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen pool_t extension_pool;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen ARRAY(struct mail_index_ext) extensions;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen ARRAY(uint32_t) ext_id_map; /* index -> file */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen ARRAY(unsigned int) keyword_idx_map; /* file -> index */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index_record_map *rec_map;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen};
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenstruct mail_index_module_register {
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int id;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen};
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenunion mail_index_module_context {
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index_module_register *reg;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen};
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenstruct mail_index {
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen char *dir, *prefix;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_cache *cache;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_transaction_log *log;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int open_count;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen enum mail_index_open_flags flags;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen enum fsync_mode fsync_mode;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen enum mail_index_fsync_mask fsync_mask;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen mode_t mode;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen gid_t gid;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen char *gid_origin;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen pool_t extension_pool;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen ARRAY(struct mail_index_registered_ext) extensions;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint32_t ext_hdr_init_id;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen void *ext_hdr_init_data;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen ARRAY(mail_index_sync_lost_handler_t *) sync_lost_handlers;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen char *filepath;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen int fd;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index_map *map;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint32_t indexid;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int inconsistency_id;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen /* last_read_log_file_* contains the seq/offsets we last read from
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen the main index file's headers. these are used to figure out when
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen the main index file should be updated, and if we can update it
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen by writing on top of it or if we need to recreate it. */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint32_t last_read_log_file_seq;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen uint32_t last_read_log_file_head_offset;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t last_read_log_file_tail_offset;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen struct stat last_read_stat;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen /* transaction log head seq/offset when we last fscked */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t fsck_log_head_file_seq;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uoff_t fsck_log_head_file_offset;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen /* syncing will update this if non-NULL */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen struct mail_index_transaction_commit_result *sync_commit_result;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen enum file_lock_method lock_method;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen unsigned int max_lock_timeout_secs;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen pool_t keywords_pool;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen ARRAY_TYPE(keywords) keywords;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen HASH_TABLE(char *, void *) keywords_hash; /* name -> unsigned int idx */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint32_t keywords_ext_id;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t modseq_ext_id;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen struct mail_index_view *views;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* Module-specific contexts. */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen ARRAY(union mail_index_module_context *) module_contexts;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen char *error;
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen unsigned int nodiskspace:1;
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen unsigned int index_lock_timeout:1;
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int index_delete_requested:1; /* next sync sets it deleted */
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int index_deleted:1; /* no changes allowed anymore */
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen unsigned int log_sync_locked:1;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int readonly:1;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int mapping:1;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen unsigned int syncing:1;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen unsigned int need_recreate:1;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen unsigned int index_min_write:1;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int modseqs_enabled:1;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen unsigned int initial_create:1;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int initial_mapped:1;
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int fscked:1;
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen};
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenextern struct mail_index_module_register mail_index_module_register;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen/* Add/replace sync handler for specified extra record. */
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t ext_id, bool call_always,
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen mail_index_expunge_handler_t *callback,
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen void *context);
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen uint32_t ext_id);
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen mail_index_sync_handler_t *cb,
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainen enum mail_index_sync_handler_type type);
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen uint32_t ext_id);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen mail_index_sync_lost_handler_t *cb);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen mail_index_sync_lost_handler_t *cb);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_create_tmp_file(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char *path_prefix, const char **path_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_try_open_only(struct mail_index *index);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_close_file(struct mail_index *index);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_reopen_if_changed(struct mail_index *index);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Update/rewrite the main index file from index->map */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_write(struct mail_index *index, bool want_rotate);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_flush_read_cache(struct mail_index *index, const char *path,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen int fd, bool locked);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen int lock_type, unsigned int timeout_secs,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen struct file_lock **lock_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Allocate a new empty map. */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenstruct mail_index_map *mail_index_map_alloc(struct mail_index *index);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Replace index->map with the latest index changes. This may reopen the index
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen file and/or it may read the latest changes from transaction log. The log is
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen read up to EOF, but non-synced expunges are skipped.
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen If we mmap()ed the index file, the map is returned locked.
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen Returns 1 = ok, 0 = corrupted, -1 = error. */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_map(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen enum mail_index_sync_handler_type type);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Unreference given mapping and unmap it if it's dropped to zero. */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_unmap(struct mail_index_map **map);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Clone a map. The returned map is always in memory. */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenstruct mail_index_map *mail_index_map_clone(const struct mail_index_map *map);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_record_map_move_to_private(struct mail_index_map *map);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Move a mmaped map to memory. */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_map_move_to_memory(struct mail_index_map *map);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_fchown(struct mail_index *index, int fd, const char *path);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenbool mail_index_map_lookup_ext(struct mail_index_map *map, const char *name,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen uint32_t *idx_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenuint32_t
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenmail_index_map_register_ext(struct mail_index_map *map,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char *name, uint32_t ext_offset,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const struct mail_index_ext_header *ext_hdr);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenbool mail_index_map_get_ext_idx(struct mail_index_map *map,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen uint32_t ext_id, uint32_t *idx_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenconst struct mail_index_ext *
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenmail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_map_lookup_seq_range(struct mail_index_map *map,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen uint32_t first_uid, uint32_t last_uid,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen uint32_t *first_seq_r,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen uint32_t *last_seq_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Returns 1 on success, 0 on non-critical errors we want to silently fix,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen -1 if map isn't usable. The caller is responsible for logging the errors
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen if -1 is returned. */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_map_check_header(struct mail_index_map *map,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char **error_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* Returns 1 if header is usable, 0 or -1 if not. The caller should log an
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen error if -1 is returned, but not if 0 is returned. */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenbool mail_index_check_header_compat(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const struct mail_index_header *hdr,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen uoff_t file_size, const char **error_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_map_parse_extensions(struct mail_index_map *map);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_map_parse_keywords(struct mail_index_map *map);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_map_init_extbufs(struct mail_index_map *map,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen unsigned int initial_count);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_map_ext_get_next(struct mail_index_map *map,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen unsigned int *offset,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const struct mail_index_ext_header **ext_hdr_r,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char **name_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenint mail_index_map_ext_hdr_check(const struct mail_index_header *hdr,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const struct mail_index_ext_header *ext_hdr,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char *name, const char **error_r);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenunsigned int mail_index_map_ext_hdr_offset(unsigned int name_len);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_fsck_locked(struct mail_index *index);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_set_error(struct mail_index *index, const char *fmt, ...)
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen ATTR_FORMAT(2, 3);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* "%s failed with index file %s: %m" */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_set_syscall_error(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char *function);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen/* "%s failed with file %s: %m" */
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainenvoid mail_index_file_set_syscall_error(struct mail_index *index,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char *filepath,
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen const char *function);
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen#endif
2bd2ca14d18819b77201ab2b46910d9ae6858abeTimo Sirainen