# HG changeset patch # User Timo Sirainen # Date 1112098729 -10800 # Node ID 40b4ba3c55b8207c28f1986c3a29524046f75a6d # Parent 9a08cf5e5f610e3d2236beb49243073ea49ee9aa In-memory indexes work again. Just pass dir as NULL to mail_index_alloc(). diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-cache-compress.c --- a/src/lib-index/mail-cache-compress.c Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-cache-compress.c Tue Mar 29 15:18:49 2005 +0300 @@ -300,6 +300,9 @@ { int ret; + if (MAIL_INDEX_IS_IN_MEMORY(cache->index)) + return 0; + if (cache->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) { /* we're using dotlocking, cache file creation itself creates the dotlock file we need. */ diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-cache.c --- a/src/lib-index/mail-cache.c Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-cache.c Tue Mar 29 15:18:49 2005 +0300 @@ -69,8 +69,9 @@ struct mail_index_view *view; const struct mail_index_ext *ext; - if (MAIL_CACHE_IS_UNUSABLE(cache) && cache->need_compress) { - /* unusable, we're just waiting for compression */ + if (MAIL_CACHE_IS_UNUSABLE(cache) && + (cache->need_compress || MAIL_INDEX_IS_IN_MEMORY(cache->index))) { + /* reopening does no good */ return 0; } @@ -192,8 +193,10 @@ mail_cache_set_syscall_error(cache, "munmap()"); } else { if (cache->fd == -1) { - /* unusable, waiting for compression */ - i_assert(cache->need_compress); + /* unusable, waiting for compression or + index is in memory */ + i_assert(cache->need_compress || + MAIL_INDEX_IS_IN_MEMORY(cache->index)); return -1; } } @@ -222,6 +225,9 @@ static int mail_cache_open_and_verify(struct mail_cache *cache) { + if (MAIL_INDEX_IS_IN_MEMORY(cache->index)) + return 0; + cache->fd = open(cache->filepath, O_RDWR); if (cache->fd == -1) { if (errno == ENOENT) { @@ -261,8 +267,10 @@ cache->dotlock_settings.immediate_stale_timeout = MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT; - if (index->mmap_disable || index->mmap_no_write) - cache->file_cache = file_cache_new(-1); + if (!MAIL_INDEX_IS_IN_MEMORY(index)) { + if (index->mmap_disable || index->mmap_no_write) + cache->file_cache = file_cache_new(-1); + } cache->ext_id = mail_index_ext_register(index, "cache", 0, diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-index-lock.c --- a/src/lib-index/mail-index-lock.c Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-index-lock.c Tue Mar 29 15:18:49 2005 +0300 @@ -41,6 +41,9 @@ if (timeout_secs != 0) alarm(MAIL_INDEX_LOCK_WAIT_TIME); + if (MAIL_INDEX_IS_IN_MEMORY(index)) + return 1; + switch (index->lock_method) { case MAIL_INDEX_LOCK_FCNTL: { #ifndef HAVE_FCNTL @@ -233,6 +236,8 @@ const char *path; int ret, fd; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); + fd = mail_index_create_tmp_file(index, &path); if (fd == -1) return -1; @@ -367,11 +372,14 @@ i_free(index->copy_lock_path); index->copy_lock_path = NULL; } - fd = mail_index_copy(index); - if (fd == -1) - mail_index_set_inconsistent(index); - else - (void)close(fd); + + if (!MAIL_INDEX_IS_IN_MEMORY(index)) { + fd = mail_index_copy(index); + if (fd == -1) + mail_index_set_inconsistent(index); + else + (void)close(fd); + } } if (index->shared_lock_count > 0 && diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-index-private.h --- a/src/lib-index/mail-index-private.h Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-index-private.h Tue Mar 29 15:18:49 2005 +0300 @@ -20,6 +20,9 @@ rewritten by another computer than us). */ #define MAIL_INDEX_ESTALE_RETRY_COUNT 10 +#define MAIL_INDEX_IS_IN_MEMORY(index) \ + ((index)->dir == NULL) + #define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \ ((map) != NULL && (map)->buffer != NULL) diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-index-sync.c --- a/src/lib-index/mail-index-sync.c Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-index-sync.c Tue Mar 29 15:18:49 2005 +0300 @@ -630,7 +630,6 @@ return &ctx->index->keywords; } - void mail_index_sync_flags_apply(const struct mail_index_sync_rec *sync_rec, uint8_t *flags) { diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-index.c --- a/src/lib-index/mail-index.c Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-index.c Tue Mar 29 15:18:49 2005 +0300 @@ -16,6 +16,8 @@ #include static int mail_index_try_open_only(struct mail_index *index); +static void mail_index_create_in_memory(struct mail_index *index, + const struct mail_index_header *hdr); struct mail_index *mail_index_alloc(const char *dir, const char *prefix) { @@ -886,6 +888,12 @@ i_assert(index->map == NULL || index->map->refcount > 0); i_assert(index->lock_type != F_UNLCK); + if (MAIL_INDEX_IS_IN_MEMORY(index)) { + if (index->map == NULL) + mail_index_create_in_memory(index, NULL); + return 1; + } + index->mapping = TRUE; if (!force && index->map != NULL) { @@ -1052,6 +1060,8 @@ { int i; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); + for (i = 0; i < 3; i++) { index->fd = open(index->filepath, O_RDWR); if (index->fd == -1 && errno == EACCES) { @@ -1086,6 +1096,9 @@ if (lock_id_r != NULL) *lock_id_r = 0; + if (MAIL_INDEX_IS_IN_MEMORY(index)) + return 0; + ret = mail_index_try_open_only(index); if (ret <= 0) return ret; @@ -1126,9 +1139,12 @@ return mail_index_set_syscall_error(index, "msync()"); index->map->hdr = *hdr; } else { - if (pwrite_full(index->fd, hdr, hdr_size, 0) < 0) { - mail_index_set_syscall_error(index, "pwrite_full()"); - return -1; + if (!MAIL_INDEX_IS_IN_MEMORY(index)) { + if (pwrite_full(index->fd, hdr, hdr_size, 0) < 0) { + mail_index_set_syscall_error(index, + "pwrite_full()"); + return -1; + } } index->map->hdr = *hdr; @@ -1144,6 +1160,8 @@ const char *path; int fd; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); + path = *path_r = t_strconcat(index->filepath, ".tmp", NULL); old_mask = umask(0); fd = open(path, O_RDWR|O_CREAT|O_TRUNC, index->mode); @@ -1167,6 +1185,7 @@ uoff_t offset; int ret; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); i_assert(index->lock_type == F_UNLCK); /* log file lock protects index creation */ @@ -1243,6 +1262,27 @@ hdr->next_uid = 1; } +static void mail_index_create_in_memory(struct mail_index *index, + const struct mail_index_header *hdr) +{ + struct mail_index_header tmp_hdr; + struct mail_index_map tmp_map; + + if (hdr == NULL) { + mail_index_header_init(&tmp_hdr); + hdr = &tmp_hdr; + } + + memset(&tmp_map, 0, sizeof(tmp_map)); + tmp_map.hdr = *hdr; + tmp_map.hdr_base = hdr; + + /* a bit kludgy way to do this, but it initializes everything + nicely and correctly */ + index->map = mail_index_map_clone(&tmp_map, hdr->record_size); + index->hdr = &index->map->hdr; +} + /* returns -1 = error, 0 = won't create, 1 = ok */ static int mail_index_open_files(struct mail_index *index, enum mail_index_open_flags flags) @@ -1274,8 +1314,12 @@ mail_index_unlock(index, lock_id); lock_id = 0; } - if (mail_index_create(index, &hdr) < 0) - return -1; + if (!MAIL_INDEX_IS_IN_MEMORY(index)) { + if (mail_index_create(index, &hdr) < 0) + return -1; + } else { + mail_index_create_in_memory(index, &hdr); + } created = TRUE; } @@ -1307,7 +1351,9 @@ } } - index->filepath = i_strconcat(index->dir, "/", index->prefix, NULL); + index->filepath = MAIL_INDEX_IS_IN_MEMORY(index) ? + i_strdup("(in-memory index)") : + i_strconcat(index->dir, "/", index->prefix, NULL); do { index->shared_lock_count = 0; @@ -1397,6 +1443,8 @@ unsigned int old_shared_locks, old_lock_id, lock_id = 0; int ret, old_fd, old_lock_type; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(index)); + old_map = index->map; old_fd = index->fd; old_map->refcount++; @@ -1463,6 +1511,9 @@ { struct stat st1, st2; + if (MAIL_INDEX_IS_IN_MEMORY(index)) + return 0; + if (fstat(index->fd, &st1) < 0) return mail_index_set_syscall_error(index, "fstat()"); if (stat(index->filepath, &st2) < 0) { @@ -1490,6 +1541,9 @@ unsigned int lock_id; int ret; + if (MAIL_INDEX_IS_IN_MEMORY(index)) + return 0; + if (index->excl_lock_count > 0) { /* we have index exclusively locked, nothing could have changed. */ @@ -1552,7 +1606,7 @@ hdr = *index->hdr; hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED; if (mail_index_write_base_header(index, &hdr) == 0) { - if (fsync(index->fd) < 0) + if (!MAIL_INDEX_IS_IN_MEMORY(index) && fsync(index->fd) < 0) mail_index_set_syscall_error(index, "fsync()"); } } diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-transaction-log-append.c --- a/src/lib-index/mail-transaction-log-append.c Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-transaction-log-append.c Tue Mar 29 15:18:49 2005 +0300 @@ -41,29 +41,41 @@ if (external) hdr.type |= MAIL_TRANSACTION_EXTERNAL; - hdr_size = - mail_index_uint32_to_offset(sizeof(hdr) + size + hdr_data_size); - if (file->first_append_size == 0) { - /* size will be written later once everything is in disk */ - file->first_append_size = hdr_size; + hdr_size = mail_index_uint32_to_offset(sizeof(hdr) + size + + hdr_data_size); + if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) { + if (file->first_append_size == 0) { + /* size will be written later once everything is in + disk */ + file->first_append_size = hdr_size; + } else { + hdr.size = hdr_size; + } + if (pwrite_full(file->fd, &hdr, sizeof(hdr), + file->sync_offset) < 0) + return -1; + file->sync_offset += sizeof(hdr); + + if (hdr_data_size > 0) { + if (pwrite_full(file->fd, hdr_data, hdr_data_size, + file->sync_offset) < 0) + return -1; + file->sync_offset += hdr_data_size; + } + + if (pwrite_full(file->fd, data, size, file->sync_offset) < 0) + return -1; + file->sync_offset += size; } else { hdr.size = hdr_size; + + i_assert(file->buffer_offset + file->buffer->used == + file->sync_offset); + buffer_append(file->buffer, &hdr, sizeof(hdr)); + buffer_append(file->buffer, hdr_data, hdr_data_size); + buffer_append(file->buffer, data, size); + file->sync_offset = file->buffer_offset + file->buffer->used; } - - if (pwrite_full(file->fd, &hdr, sizeof(hdr), file->sync_offset) < 0) - return -1; - file->sync_offset += sizeof(hdr); - - if (hdr_data_size > 0) { - if (pwrite_full(file->fd, hdr_data, hdr_data_size, - file->sync_offset) < 0) - return -1; - file->sync_offset += hdr_data_size; - } - - if (pwrite_full(file->fd, data, size, file->sync_offset) < 0) - return -1; - file->sync_offset += size; return 0; } @@ -421,22 +433,24 @@ append_offset); } - if (ret == 0 && fsync(file->fd) < 0) { - /* we don't know how much of it got written, - it may be corrupted now.. */ - mail_index_file_set_syscall_error(log->index, file->filepath, - "fsync()"); - ret = -1; - } - - if (ret == 0 && file->first_append_size != 0) { - /* synced - rewrite first record's header */ - ret = pwrite_full(file->fd, &file->first_append_size, - sizeof(uint32_t), append_offset); - if (ret < 0) { + if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) { + if (ret == 0 && fsync(file->fd) < 0) { + /* we don't know how much of it got written, + it may be corrupted now.. */ mail_index_file_set_syscall_error(log->index, file->filepath, - "pwrite()"); + "fsync()"); + ret = -1; + } + + if (ret == 0 && file->first_append_size != 0) { + /* synced - rewrite first record's header */ + ret = pwrite_full(file->fd, &file->first_append_size, + sizeof(uint32_t), append_offset); + if (ret < 0) { + mail_index_file_set_syscall_error(log->index, + file->filepath, "pwrite()"); + } } } diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-transaction-log-private.h --- a/src/lib-index/mail-transaction-log-private.h Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-transaction-log-private.h Tue Mar 29 15:18:49 2005 +0300 @@ -7,6 +7,8 @@ #define MAIL_TRANSACTION_LOG_ROTATE_SIZE (1024*128) #define MAIL_TRANSACTION_LOG_ROTATE_TIME (60*5) +#define MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file) ((file)->fd == -1) + struct mail_transaction_log_file { struct mail_transaction_log *log; struct mail_transaction_log_file *next; diff -r 9a08cf5e5f61 -r 40b4ba3c55b8 src/lib-index/mail-transaction-log.c --- a/src/lib-index/mail-transaction-log.c Tue Mar 29 13:30:19 2005 +0300 +++ b/src/lib-index/mail-transaction-log.c Tue Mar 29 15:18:49 2005 +0300 @@ -37,10 +37,12 @@ va_list va; file->hdr.indexid = 0; - if (pwrite_full(file->fd, &file->hdr.indexid, - sizeof(file->hdr.indexid), 0) < 0) { - mail_index_file_set_syscall_error(file->log->index, - file->filepath, "pwrite()"); + if (!MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) { + if (pwrite_full(file->fd, &file->hdr.indexid, + sizeof(file->hdr.indexid), 0) < 0) { + mail_index_file_set_syscall_error(file->log->index, + file->filepath, "pwrite()"); + } } va_start(va, fmt); @@ -122,6 +124,11 @@ if (file->locked) return 0; + if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) { + file->locked = TRUE; + return 0; + } + if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) return mail_transaction_log_file_dotlock(file); @@ -155,6 +162,9 @@ file->locked = FALSE; + if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) + return; + if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) { mail_transaction_log_file_undotlock(file); return; @@ -278,9 +288,12 @@ } } - if (close(file->fd) < 0) { - mail_index_file_set_syscall_error(file->log->index, - file->filepath, "close()"); + if (file->fd != -1) { + if (close(file->fd) < 0) { + mail_index_file_set_syscall_error(file->log->index, + file->filepath, + "close()"); + } } i_free(file->filepath); @@ -293,6 +306,8 @@ struct mail_transaction_log_file *f; int ret; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(file->log->index)); + ret = pread_full(file->fd, &file->hdr, sizeof(file->hdr), 0); if (ret < 0) { // FIXME: handle ESTALE @@ -362,6 +377,43 @@ } static int +mail_transaction_log_init_hdr(struct mail_transaction_log *log, + struct mail_transaction_log_header *hdr) +{ + struct mail_index *index = log->index; + unsigned int lock_id; + + memset(hdr, 0, sizeof(*hdr)); + hdr->major_version = MAIL_TRANSACTION_LOG_MAJOR_VERSION; + hdr->minor_version = MAIL_TRANSACTION_LOG_MINOR_VERSION; + hdr->hdr_size = sizeof(struct mail_transaction_log_header); + hdr->indexid = log->index->indexid; + hdr->create_stamp = ioloop_time; + + if (index->fd != -1) { + /* not creating index - make sure we have latest header */ + if (mail_index_lock_shared(index, TRUE, &lock_id) < 0) + return -1; + if (mail_index_map(index, FALSE) <= 0) { + mail_index_unlock(index, lock_id); + return -1; + } + } + hdr->prev_file_seq = index->hdr->log_file_seq; + hdr->prev_file_offset = index->hdr->log_file_int_offset; + hdr->file_seq = index->hdr->log_file_seq+1; + + if (index->fd != -1) + mail_index_unlock(index, lock_id); + + if (log->head != NULL && hdr->file_seq <= log->head->hdr.file_seq) { + /* make sure the sequence grows */ + hdr->file_seq = log->head->hdr.file_seq+1; + } + return 0; +} + +static int mail_transaction_log_file_create2(struct mail_transaction_log *log, const char *path, int fd, struct dotlock **dotlock, @@ -370,7 +422,6 @@ struct mail_index *index = log->index; struct mail_transaction_log_header hdr; struct stat st; - unsigned int lock_id; int fd2, ret; /* log creation is locked now - see if someone already created it */ @@ -397,33 +448,8 @@ return -1; } - memset(&hdr, 0, sizeof(hdr)); - hdr.major_version = MAIL_TRANSACTION_LOG_MAJOR_VERSION; - hdr.minor_version = MAIL_TRANSACTION_LOG_MINOR_VERSION; - hdr.hdr_size = sizeof(struct mail_transaction_log_header); - hdr.indexid = index->indexid; - hdr.create_stamp = ioloop_time; - - if (index->fd != -1) { - if (mail_index_lock_shared(index, TRUE, &lock_id) < 0) - return -1; - if (mail_index_map(index, FALSE) <= 0) { - mail_index_unlock(index, lock_id); - return -1; - } - - hdr.prev_file_seq = index->hdr->log_file_seq; - hdr.prev_file_offset = index->hdr->log_file_int_offset; - } - hdr.file_seq = index->hdr->log_file_seq+1; - - if (index->fd != -1) - mail_index_unlock(index, lock_id); - - if (log->head != NULL && hdr.file_seq <= log->head->hdr.file_seq) { - /* make sure the sequence grows */ - hdr.file_seq = log->head->hdr.file_seq+1; - } + if (mail_transaction_log_init_hdr(log, &hdr) < 0) + return -1; if (write_full(fd, &hdr, sizeof(hdr)) < 0) { mail_index_file_set_syscall_error(index, path, @@ -448,6 +474,8 @@ mode_t old_mask; int fd, fd2; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(log->index)); + /* With dotlocking we might already have path.lock created, so this filename has to be different. */ old_mask = umask(log->index->mode ^ 0666); @@ -476,15 +504,39 @@ return fd2; } +static void +mail_transaction_log_file_alloc_finish(struct mail_transaction_log_file *file) +{ + struct mail_transaction_log *log = file->log; + struct mail_transaction_log_file **p; + + if (log->index->map != NULL && + file->hdr.file_seq == log->index->map->hdr.log_file_seq && + log->index->map->hdr.log_file_int_offset != 0) { + /* we can get a valid log offset from index file. initialize + sync_offset from it so we don't have to read the whole log + file from beginning. */ + file->sync_offset = log->index->map->hdr.log_file_int_offset; + } else { + file->sync_offset = file->hdr.hdr_size; + } + + /* append to end of list. */ + for (p = &log->tail; *p != NULL; p = &(*p)->next) + i_assert((*p)->hdr.file_seq < file->hdr.file_seq); + *p = file; +} + static struct mail_transaction_log_file * mail_transaction_log_file_fd_open(struct mail_transaction_log *log, const char *path, int fd) { - struct mail_transaction_log_file **p; struct mail_transaction_log_file *file; struct stat st; int ret; + i_assert(!MAIL_INDEX_IS_IN_MEMORY(log->index)); + if (fstat(fd, &st) < 0) { mail_index_file_set_syscall_error(log->index, path, "fstat()"); (void)close(fd); @@ -532,22 +584,30 @@ return NULL; } - if (log->index->map != NULL && - file->hdr.file_seq == log->index->map->hdr.log_file_seq && - log->index->map->hdr.log_file_int_offset != 0) { - /* we can get a valid log offset from index file. initialize - sync_offset from it so we don't have to read the whole log - file from beginning. */ - file->sync_offset = log->index->map->hdr.log_file_int_offset; - } else { - file->sync_offset = file->hdr.hdr_size; + mail_transaction_log_file_alloc_finish(file); + return file; +} + +static struct mail_transaction_log_file * +mail_transaction_log_file_alloc_in_memory(struct mail_transaction_log *log) +{ + struct mail_transaction_log_file *file; + + file = i_new(struct mail_transaction_log_file, 1); + file->refcount = 1; + file->log = log; + file->filepath = i_strdup("(in-memory transaction log file)"); + file->fd = -1; + + if (mail_transaction_log_init_hdr(log, &file->hdr) < 0) { + i_free(file); + return NULL; } - /* append to end of list. */ - for (p = &log->tail; *p != NULL; p = &(*p)->next) - i_assert((*p)->hdr.file_seq < file->hdr.file_seq); - *p = file; + file->buffer = buffer_create_dynamic(default_pool, 4096); + file->buffer_offset = sizeof(file->hdr); + mail_transaction_log_file_alloc_finish(file); return file; } @@ -557,6 +617,9 @@ { int fd; + if (MAIL_INDEX_IS_IN_MEMORY(log->index)) + return mail_transaction_log_file_alloc_in_memory(log); + fd = open(path, O_RDWR); if (fd == -1) { if (errno != ENOENT) { @@ -591,26 +654,31 @@ int mail_transaction_log_rotate(struct mail_transaction_log *log, int lock) { struct mail_transaction_log_file *file; + const char *path = log->head->filepath; struct stat st; int fd; i_assert(log->head->locked); - if (fstat(log->head->fd, &st) < 0) { - mail_index_file_set_syscall_error(log->index, - log->head->filepath, - "fstat()"); - return -1; - } + if (MAIL_INDEX_IS_IN_MEMORY(log->index)) + file = mail_transaction_log_file_alloc_in_memory(log); + else { + if (fstat(log->head->fd, &st) < 0) { + mail_index_file_set_syscall_error(log->index, path, + "fstat()"); + return -1; + } - fd = mail_transaction_log_file_create(log, log->head->filepath, - st.st_dev, st.st_ino, st.st_size); - if (fd == -1) - return -1; + fd = mail_transaction_log_file_create(log, path, + st.st_dev, st.st_ino, + st.st_size); + if (fd == -1) + return -1; - file = mail_transaction_log_file_fd_open(log, log->head->filepath, fd); - if (file == NULL) - return -1; + file = mail_transaction_log_file_fd_open(log, path, fd); + if (file == NULL) + return -1; + } if (lock) { if (mail_transaction_log_file_lock(file) < 0) { @@ -637,6 +705,9 @@ struct stat st; const char *path; + if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(log->head)) + return 0; + path = t_strconcat(log->index->filepath, MAIL_TRANSACTION_LOG_PREFIX, NULL); if (stat(path, &st) < 0) { @@ -830,6 +901,9 @@ return 0; } + if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) + return 1; + if (start_offset < file->hdr.hdr_size) { mail_transaction_log_file_set_corrupted(file, "offset (%"PRIuUOFF_T") < header size (%"PRIuSIZE_T")",