dovecot: Handle partial reads with mmap_disable=no correctly.
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jun 20 20:49:58 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/2a05cff7eca4
changeset: 5791:2a05cff7eca4
user: Timo Sirainen <tss at iki.fi>
date: Wed Jun 20 20:49:51 2007 +0300
description:
Handle partial reads with mmap_disable=no correctly.
diffstat:
1 file changed, 26 insertions(+), 23 deletions(-)
src/lib-index/mail-transaction-log-file.c | 49 +++++++++++++++--------------
diffs (72 lines):
diff -r e1347a122140 -r 2a05cff7eca4 src/lib-index/mail-transaction-log-file.c
--- 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 @@ mail_transaction_log_file_sync(struct ma
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 @@ mail_transaction_log_file_read(struct ma
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
More information about the dovecot-cvs
mailing list