mail-index-private.h revision 1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#ifndef __MAIL_INDEX_PRIVATE_H
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#define __MAIL_INDEX_PRIVATE_H
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Make sure F_RDLCK, F_WRLCK and F_UNLCK get defined */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#include <unistd.h>
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#include <fcntl.h>
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#include "file-dotlock.h"
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#include "mail-index.h"
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_transaction_header;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_index_sync_map_ctx;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* How many seconds to wait a lock for index file. */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#define MAIL_INDEX_LOCK_SECS 120
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Index file is grown exponentially when we're adding less than this many
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano records. */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#define MAIL_INDEX_MAX_POWER_GROW (1024*1024 / sizeof(struct mail_index_record))
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* How many times to retry opening index files if read/fstat returns ESTALE.
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano This happens with NFS when the file has been deleted (ie. index file was
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano rewritten by another computer than us). */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#define MAIL_INDEX_ESTALE_RETRY_COUNT 10
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano ((map)->buffer != NULL)
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand#define MAIL_INDEX_MAP_IDX(map, idx) \
10fba81b9d0221b8e47aa1e0b43236413b7d28dfMichel Normand ((struct mail_index_record *) \
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand PTR_OFFSET((map)->records, (idx) * (map)->hdr.record_size))
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normand
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanotypedef int mail_index_expunge_handler_t(struct mail_index_sync_map_ctx *ctx,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t seq, const void *data,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano void **context);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanotypedef int mail_index_sync_handler_t(struct mail_index_sync_map_ctx *ctx,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t seq, void *old_data,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano const void *new_data, void **context);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#define MAIL_INDEX_HEADER_SIZE_ALIGN(size) \
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano (((size) + 7) & ~7)
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_index_ext {
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano const char *name;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t reset_id;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t hdr_offset;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t hdr_size;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint16_t record_offset;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint16_t record_size;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint16_t record_align;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano};
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_index_ext_header {
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t hdr_size;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t reset_id;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint16_t record_offset;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint16_t record_size;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint16_t record_align;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint16_t name_size;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano /* unsigned char name[] */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano};
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_index_map {
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano int refcount;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano struct mail_index_header hdr;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano const void *hdr_base;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano void *records; /* struct mail_index_record[] */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int records_count;
10fba81b9d0221b8e47aa1e0b43236413b7d28dfMichel Normand
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano pool_t extension_pool;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano buffer_t *extensions; /* struct mail_index_ext[] */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano buffer_t *ext_id_map; /* uint32_t[] (index -> file) */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano void *mmap_base;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano size_t mmap_size, mmap_used_size;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano buffer_t *buffer;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano buffer_t *hdr_copy_buf;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int write_to_disk:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano};
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_index {
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano char *dir, *prefix;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano struct mail_cache *cache;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano struct mail_transaction_log *log;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mode_t mode;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano gid_t gid;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano pool_t extension_pool;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano buffer_t *extensions; /* struct mail_index_ext[] */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano buffer_t *expunge_handlers; /* mail_index_expunge_handler_t*[] */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano buffer_t *sync_handlers; /* mail_index_sync_handler_t*[] */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano char *filepath;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano int fd;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano struct mail_index_map *map;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano const struct mail_index_header *hdr;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t indexid;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano int lock_type, shared_lock_count, excl_lock_count;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int lock_id;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano char *copy_lock_path;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano struct dotlock dotlock;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano enum mail_index_lock_method lock_method;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int last_grow_count;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano char *error;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int nodiskspace:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int index_lock_timeout:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int opened:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int log_locked:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int mmap_disable:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int mmap_no_write:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int readonly:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int fsck:1;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano};
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoenum mail_index_sync_handler_type {
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano MAIL_INDEX_SYNC_HANDLER_INDEX = 0x01,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano MAIL_INDEX_SYNC_HANDLER_VIEW = 0x02
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano};
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_index_sync_handler {
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mail_index_sync_handler_t *callback;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano enum mail_index_sync_handler_type type;
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano};
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Add/replace sync handler for specified extra record. */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanovoid mail_index_register_expunge_handler(struct mail_index *index,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano uint32_t ext_id,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mail_index_expunge_handler_t *cb);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanovoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano mail_index_sync_handler_t *cb,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano enum mail_index_sync_handler_type type);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoint mail_index_write_base_header(struct mail_index *index,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano const struct mail_index_header *hdr);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normandint mail_index_reopen(struct mail_index *index, int fd);
99e4008cad9e959b683c6f48411fcf15a92be3b5Michel Normandint mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Returns 0 = ok, -1 = error. If update_index is TRUE, reopens the index
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano file if needed to get later version of it (not necessarily latest due to
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano races, unless transaction log is exclusively locked). */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoint mail_index_lock_shared(struct mail_index *index, int update_index,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int *lock_id_r);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Returns 0 = ok, -1 = error. */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoint mail_index_lock_exclusive(struct mail_index *index,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int *lock_id_r);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanovoid mail_index_unlock(struct mail_index *index, unsigned int lock_id);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Returns 1 if given lock_id is valid, 0 if not. */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoint mail_index_is_locked(struct mail_index *index, unsigned int lock_id);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoint mail_index_lock_fd(struct mail_index *index, int fd, int lock_type,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano unsigned int timeout_secs);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Map index file to memory, replacing the previous mapping for index.
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano returns 1 but sets index->fsck = TRUE. */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanoint mail_index_map(struct mail_index *index, int force);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Unreference given mapping and unmap it if it's dropped to zero. */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanovoid mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcanostruct mail_index_map *
mail_index_map_to_memory(struct mail_index_map *map, uint32_t new_record_size);
uint32_t mail_index_map_lookup_ext(struct mail_index_map *map,
const char *name);
uint32_t
mail_index_map_register_ext(struct mail_index *index,
struct mail_index_map *map, const char *name,
uint32_t hdr_offset, uint32_t hdr_size,
uint32_t record_offset, uint32_t record_size,
uint32_t record_align, uint32_t reset_id);
int mail_index_map_get_ext_idx(struct mail_index_map *map,
uint32_t ext_id, uint32_t *idx_r);
const struct mail_index_ext *
mail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id);
int mail_index_fix_header(struct mail_index *index, struct mail_index_map *map,
struct mail_index_header *hdr, const char **error_r);
void mail_index_view_transaction_ref(struct mail_index_view *view);
void mail_index_view_transaction_unref(struct mail_index_view *view);
void mail_index_set_inconsistent(struct mail_index *index);
int mail_index_set_error(struct mail_index *index, const char *fmt, ...)
__attr_format__(2, 3);
/* "%s failed with index file %s: %m" */
int mail_index_set_syscall_error(struct mail_index *index,
const char *function);
/* "%s failed with file %s: %m" */
int mail_index_file_set_syscall_error(struct mail_index *index,
const char *filepath,
const char *function);
void mail_index_reset_error(struct mail_index *index);
uint32_t mail_index_uint32_to_offset(uint32_t offset);
uint32_t mail_index_offset_to_uint32(uint32_t offset);
#endif