mail-index-private.h revision 0add8c99ca65e56dbf613595fc37c41aafff3f7f
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#ifndef __MAIL_INDEX_PRIVATE_H
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define __MAIL_INDEX_PRIVATE_H
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "file-dotlock.h"
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#include "mail-index.h"
a7797068c4deb6ce2bdbcda27c45ff1bbb4a8e78Jakub Hrozek
b20208b80e99abb79c00d5ec526caa9465859c52Jakub Hrozekstruct mail_transaction_header;
a7797068c4deb6ce2bdbcda27c45ff1bbb4a8e78Jakub Hrozek
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* number of records to always keep allocated in index file,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher either used or unused */
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek#define INDEX_MIN_RECORDS_COUNT 64
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* when empty space in index file gets full, grow the file n% larger */
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek#define INDEX_GROW_PERCENTAGE 10
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek/* ftruncate() the index file when only n% of it is in use */
a9228ebcce14888b3123bdf46e610e0900bcd2ccJakub Hrozek#define INDEX_TRUNCATE_PERCENTAGE 30
a7797068c4deb6ce2bdbcda27c45ff1bbb4a8e78Jakub Hrozek/* don't truncate whole file anyway, keep n% of the empty space */
a7797068c4deb6ce2bdbcda27c45ff1bbb4a8e78Jakub Hrozek#define INDEX_TRUNCATE_KEEP_PERCENTAGE 10
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Compress the file when deleted space reaches n% of total size */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define INDEX_COMPRESS_PERCENTAGE 50
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Compress the file when searching deleted records tree has to go this deep */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define INDEX_COMPRESS_DEPTH 10
7a14e8f66c0e932fe2954d792614a3b61d444bd1Jakub Hrozek/* How many times to retry opening index files if read/fstat returns ESTALE.
481ec0e1eb0058195732cb320845b41f6f4d43ebJakub Hrozek This happens with NFS when the file has been deleted (ie. index file was
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher rewritten by another computer than us). */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define INDEX_ESTALE_RETRY_COUNT 10
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher#define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek ((map)->buffer != NULL)
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozekstruct mail_index_map {
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek int refcount;
5ee3fba0bd812242a1ffe189f5ddf2689e6e6811Jakub Hrozek
5ee3fba0bd812242a1ffe189f5ddf2689e6e6811Jakub Hrozek const struct mail_index_header *hdr;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mail_index_record *records;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher unsigned int records_count;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher void *mmap_base;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher size_t mmap_size, mmap_used_size;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher buffer_t *buffer;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uint32_t log_file_seq;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uoff_t log_file_offset;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mail_index_header hdr_copy;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek unsigned int write_to_disk:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct mail_index {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *dir, *prefix;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mail_cache *cache;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher struct mail_transaction_log *log;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher mode_t mode;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher gid_t gid;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher char *filepath;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int fd;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mail_index_map *map;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher const struct mail_index_header *hdr;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher uint32_t indexid;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher int lock_type, shared_lock_count, excl_lock_count;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int lock_id;
fbeb1aba9e11e7aab8adac943276ca040f0c5311Jakub Hrozek char *copy_lock_path;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct dotlock dotlock;
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek unsigned int last_grow_count;
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek char *error;
a23014d69b56cbdf48ad05229c334648b5309d8fJakub Hrozek unsigned int nodiskspace:1;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher unsigned int index_lock_timeout:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher unsigned int opened:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int log_locked:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int mmap_disable:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int mmap_no_write:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int fcntl_locks_disable:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int readonly:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int fsck:1;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher};
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallaghervoid mail_index_header_init(struct mail_index_header *hdr);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_write_header(struct mail_index *index,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const struct mail_index_header *hdr);
fbeb1aba9e11e7aab8adac943276ca040f0c5311Jakub Hrozek
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_create(struct mail_index *index, struct mail_index_header *hdr);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_try_open_only(struct mail_index *index);
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozekint mail_index_try_open(struct mail_index *index, unsigned int *lock_id_r);
ea929f1b022fc2cb77dec89b0e12accef983ec85Jakub Hrozekint mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher/* Returns 0 = ok, -1 = error. If update_index is TRUE, reopens the index
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher file if needed to get later version of it (not necessarily latest due to
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher races, unless transaction log is exclusively locked). */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_lock_shared(struct mail_index *index, int update_index,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int *lock_id_r);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Returns 0 = ok, -1 = error. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_lock_exclusive(struct mail_index *index,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher unsigned int *lock_id_r);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallaghervoid mail_index_unlock(struct mail_index *index, unsigned int lock_id);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher/* Returns 1 if given lock_id is valid, 0 if not. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_is_locked(struct mail_index *index, unsigned int lock_id);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_map_lock_mprotect(struct mail_index *index,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mail_index_map *map, int lock_type);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* Map index file to memory, replacing the previous mapping for index.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher returns 1 but sets index->fsck = TRUE. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_map(struct mail_index *index, int force);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher/* Unreference given mapping and unmap it if it's dropped to zero. */
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallaghervoid mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagherstruct mail_index_map *mail_index_map_to_memory(struct mail_index_map *map);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghervoid mail_index_update_cache(struct mail_index_transaction *t,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher uint32_t seq, uint32_t offset);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_fix_header(struct mail_index *index, struct mail_index_map *map,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mail_index_header *hdr, const char **error_r);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallaghervoid mail_index_view_transaction_ref(struct mail_index_view *view);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallaghervoid mail_index_view_transaction_unref(struct mail_index_view *view);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_sync_get_rec(struct mail_index_view *view,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher struct mail_index_sync_rec *rec,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const struct mail_transaction_header *hdr,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const void *data, size_t *data_offset);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallaghervoid mail_index_set_inconsistent(struct mail_index *index);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagherint mail_index_mark_corrupted(struct mail_index *index);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_set_error(struct mail_index *index, const char *fmt, ...)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher __attr_format__(2, 3);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* "%s failed with index file %s: %m" */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_set_syscall_error(struct mail_index *index,
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher const char *function);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher/* "%s failed with file %s: %m" */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherint mail_index_file_set_syscall_error(struct mail_index *index,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher const char *filepath,
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek const char *function);
5ee3fba0bd812242a1ffe189f5ddf2689e6e6811Jakub Hrozekvoid mail_index_reset_error(struct mail_index *index);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher#endif
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher