mail-index-private.h revision 7797aa2479e99aeb71057b7a2584b2cb72e4d3f8
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#ifndef __MAIL_INDEX_PRIVATE_H
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#define __MAIL_INDEX_PRIVATE_H
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#include "file-dotlock.h"
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#include "mail-index.h"
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenystruct mail_transaction_header;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny/* Index file is grown exponentially when we're adding less than this many
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny records. */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#define MAIL_INDEX_MAX_POWER_GROW (1024*1024 / sizeof(struct mail_index_record))
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny/* How many times to retry opening index files if read/fstat returns ESTALE.
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny This happens with NFS when the file has been deleted (ie. index file was
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny rewritten by another computer than us). */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#define MAIL_INDEX_ESTALE_RETRY_COUNT 10
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny ((map)->buffer != NULL)
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#define MAIL_INDEX_MAP_IDX(map, idx) \
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny ((struct mail_index_record *) \
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny PTR_OFFSET((map)->records, (idx) * (map)->hdr->record_size))
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenystruct mail_index_ext {
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const char *name;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t hdr_offset;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t hdr_size;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t record_offset;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t record_size;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny};
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenystruct mail_index_ext_header {
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t hdr_size;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t record_offset;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t record_size;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny};
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenystruct mail_index_map {
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny int refcount;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const struct mail_index_header *hdr;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const void *hdr_base;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny void *records; /* struct mail_index_record[] */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int records_count;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny pool_t extension_pool;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny buffer_t *extensions; /* struct mail_index_ext[] */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny buffer_t *ext_id_map; /* uint32_t[] (index -> file) */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny void *mmap_base;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny size_t mmap_size, mmap_used_size;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny buffer_t *buffer;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t log_file_seq;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uoff_t log_file_offset;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny buffer_t *hdr_copy_buf;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t base_header_size; /* so we don't need lock to access it */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int write_to_disk:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny};
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenystruct mail_index {
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny char *dir, *prefix;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct mail_cache *cache;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct mail_transaction_log *log;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny mode_t mode;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny gid_t gid;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny pool_t extension_pool;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny buffer_t *extensions; /* struct mail_index_ext[] */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny char *filepath;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny int fd;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct mail_index_map *map;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const struct mail_index_header *hdr;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t indexid;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny int lock_type, shared_lock_count, excl_lock_count;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int lock_id;
8bbf89c5ab798c112773fe23515c3a9df56dde71Nick Guay char *copy_lock_path;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct dotlock dotlock;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
8bbf89c5ab798c112773fe23515c3a9df56dde71Nick Guay unsigned int last_grow_count;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny char *error;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int nodiskspace:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int index_lock_timeout:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int opened:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int log_locked:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int mmap_disable:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int mmap_no_write:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int fcntl_locks_disable:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int readonly:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int fsck:1;
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny};
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_write_base_header(struct mail_index *index,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const struct mail_index_header *hdr);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_reopen(struct mail_index *index, int fd);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny/* Returns 0 = ok, -1 = error. If update_index is TRUE, reopens the index
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny file if needed to get later version of it (not necessarily latest due to
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny races, unless transaction log is exclusively locked). */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_lock_shared(struct mail_index *index, int update_index,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int *lock_id_r);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny/* Returns 0 = ok, -1 = error. */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_lock_exclusive(struct mail_index *index,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny unsigned int *lock_id_r);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyvoid mail_index_unlock(struct mail_index *index, unsigned int lock_id);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny/* Returns 1 if given lock_id is valid, 0 if not. */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_is_locked(struct mail_index *index, unsigned int lock_id);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_map_lock_mprotect(struct mail_index *index,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct mail_index_map *map, int lock_type);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny/* Map index file to memory, replacing the previous mapping for index.
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny returns 1 but sets index->fsck = TRUE. */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_map(struct mail_index *index, int force);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny/* Unreference given mapping and unmap it if it's dropped to zero. */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyvoid mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenystruct mail_index_map *
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenymail_index_map_to_memory(struct mail_index_map *map, uint32_t new_record_size);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyuint32_t mail_index_map_register_ext(struct mail_index *index,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct mail_index_map *map,
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek const char *name, uint32_t hdr_offset,
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek uint32_t hdr_size, uint32_t record_size);
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidekint mail_index_map_get_ext_idx(struct mail_index_map *map,
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek uint32_t ext_id, uint32_t *idx_r);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct mail_index_map **map_r,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const struct mail_index_record **rec_r);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyvoid mail_index_reset_cache(struct mail_index_transaction *t,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t new_file_seq);
894d18ff4178f40a18bbfece8fae270d8307eac6Jakub Hrozekvoid mail_index_update_cache(struct mail_index_transaction *t, uint32_t seq,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t file_seq, uint32_t offset,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t *old_offset_r);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_update_cache_lookup(struct mail_index_transaction *t,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny uint32_t seq, uint32_t *offset_r);
894d18ff4178f40a18bbfece8fae270d8307eac6Jakub Hrozek
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_fix_header(struct mail_index *index, struct mail_index_map *map,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny struct mail_index_header *hdr, const char **error_r);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyvoid mail_index_view_transaction_ref(struct mail_index_view *view);
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidekvoid mail_index_view_transaction_unref(struct mail_index_view *view);
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidekvoid mail_index_set_inconsistent(struct mail_index *index);
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidekint mail_index_set_error(struct mail_index *index, const char *fmt, ...)
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek __attr_format__(2, 3);
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek/* "%s failed with index file %s: %m" */
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyint mail_index_set_syscall_error(struct mail_index *index,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const char *function);
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek/* "%s failed with file %s: %m" */
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidekint mail_index_file_set_syscall_error(struct mail_index *index,
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek const char *filepath,
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny const char *function);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyvoid mail_index_reset_error(struct mail_index *index);
3a59cbd0b7b9c5dd3c62ac1679876070c264d80fMichal Zidek
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyuint32_t mail_index_uint32_to_offset(uint32_t offset);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zelenyuint32_t mail_index_offset_to_uint32(uint32_t offset);
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny#endif
4c11f752e1f10cf5740d53a3206bb795e9e34fe8Jan Zeleny