mail-index-open.c revision 99b621cc5076398c5d780d2ea33dd7391341d630
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainenstatic int mail_index_open_init(struct mail_index *index,
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen /* update \Recent message counters */
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT) != 0 &&
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila /* keep last_recent_uid to next_uid-1 */
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen index->first_recent_uid = index->header->last_nonrecent_uid+1;
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen index->header->last_nonrecent_uid = index->header->next_uid-1;
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen index->first_recent_uid = hdr->last_nonrecent_uid+1;
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen if (hdr->next_uid >= MAX_ALLOWED_UID - 1000) {
f5c0d5cada4da23a167c38426d0c481a3e1d5583Timo Sirainen /* UID values are getting too high, rebuild index */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (index->lock_type == MAIL_LOCK_EXCLUSIVE) {
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* finally reset the modify log marks, fsck or syncing might
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen have deleted some messages, and since we're only just
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen opening the index, there's no need to remember them */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (!mail_modifylog_mark_synced(index->modifylog))
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainenstatic int index_open_and_fix(struct mail_index *index,
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen /* open/create the index files */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if ((index->set_flags & MAIL_INDEX_FLAG_REBUILD) == 0)
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen /* data file is corrupted, need to rebuild index */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) != 0) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (!mail_index_set_lock(index, MAIL_LOCK_EXCLUSIVE))
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen /* custom flags file needs to be open before
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen rebuilding index */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) != 0 ||
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen (index->header->flags & MAIL_INDEX_FLAG_REBUILD) != 0) {
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen /* no inconsistency problems since we're still opening
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if ((flags & _MAIL_INDEX_OPEN_FLAG_CREATING) == 0) {
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen if (index->header->flags & MAIL_INDEX_FLAG_FSCK) {
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* index needs fscking */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if ((index->header->flags & MAIL_INDEX_FLAG_REBUILD_TREE) != 0) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen /* sync ourself. do it before updating cache and compression which
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen may happen because of this. */
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (!index->sync_and_lock(index, MAIL_LOCK_SHARED, NULL))
78f87ea1d30f3f54bdf8560ea947ab7ee094283aTeemu Huovila /* we never want to keep shared lock if syncing happens to set it.
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen either exclusive or nothing (NOTE: drop it directly, not through
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen index->set_lock() so mbox lock won't be affected). */
b04e76cbc807707d299055be79500f8ff131da43Timo Sirainen if (!mail_index_set_lock(index, MAIL_LOCK_UNLOCK))
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_FAST) == 0) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (index->header->flags & MAIL_INDEX_FLAG_COMPRESS) {
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* remove deleted blocks from index file */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (index->header->flags & MAIL_INDEX_FLAG_CACHE_FIELDS) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen /* need to update cached fields */
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen if (index->header->flags & MAIL_INDEX_FLAG_COMPRESS_DATA) {
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen /* remove unused space from index data file.
62fc0b4f07eb6f18a3bff4b1fccb636e6fae3cf4Timo Sirainen keep after cache updates which may move data
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen and create unused space */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic int mail_index_read_header(struct mail_index *index,
0c5854b6891c59c1c3f443569bc823d7db571582Teemu Huovila /* missing data */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic int mail_index_is_compatible(const struct mail_index_header *hdr)
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen return hdr->compat_data[0] == MAIL_INDEX_VERSION &&
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen hdr->compat_data[1] == MAIL_INDEX_COMPAT_FLAGS &&
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen hdr->compat_data[2] == sizeof(unsigned int) &&
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenstatic int mail_index_init_file(struct mail_index *index,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen INDEX_MIN_RECORDS_COUNT * sizeof(struct mail_index_record);
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen if (write_full(index->fd, hdr, sizeof(*hdr)) < 0) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen index_set_syscall_error(index, "write_full()");
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen if (file_set_size(index->fd, (off_t)hdr->used_file_size) < 0) {
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen index_set_syscall_error(index, "file_set_size()");
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainenvoid mail_index_init_header(struct mail_index *index,
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen hdr->compat_data[1] = MAIL_INDEX_COMPAT_FLAGS;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen /* mark the index requiring rebuild - rebuild() removes this flag
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen when it succeeds */
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen /* set the fields we always want to cache */
e4bf76afb82ea28ec9d06823fa7deed5f8277183Timo Sirainen hdr->cache_fields |= index->default_cache_fields;
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen hdr->used_file_size = sizeof(struct mail_index_header);
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainenstatic void mail_index_cleanup_temp_files(const char *dir)
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainen unlink_lockfiles(dir, t_strconcat("temp.", my_hostname, NULL),
568fec5b1e629f25d288b48007485b9aa4a018b1Timo Sirainenvoid mail_index_init(struct mail_index *index, const char *dir)
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen index->mail_read_mmaped = getenv("MAIL_READ_MMAPED") != NULL;
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainenstatic int mail_index_create_memory(struct mail_index *index,
c4b772bfbdafe68ac1a0076eab26cd681f8e5046Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
8b1a9a4d63b0abccdf7cb1acb8359d5396dd657bTimo Sirainen index->mmap_full_length = INDEX_FILE_MIN_SIZE;
2730605833442b5ddcb261f90b8375fc98201e35Timo Sirainen index->mmap_base = mmap_anon(index->mmap_full_length);
2730605833442b5ddcb261f90b8375fc98201e35Timo Sirainen mail_index_init_header(index, index->mmap_base);
e4bf76afb82ea28ec9d06823fa7deed5f8277183Timo Sirainen index->mmap_used_length = index->header->used_file_size;
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainen index->filepath = i_strdup_printf("(in-memory index for %s)",
c865b0e9c65fd77f7b2ab6f8616d3def5501ecb3Timo Sirainenint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
return TRUE;