2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* How large index files to mmap() instead of reading to memory. */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen/* How many times to retry opening index files if read/fstat returns ESTALE.
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen This happens with NFS when the file has been deleted (ie. index file was
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen rewritten by another computer than us). */
89b548af722113acb5d63dfffb44423cb60f91e4Timo Sirainen#define MAIL_INDEX_ESTALE_RETRY_COUNT NFS_ESTALE_RETRY_COUNT
ed50658501d9ae8c85f6264831056b1debed11c3Timo Sirainen/* Large extension header sizes are probably caused by file corruption, so
ed50658501d9ae8c85f6264831056b1debed11c3Timo Sirainen try to catch them by limiting the header size. */
ed50658501d9ae8c85f6264831056b1debed11c3Timo Sirainen#define MAIL_INDEX_EXT_HEADER_MAX_SIZE (1024*1024*16-1)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen PTR_OFFSET((map)->rec_map->records, (idx) * (map)->hdr.record_size))
f5e06b955adead65ab7281b6410059230c0bf512Phil Carmody PTR_OFFSET((map)->rec_map->records, ((seq)-1) * (map)->hdr.record_size))
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen#define MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u) \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen ((((u)->add_flags | (u)->remove_flags) & MAIL_INDEX_FLAGS_MASK) == 0 && \
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainentypedef int mail_index_expunge_handler_t(struct mail_index_sync_map_ctx *ctx,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainentypedef int mail_index_sync_handler_t(struct mail_index_sync_map_ctx *ctx,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo 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 */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint32_t hdr_offset; /* points to mail_index_ext_header.data[] */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
d74899545d913eac91c82b692927b32c3bf36abaTimo Sirainen /* unsigned char name[name_size] */
d74899545d913eac91c82b692927b32c3bf36abaTimo Sirainen /* unsigned char data[hdr_size] (starting 64bit aligned) */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* struct mail_index_keyword_header_rec[] */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* char name[][] */
625101600b8c05f72f79b13604de0c751a73e959Timo Sirainen uint32_t unused; /* for backwards compatibility */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t name_offset; /* relative to beginning of name[] */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen mail_index_expunge_handler_t *expunge_handler;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen void *records; /* struct mail_index_record[] */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(uint32_t) ext_id_map; /* index -> file */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(unsigned int) keyword_idx_map; /* file -> index */
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen struct mail_index_optimization_settings optimization_set;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct mail_index_registered_ext) extensions;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(mail_index_sync_lost_handler_t *) sync_lost_handlers;
8e57335924f5ff57cbd1929ec99764dc267c3312Timo Sirainen /* last_read_log_file_* contains the seq/offsets we last read from
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen the main index file's headers. these are used to figure out when
2988b4cbf3540a0c02a9ddf185cafec5938c0cacTimo Sirainen the main index file should be updated. */
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen /* transaction log head seq/offset when we last fscked */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen /* syncing will update this if non-NULL */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen struct mail_index_transaction_commit_result *sync_commit_result;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen HASH_TABLE(char *, void *) keywords_hash; /* name -> unsigned int idx */
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen /* Module-specific contexts. */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(union mail_index_module_context *) module_contexts;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool index_delete_requested:1; /* next sync sets it deleted */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool index_deleted:1; /* no changes allowed anymore */
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainenextern struct mail_index_module_register mail_index_module_register;
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainenextern struct event_category event_category_index;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* Add/replace sync handler for specified extra record. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
06fc580f6baf83fe5bb94c64be8149d527b01a42Timo Sirainenint mail_index_create_tmp_file(struct mail_index *index,
06fc580f6baf83fe5bb94c64be8149d527b01a42Timo Sirainen const char *path_prefix, const char **path_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_try_open_only(struct mail_index *index);
c2feb7d13482d0f60691cd71d06d42a80df99397Timo Sirainenvoid mail_index_close_file(struct mail_index *index);
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainenint mail_index_reopen_if_changed(struct mail_index *index,
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen const char **reason_r);
10a97b15c34119ffe2d2eab9b975252fed631df2Timo Sirainen/* Update/rewrite the main index file from index->map */
10a97b15c34119ffe2d2eab9b975252fed631df2Timo Sirainenvoid mail_index_write(struct mail_index *index, bool want_rotate);
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainenvoid mail_index_flush_read_cache(struct mail_index *index, const char *path,
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainenint mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Allocate a new empty map. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstruct mail_index_map *mail_index_map_alloc(struct mail_index *index);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Replace index->map with the latest index changes. This may reopen the index
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen file and/or it may read the latest changes from transaction log. The log is
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen read up to EOF, but non-synced expunges are skipped.
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen If we mmap()ed the index file, the map is returned locked.
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen Returns 1 = ok, 0 = corrupted, -1 = error. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Unreference given mapping and unmap it if it's dropped to zero. */
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainenvoid mail_index_unmap(struct mail_index_map **map);
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen/* Clone a map. The returned map is always in memory. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstruct mail_index_map *mail_index_map_clone(const struct mail_index_map *map);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainenvoid mail_index_record_map_move_to_private(struct mail_index_map *map);
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen/* Move a mmaped map to memory. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_index_map_move_to_memory(struct mail_index_map *map);
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainenvoid mail_index_fchown(struct mail_index *index, int fd, const char *path);
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainenbool mail_index_map_lookup_ext(struct mail_index_map *map, const char *name,
3675a7e9bd3775ba13fe8bc93915902513a0f1a4Timo Sirainenmail_index_map_register_ext(struct mail_index_map *map,
12053b7b4b57dbd2790057426d1633988eedad56Timo Sirainenbool mail_index_map_get_ext_idx(struct mail_index_map *map,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenmail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id);
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainenvoid mail_index_map_lookup_seq_range(struct mail_index_map *map,
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen/* Returns 1 on success, 0 on non-critical errors we want to silently fix,
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen -1 if map isn't usable. The caller is responsible for logging the errors
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen if -1 is returned. */
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainenint mail_index_map_check_header(struct mail_index_map *map,
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen const char **error_r);
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen/* Returns 1 if header is usable, 0 or -1 if not. The caller should log an
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen error if -1 is returned, but not if 0 is returned. */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenbool mail_index_check_header_compat(struct mail_index *index,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenint mail_index_map_parse_extensions(struct mail_index_map *map);
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainenint mail_index_map_parse_keywords(struct mail_index_map *map);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenvoid mail_index_map_init_extbufs(struct mail_index_map *map,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenint mail_index_map_ext_get_next(struct mail_index_map *map,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int *offset,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen const struct mail_index_ext_header **ext_hdr_r,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen const char **name_r);
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenint mail_index_map_ext_hdr_check(const struct mail_index_header *hdr,
8ababf3e7b15f793370d1dedf85825d38b42633fTimo Sirainenunsigned int mail_index_map_ext_hdr_offset(unsigned int name_len);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view);
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainenvoid mail_index_fsck_locked(struct mail_index *index);
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen/* Log an error and set it as the index's current error that is available
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen with mail_index_get_error_message(). */
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_set_error(struct mail_index *index, const char *fmt, ...)
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen/* Same as mail_index_set_error(), but don't log the error. */
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainenvoid mail_index_set_error_nolog(struct mail_index *index, const char *str);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* "%s failed with index file %s: %m" */
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_set_syscall_error(struct mail_index *index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* "%s failed with file %s: %m" */