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