mail-index-private.h revision 7e94cf9d70ce9fdeccb7a85ff400b899e6386f36
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#ifndef __MAIL_INDEX_PRIVATE_H
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#define __MAIL_INDEX_PRIVATE_H
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#include "file-dotlock.h"
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#include "mail-index.h"
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstruct mail_transaction_header;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* Maximum number of extra record data items we allowed. Raising this limit
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg only means it takes a few bytes more memory, but 32 should be enough for a
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg long time, right? :) */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#define MAIL_INDEX_MAX_EXTRA_RECORDS 32
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* Index file is grown exponentially when we're adding less than this many
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg records. */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#define MAIL_INDEX_MAX_POWER_GROW (1024*1024 / sizeof(struct mail_index_record))
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* How many times to retry opening index files if read/fstat returns ESTALE.
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg This happens with NFS when the file has been deleted (ie. index file was
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg rewritten by another computer than us). */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#define MAIL_INDEX_ESTALE_RETRY_COUNT 10
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg ((map)->buffer != NULL)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#define MAIL_INDEX_MAP_IDX(map, idx) \
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg ((struct mail_index_record *) \
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg PTR_OFFSET((map)->records, (idx) * (map)->hdr->record_size))
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstruct mail_index_extra_record_info {
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const char *name;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg uint16_t offset;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg uint16_t size;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg};
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstruct mail_index_map {
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg int refcount;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const struct mail_index_header *hdr;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg void *records; /* struct mail_index_record[] */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int records_count;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_index_extra_record_info *
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg extra_record_map[MAIL_INDEX_MAX_EXTRA_RECORDS];
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg void *mmap_base;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg size_t mmap_size, mmap_used_size;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg buffer_t *buffer;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg uint32_t log_file_seq;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg uoff_t log_file_offset;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_index_header hdr_copy;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int write_to_disk:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg};
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstruct mail_index {
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg char *dir, *prefix;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_cache *cache;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_transaction_log *log;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg mode_t mode;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg gid_t gid;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg pool_t extra_records_pool;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg buffer_t *extra_records_buf;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const struct mail_index_extra_record_info *extra_records;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int extra_records_count;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int max_record_size;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg char *filepath;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg int fd;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_index_map *map;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const struct mail_index_header *hdr;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg uint32_t indexid;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg int lock_type, shared_lock_count, excl_lock_count;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int lock_id;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg char *copy_lock_path;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct dotlock dotlock;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int last_grow_count;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg char *error;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int nodiskspace:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int index_lock_timeout:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int opened:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int log_locked:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int mmap_disable:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int mmap_no_write:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int fcntl_locks_disable:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int readonly:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int fsck:1;
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg};
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_write_base_header(struct mail_index *index,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const struct mail_index_header *hdr);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_reopen(struct mail_index *index, int fd);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* Returns 0 = ok, -1 = error. If update_index is TRUE, reopens the index
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg file if needed to get later version of it (not necessarily latest due to
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg races, unless transaction log is exclusively locked). */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_lock_shared(struct mail_index *index, int update_index,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int *lock_id_r);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* Returns 0 = ok, -1 = error. */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_lock_exclusive(struct mail_index *index,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg unsigned int *lock_id_r);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_unlock(struct mail_index *index, unsigned int lock_id);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* Returns 1 if given lock_id is valid, 0 if not. */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_is_locked(struct mail_index *index, unsigned int lock_id);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_map_lock_mprotect(struct mail_index *index,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_index_map *map, int lock_type);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* Map index file to memory, replacing the previous mapping for index.
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg returns 1 but sets index->fsck = TRUE. */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_map(struct mail_index *index, int force);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* Unreference given mapping and unmap it if it's dropped to zero. */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgstruct mail_index_map *
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgmail_index_map_to_memory(struct mail_index_map *map, uint32_t new_record_size);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_index_map **map_r,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const struct mail_index_record **rec_r);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_reset_cache(struct mail_index_transaction *t,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg uint32_t new_file_seq);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_update_cache(struct mail_index_transaction *t,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg uint32_t seq, uint32_t offset);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_fix_header(struct mail_index *index, struct mail_index_map *map,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg struct mail_index_header *hdr, const char **error_r);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_view_transaction_ref(struct mail_index_view *view);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_view_transaction_unref(struct mail_index_view *view);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_set_inconsistent(struct mail_index *index);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_set_error(struct mail_index *index, const char *fmt, ...)
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg __attr_format__(2, 3);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* "%s failed with index file %s: %m" */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_set_syscall_error(struct mail_index *index,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const char *function);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg/* "%s failed with file %s: %m" */
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgint mail_index_file_set_syscall_error(struct mail_index *index,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const char *filepath,
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg const char *function);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankgvoid mail_index_reset_error(struct mail_index *index);
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg#endif
ef06a12023b00bdbe0b983192e4afdbdb21139e3fuankg