Mercurial > dovecot > core-2.2
changeset 12395:878746da7992
lib-index: Fixed another transaction log read optimization.
Buffer's size should always be the same as sync_offset, otherwise some
optimizations could think that the data doesn't have to be re-read even
though it was updated in disk already.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 05 Nov 2010 19:51:47 +0000 |
parents | 7f8f73bed7f9 |
children | 11169c6c6e8d |
files | src/lib-index/mail-transaction-log-file.c |
diffstat | 1 files changed, 27 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-transaction-log-file.c Fri Nov 05 18:58:56 2010 +0000 +++ b/src/lib-index/mail-transaction-log-file.c Fri Nov 05 19:51:47 2010 +0000 @@ -17,6 +17,9 @@ #define LOG_NEW_DOTLOCK_SUFFIX ".newlock" static int +mail_transaction_log_file_sync(struct mail_transaction_log_file *file); + +static int log_file_set_syscall_error(struct mail_transaction_log_file *file, const char *function) { @@ -186,6 +189,14 @@ file->next = *p; *p = file; + + if (file->buffer != NULL) { + /* if we read any unfinished data, make sure the buffer gets + truncated. */ + (void)mail_transaction_log_file_sync(file); + buffer_set_used_size(file->buffer, + file->sync_offset - file->buffer_offset); + } } static int @@ -399,7 +410,9 @@ memset(&file->hdr, 0, sizeof(file->hdr)); if (file->last_size < mmap_get_page_size() && file->last_size > 0) { - /* just read the entire transaction log to memory */ + /* just read the entire transaction log to memory. + note that if some of the data hasn't been fully committed + yet (hdr.size=0), the buffer must be truncated later */ file->buffer = buffer_create_dynamic(default_pool, 4096); file->buffer_offset = 0; dest_size = file->last_size; @@ -1403,23 +1416,19 @@ } if ((ret = mail_transaction_log_file_read_more(file)) <= 0) - return ret; - - if (file->log->nfs_flush && !nfs_flush && - mail_transaction_log_file_need_nfs_flush(file)) { + ; + else if (file->log->nfs_flush && !nfs_flush && + mail_transaction_log_file_need_nfs_flush(file)) { /* we didn't read enough data. flush and try again. */ return mail_transaction_log_file_read(file, start_offset, TRUE); + } else if ((ret = mail_transaction_log_file_sync(file)) <= 0) { + i_assert(ret != 0); /* ret=0 happens only with mmap */ + } else { + i_assert(file->sync_offset >= file->buffer_offset); } - - if ((ret = mail_transaction_log_file_sync(file)) <= 0) { - i_assert(ret != 0); /* happens only with mmap */ - return -1; - } - - i_assert(file->sync_offset >= file->buffer_offset); buffer_set_used_size(file->buffer, file->sync_offset - file->buffer_offset); - return 1; + return ret; } static int @@ -1553,6 +1562,8 @@ i_assert(start_offset >= file->hdr.hdr_size); i_assert(start_offset <= end_offset); + i_assert(file->buffer == NULL || file->mmap_base != NULL || + file->sync_offset >= file->buffer_offset + file->buffer->used); if (file->locked_sync_offset_updated && file == file->log->head && end_offset == (uoff_t)-1) { @@ -1606,6 +1617,9 @@ ret = mail_transaction_log_file_read(file, start_offset, FALSE); } + i_assert(file->buffer == NULL || file->mmap_base != NULL || + file->sync_offset >= file->buffer_offset + file->buffer->used); + return ret <= 0 ? ret : log_file_map_check_offsets(file, start_offset, end_offset); }