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