Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5791:2a05cff7eca4 HEAD
Handle partial reads with mmap_disable=no correctly.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 20 Jun 2007 20:49:51 +0300 |
parents | e1347a122140 |
children | a250c1a48471 |
files | src/lib-index/mail-transaction-log-file.c |
diffstat | 1 files changed, 26 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-transaction-log-file.c Wed Jun 20 16:22:48 2007 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Wed Jun 20 20:49:51 2007 +0300 @@ -723,16 +723,20 @@ return -1; } file->sync_offset += trans_size; + trans_size = 0; } avail = file->sync_offset - file->buffer_offset; - if (avail != size && avail >= sizeof(*hdr)) { - /* Record goes outside the file we've seen. Unless we're - locked, we can't know if this is expected or not. Even when - we're read()ing the file, the kernel (at least Linux 2.6) - can show the last read memory page updated, but without the - expected next page. */ - if (file->locked) { + if (avail != size) { + /* There's more data than we could sync at the moment. If the + last record's size wasn't valid, we can't know if it will + be updated unless we've locked the log. + + Without locking we can be sure only if we're not using + mmaping, because with mmaping the data and the file size + can get updated at any time. */ + if (file->locked || + (trans_size != 0 && file->mmap_base == NULL)) { if (trans_size != 0) { mail_transaction_log_file_set_corrupted(file, "hdr.size too large (%u)", trans_size); @@ -822,25 +826,24 @@ file->last_size = read_offset; + if (ret < 0) { + if (errno == ESTALE) { + /* log file was deleted in NFS server, fail silently */ + return 0; + } + + mail_index_file_set_syscall_error(file->log->index, + file->filepath, "pread()"); + return -1; + } + if (mail_transaction_log_file_sync(file) < 0) return 0; - if (ret == 0) { - /* EOF */ - i_assert(file->sync_offset >= file->buffer_offset); - buffer_set_used_size(file->buffer, - file->sync_offset - file->buffer_offset); - return 1; - } - - if (errno == ESTALE) { - /* log file was deleted in NFS server, fail silently */ - return 0; - } - - mail_index_file_set_syscall_error(file->log->index, file->filepath, - "pread()"); - return -1; + i_assert(file->sync_offset >= file->buffer_offset); + buffer_set_used_size(file->buffer, + file->sync_offset - file->buffer_offset); + return 1; } static int