Mercurial > dovecot > original-hg > dovecot-1.2
diff src/lib-index/mail-transaction-log.c @ 3833:318c70c1d4ec HEAD
Beginnings of fallbacking to in-memory indexes when write fails with "out of
disk space" error.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 07 Jan 2006 01:48:57 +0200 |
parents | 76f4be7ae499 |
children | 55df57c028d4 |
line wrap: on
line diff
--- a/src/lib-index/mail-transaction-log.c Sat Jan 07 00:31:40 2006 +0200 +++ b/src/lib-index/mail-transaction-log.c Sat Jan 07 01:48:57 2006 +0200 @@ -30,6 +30,9 @@ static struct mail_transaction_log_file * mail_transaction_log_file_open_or_create(struct mail_transaction_log *log, const char *path); +static int +mail_transaction_log_file_read(struct mail_transaction_log_file *file, + uoff_t offset); void mail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file, @@ -237,8 +240,13 @@ MAIL_TRANSACTION_LOG_SUFFIX, NULL); log->head = mail_transaction_log_file_open_or_create(log, path); if (log->head == NULL) { - mail_transaction_log_close(log); - return NULL; + /* fallback to in-memory indexes */ + if (mail_index_move_to_memory(index) < 0) { + mail_transaction_log_close(log); + return NULL; + } + log->head = mail_transaction_log_file_open_or_create(log, path); + i_assert(log->head != NULL); } if (index->fd != -1 && @@ -268,16 +276,16 @@ } static void -mail_transaction_log_file_close(struct mail_transaction_log_file *file) +mail_transaction_log_file_free(struct mail_transaction_log_file *file) { + mail_transaction_log_file_unlock(file); + if (file == file->log->head) file->log->head = NULL; if (file == file->log->tail) file->log->tail = file->next; - mail_transaction_log_file_unlock(file); - - if (file->buffer != NULL) + if (file->buffer != NULL) buffer_free(file->buffer); if (file->mmap_base != NULL) { @@ -300,6 +308,44 @@ i_free(file); } +int mail_transaction_log_move_to_memory(struct mail_transaction_log *log) +{ + struct mail_transaction_log_file *file = log->head; + + if (file == NULL || MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) + return 0; + + /* read the whole file to memory. we might currently be appending + data into it, so we want to read it up to end of file */ + file->buffer_offset = 0; + + if (file->buffer != NULL) { + buffer_free(file->buffer); + file->buffer = NULL; + } + + if (file->mmap_base != NULL) { + if (munmap(file->mmap_base, file->mmap_size) < 0) { + mail_index_file_set_syscall_error(file->log->index, + file->filepath, + "munmap()"); + } + file->mmap_base = NULL; + } + + if (mail_transaction_log_file_read(file, 0) <= 0) + return -1; + + /* after we've read the file into memory, make it into in-memory + log file */ + if (close(file->fd) < 0) { + mail_index_file_set_syscall_error(file->log->index, + file->filepath, "close()"); + } + file->fd = -1; + return 0; +} + static int mail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file, int head) @@ -610,7 +656,7 @@ ret = mail_transaction_log_file_read_hdr(file, head); if (ret < 0) { - mail_transaction_log_file_close(file); + mail_transaction_log_file_free(file); return -1; } @@ -660,7 +706,7 @@ } } if (ret <= 0) { - mail_transaction_log_file_close(file); + mail_transaction_log_file_free(file); return NULL; } @@ -733,7 +779,7 @@ if (ret <= 0) { /* error / corrupted */ if (ret == 0) - mail_transaction_log_file_close(file); + mail_transaction_log_file_free(file); return NULL; } @@ -750,7 +796,7 @@ p = &(*p)->next; else { next = (*p)->next; - mail_transaction_log_file_close(*p); + mail_transaction_log_file_free(*p); *p = next; } } @@ -905,7 +951,7 @@ i_error("unlink(%s) failed: %m", file->filepath); } - mail_transaction_log_file_close(file); + mail_transaction_log_file_free(file); return 0; } return -1;