mail-index-private.h revision cfadd9a17fca2f25981664b02e38eafe27b6686f
fc71e94957d0c2959a609450a2f303640d681858Sascha Wilde/* How large index files to mmap() instead of reading to memory. */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* How many times to retry opening index files if read/fstat returns ESTALE.
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen This happens with NFS when the file has been deleted (ie. index file was
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen rewritten by another computer than us). */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen#define MAIL_INDEX_ESTALE_RETRY_COUNT NFS_ESTALE_RETRY_COUNT
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* Large extension header sizes are probably caused by file corruption, so
fc71e94957d0c2959a609450a2f303640d681858Sascha Wilde try to catch them by limiting the header size. */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen#define MAIL_INDEX_EXT_HEADER_MAX_SIZE (1024*1024*16-1)
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen/* Write to main index file when bytes-to-be-read-from-log is between these
fc71e94957d0c2959a609450a2f303640d681858Sascha Wilde PTR_OFFSET((map)->rec_map->records, (idx) * (map)->hdr.record_size))
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen PTR_OFFSET((map)->rec_map->records, ((seq)-1) * (map)->hdr.record_size))
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen#define MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u) \
fc71e94957d0c2959a609450a2f303640d681858Sascha Wilde ((((u)->add_flags | (u)->remove_flags) & MAIL_INDEX_FLAGS_MASK) == 0 && \
fc71e94957d0c2959a609450a2f303640d681858Sascha Wildetypedef int mail_index_expunge_handler_t(struct mail_index_sync_map_ctx *ctx,
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainentypedef int mail_index_sync_handler_t(struct mail_index_sync_map_ctx *ctx,
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainentypedef void mail_index_sync_lost_handler_t(struct mail_index *index);
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen uint32_t ext_offset; /* points to beginning of mail_index_ext_header */
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen uint32_t hdr_offset; /* points to mail_index_ext_header.data[] */
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen /* unsigned char name[name_size] */
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen /* unsigned char data[hdr_size] (starting 64bit aligned) */
fc71e94957d0c2959a609450a2f303640d681858Sascha Wilde /* struct mail_index_keyword_header_rec[] */
fc71e94957d0c2959a609450a2f303640d681858Sascha Wilde /* char name[][] */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen uint32_t unused; /* for backwards compatibility */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen uint32_t name_offset; /* relative to beginning of name[] */
fc71e94957d0c2959a609450a2f303640d681858Sascha Wilde const char *name;
64bfe7b4a42512971db154937905dfa2bdb9cf2cTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen mail_index_expunge_handler_t *expunge_handler;
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen void *records; /* struct mail_index_record[] */
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen ARRAY(uint32_t) ext_id_map; /* index -> file */
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen ARRAY(unsigned int) keyword_idx_map; /* file -> index */
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen unsigned int id;
2ba63f475f74b2aa87f9fd9e28a6c5738deb0878Timo Sirainen ARRAY(struct mail_index_registered_ext) extensions;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen ARRAY(mail_index_sync_lost_handler_t *) sync_lost_handlers;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainen /* last_read_log_file_* contains the seq/offsets we last read from
fc464e5b2b2ab4d415a5d5b90ce4475d34620a75Timo Sirainen the main index file's headers. these are used to figure out when
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen the main index file should be updated, and if we can update it
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen by writing on top of it or if we need to recreate it. */
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen /* transaction log head seq/offset when we last fscked */
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen /* syncing will update this if non-NULL */
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen struct mail_index_transaction_commit_result *sync_commit_result;
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen HASH_TABLE(char *, void *) keywords_hash; /* name -> unsigned int idx */
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen /* Module-specific contexts. */
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen ARRAY(union mail_index_module_context *) module_contexts;
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen unsigned int index_delete_requested:1; /* next sync sets it deleted */
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainen unsigned int index_deleted:1; /* no changes allowed anymore */
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainenextern struct mail_index_module_register mail_index_module_register;
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* Add/replace sync handler for specified extra record. */
fc71e94957d0c2959a609450a2f303640d681858Sascha Wildevoid mail_index_register_expunge_handler(struct mail_index *index,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
fc71e94957d0c2959a609450a2f303640d681858Sascha Wildevoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
5c0ab4cc4dff573940df683eb4b23bd6077153faTimo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
fc71e94957d0c2959a609450a2f303640d681858Sascha Wildeint mail_index_create_tmp_file(struct mail_index *index,
64bfe7b4a42512971db154937905dfa2bdb9cf2cTimo Sirainen const char *path_prefix, const char **path_r);
21c1655dbc5fe861a152dc9a8a388d0d64f5ae20Timo Sirainenint mail_index_try_open_only(struct mail_index *index);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_close_file(struct mail_index *index);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenint mail_index_reopen_if_changed(struct mail_index *index);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* Update/rewrite the main index file from index->map */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_write(struct mail_index *index, bool want_rotate);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_flush_read_cache(struct mail_index *index, const char *path,
9bb91f1dbf7cf8cfbd2df7784101df98d59fb46dTimo Sirainenint mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
9bb91f1dbf7cf8cfbd2df7784101df98d59fb46dTimo Sirainen/* Allocate a new empty map. */
9bb91f1dbf7cf8cfbd2df7784101df98d59fb46dTimo Sirainenstruct mail_index_map *mail_index_map_alloc(struct mail_index *index);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* Replace index->map with the latest index changes. This may reopen the index
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen file and/or it may read the latest changes from transaction log. The log is
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen read up to EOF, but non-synced expunges are skipped.
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen If we mmap()ed the index file, the map is returned locked.
64bfe7b4a42512971db154937905dfa2bdb9cf2cTimo Sirainen Returns 1 = ok, 0 = corrupted, -1 = error. */
4b1359bde7d32667197548652a4b4f540062e2acTimo Sirainen/* Unreference given mapping and unmap it if it's dropped to zero. */
fc71e94957d0c2959a609450a2f303640d681858Sascha Wildevoid mail_index_unmap(struct mail_index_map **map);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* Clone a map. The returned map is always in memory. */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenstruct mail_index_map *mail_index_map_clone(const struct mail_index_map *map);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_record_map_move_to_private(struct mail_index_map *map);
64bfe7b4a42512971db154937905dfa2bdb9cf2cTimo Sirainen/* Move a mmaped map to memory. */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_map_move_to_memory(struct mail_index_map *map);
fc71e94957d0c2959a609450a2f303640d681858Sascha Wildevoid mail_index_fchown(struct mail_index *index, int fd, const char *path);
fc71e94957d0c2959a609450a2f303640d681858Sascha Wildebool mail_index_map_lookup_ext(struct mail_index_map *map, const char *name,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenmail_index_map_register_ext(struct mail_index_map *map,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenbool mail_index_map_get_ext_idx(struct mail_index_map *map,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenmail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_map_lookup_seq_range(struct mail_index_map *map,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenint mail_index_map_check_header(struct mail_index_map *map);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenbool mail_index_check_header_compat(struct mail_index *index,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenint mail_index_map_parse_extensions(struct mail_index_map *map);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenint mail_index_map_parse_keywords(struct mail_index_map *map);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_map_init_extbufs(struct mail_index_map *map,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenint mail_index_map_ext_get_next(struct mail_index_map *map,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen unsigned int *offset,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen const struct mail_index_ext_header **ext_hdr_r,
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainen const char **name_r);
c5a6a6565be93224fc26522eda855b0990f256e8Timo Sirainenint mail_index_map_ext_hdr_check(const struct mail_index_header *hdr,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenunsigned int mail_index_map_ext_hdr_offset(unsigned int name_len);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_fsck_locked(struct mail_index *index);
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_set_error(struct mail_index *index, const char *fmt, ...)
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* "%s failed with index file %s: %m" */
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainenvoid mail_index_set_syscall_error(struct mail_index *index,
aba994a4e79a020b4748e0ceffc194e5a18e1d1aTimo Sirainen/* "%s failed with file %s: %m" */