mail-index-private.h revision 5aeb15e5817fbd4b1d8de540aa7673e3819a8030
fd2f5fbc1f07aa93e2214a28cdf02437fb7d06c8Timo Sirainen/* How large index files to mmap() instead of reading to memory. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* How many times to retry opening index files if read/fstat returns ESTALE.
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen This happens with NFS when the file has been deleted (ie. index file was
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen rewritten by another computer than us). */
dd0ba1bab2c1b89c7e063fa45d156fa72b8260d5Timo Sirainen#define MAIL_INDEX_ESTALE_RETRY_COUNT NFS_ESTALE_RETRY_COUNT
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen/* Large extension header sizes are probably caused by file corruption, so
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen try to catch them by limiting the header size. */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen#define MAIL_INDEX_EXT_HEADER_MAX_SIZE (1024*1024*16-1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen PTR_OFFSET((map)->rec_map->records, (idx) * (map)->hdr.record_size))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u) \
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainentypedef int mail_index_expunge_handler_t(struct mail_index_sync_map_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainentypedef int mail_index_sync_handler_t(struct mail_index_sync_map_ctx *ctx,
df6478c4cf605bd81b3891c148b84c14eb6c4035Timo Sirainentypedef void mail_index_sync_lost_handler_t(struct mail_index *index);
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen uint32_t ext_offset; /* points to beginning of mail_index_ext_header */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen uint32_t hdr_offset; /* points to mail_index_ext_header.data[] */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen /* unsigned char name[name_size] */
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen /* unsigned char data[hdr_size] (starting 64bit aligned) */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen /* struct mail_index_keyword_header_rec[] */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen /* char name[][] */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen uint32_t unused; /* for backwards compatibility */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen uint32_t name_offset; /* relative to beginning of name[] */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen mail_index_expunge_handler_t *expunge_handler;
61b6d1256936065321153bcd9228b9e45d95c9abTimo Sirainen unsigned int lock_id;
df6478c4cf605bd81b3891c148b84c14eb6c4035Timo Sirainen void *records; /* struct mail_index_record[] */
e9f2d9104d395bcf54be3f8ba8d9f63aecf0bcbeTimo Sirainen /* If this mapping is written to disk and write_atomic=FALSE,
a2ce2eb4c266e2854fd34416ea5cfbe05dfd3971Timo Sirainen write_seq_* specify the message sequence range that needs to be
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen ARRAY_DEFINE(extensions, struct mail_index_ext);
289064eb21595d3e4460439eccdc48232d13f5e1Timo Sirainen ARRAY_DEFINE(ext_id_map, uint32_t); /* index -> file */
f0ff961282e618945dfe997dc45ff95d656e5790Timo Sirainen ARRAY_DEFINE(keyword_idx_map, unsigned int); /* file -> index */
5e40ed3f0a2c2acddc9b8eab59670c7a850114c5Timo Sirainen unsigned int write_atomic:1; /* write to a new file and rename() */
6f73af3a3a6ee900c7e736874587968d76a20bc0Timo Sirainen unsigned int id;
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainen ARRAY_DEFINE(extensions, struct mail_index_registered_ext);
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainen ARRAY_DEFINE(sync_lost_handlers, mail_index_sync_lost_handler_t *);
d24daa83c25063ef12b524c9ffcc9ecca34dadb9Timo Sirainen /* last_read_log_file_* contains the seq/offsets we last read from
d24daa83c25063ef12b524c9ffcc9ecca34dadb9Timo Sirainen the main index file's headers. these are used to figure out when
d24daa83c25063ef12b524c9ffcc9ecca34dadb9Timo Sirainen the main index file should be updated, and if we can update it
d24daa83c25063ef12b524c9ffcc9ecca34dadb9Timo Sirainen by writing on top of it or if we need to recreate it. */
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainen /* transaction log head seq/offset when we last fscked */
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainen int lock_type, shared_lock_count, excl_lock_count;
31050c3df6cbe403e8ced8ef11b5c4e12124d354Timo Sirainen struct hash_table *keywords_hash; /* name -> idx */
8fcaba5977f7d596632df1ed2af8541e5f154258Timo Sirainen /* Module-specific contexts. */
8fcaba5977f7d596632df1ed2af8541e5f154258Timo Sirainen ARRAY_DEFINE(module_contexts, union mail_index_module_context *);
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainenextern struct mail_index_module_register mail_index_module_register;
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainen/* Add/replace sync handler for specified extra record. */
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
a2ce2eb4c266e2854fd34416ea5cfbe05dfd3971Timo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
a2ce2eb4c266e2854fd34416ea5cfbe05dfd3971Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenint mail_index_create_tmp_file(struct mail_index *index, const char **path_r);
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenint mail_index_try_open_only(struct mail_index *index);
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenvoid mail_index_close_file(struct mail_index *index);
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenint mail_index_reopen_if_changed(struct mail_index *index);
dc0474dc9d5652d76cb41f439844dd80c8b96642Timo Sirainen/* Update/rewrite the main index file from index->map */
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenvoid mail_index_write(struct mail_index *index, bool want_rotate);
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenvoid mail_index_flush_read_cache(struct mail_index *index, const char *path,
a2ec607689dc88112bf08785960e441153f35d57Timo Sirainen/* Returns 0 = ok, -1 = error. */
20ecea31024db11ea4ca51c87f34fa15470e9c28Timo Sirainenint mail_index_lock_shared(struct mail_index *index, unsigned int *lock_id_r);
a2ec607689dc88112bf08785960e441153f35d57Timo Sirainen/* Returns 1 = ok, 0 = already locked, -1 = error. */
20ecea31024db11ea4ca51c87f34fa15470e9c28Timo Sirainenint mail_index_try_lock_exclusive(struct mail_index *index,
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainen unsigned int *lock_id_r);
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenvoid mail_index_unlock(struct mail_index *index, unsigned int *lock_id);
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainen/* Returns TRUE if given lock_id is valid. */
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenbool mail_index_is_locked(struct mail_index *index, unsigned int lock_id);
b159b7fb9740b6e37238016d8395a351de498d50Timo Sirainenint mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
a2ce2eb4c266e2854fd34416ea5cfbe05dfd3971Timo Sirainen/* Allocate a new empty map. */
a2ce2eb4c266e2854fd34416ea5cfbe05dfd3971Timo Sirainenstruct mail_index_map *mail_index_map_alloc(struct mail_index *index);
a2ce2eb4c266e2854fd34416ea5cfbe05dfd3971Timo Sirainen/* Replace index->map with the latest index changes. This may reopen the index
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainen file and/or it may read the latest changes from transaction log. The log is
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainen read up to EOF, but non-synced expunges are skipped.
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainen If we mmap()ed the index file, the map is returned locked.
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainen Returns 1 = ok, 0 = corrupted, -1 = error. */
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainen/* Unreference given mapping and unmap it if it's dropped to zero. */
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainenvoid mail_index_unmap(struct mail_index_map **map);
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainen/* Clone a map. The returned map is always in memory. */
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainenstruct mail_index_map *mail_index_map_clone(const struct mail_index_map *map);
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainenvoid mail_index_record_map_move_to_private(struct mail_index_map *map);
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainen/* Move a mmaped map to memory. */
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainenvoid mail_index_map_move_to_memory(struct mail_index_map *map);
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainenbool mail_index_map_lookup_ext(struct mail_index_map *map, const char *name,
e37fbcda56ab154557e84f990012502be53aa6c6Timo Sirainenmail_index_map_register_ext(struct mail_index_map *map,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenbool mail_index_map_get_ext_idx(struct mail_index_map *map,
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainenmail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id);
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainenint mail_index_map_check_header(struct mail_index_map *map);
16c28dd75976f94acc4940d6ba68b6cd4853aac7Timo Sirainenint mail_index_map_parse_keywords(struct mail_index_map *map);
16c28dd75976f94acc4940d6ba68b6cd4853aac7Timo Sirainenint mail_index_map_ext_get_next(struct mail_index_map *map,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen unsigned int *offset,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen const struct mail_index_ext_header **ext_hdr_r,
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen const char **name_r);
d33fc6c584718efd46159e1d8f46488b9dfc66f5Timo Sirainenint mail_index_map_ext_hdr_check(const struct mail_index_header *hdr,
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenunsigned int mail_index_map_ext_hdr_offset(unsigned int name_len);
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view);
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view);
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenvoid mail_index_fsck_locked(struct mail_index *index);
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenint mail_index_set_error(struct mail_index *index, const char *fmt, ...)
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainen/* "%s failed with index file %s: %m" */
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenint mail_index_set_syscall_error(struct mail_index *index,
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainen/* "%s failed with file %s: %m" */
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenint mail_index_file_set_syscall_error(struct mail_index *index,
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenuint32_t mail_index_uint32_to_offset(uint32_t offset);
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenuint32_t mail_index_offset_to_uint32(uint32_t offset);
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainen#define MAIL_INDEX_PACK_MAX_SIZE ((sizeof(uint32_t) * 8 + 7) / 7)
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenvoid mail_index_pack_num(uint8_t **p, uint32_t num);
131b073bdc3650083b00616dc778dd3017c2bbb5Timo Sirainenint mail_index_unpack_num(const uint8_t **p, const uint8_t *end,