dovecot-2.1: lib-storage: Verify that cached message size matche...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Oct 4 17:15:51 EEST 2011
details: http://hg.dovecot.org/dovecot-2.1/rev/75f044354386
changeset: 13602:75f044354386
user: Timo Sirainen <tss at iki.fi>
date: Tue Oct 04 17:22:55 2011 +0300
description:
lib-storage: Verify that cached message size matches actually read size.
diffstat:
src/lib-storage/index/Makefile.am | 4 +-
src/lib-storage/index/imapc/imapc-mail-fetch.c | 1 +
src/lib-storage/index/index-mail.c | 12 +-
src/lib-storage/index/index-mail.h | 1 +
src/lib-storage/index/istream-mail-stats.c | 69 -------------
src/lib-storage/index/istream-mail-stats.h | 8 -
src/lib-storage/index/istream-mail.c | 129 +++++++++++++++++++++++++
src/lib-storage/index/istream-mail.h | 7 +
8 files changed, 149 insertions(+), 82 deletions(-)
diffs (truncated from 308 to 300 lines):
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/Makefile.am
--- a/src/lib-storage/index/Makefile.am Tue Oct 04 17:17:12 2011 +0300
+++ b/src/lib-storage/index/Makefile.am Tue Oct 04 17:22:55 2011 +0300
@@ -13,7 +13,7 @@
libstorage_index_la_SOURCES = \
istream-attachment.c \
- istream-mail-stats.c \
+ istream-mail.c \
index-attachment.c \
index-mail.c \
index-mail-headers.c \
@@ -37,7 +37,7 @@
headers = \
istream-attachment.h \
- istream-mail-stats.h \
+ istream-mail.h \
index-attachment.h \
index-mail.h \
index-search-private.h \
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/imapc/imapc-mail-fetch.c
--- a/src/lib-storage/index/imapc/imapc-mail-fetch.c Tue Oct 04 17:17:12 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c Tue Oct 04 17:22:55 2011 +0300
@@ -266,6 +266,7 @@
imail->data.virtual_size = size;
}
+ imail->data.stream_has_only_header = !have_body;
if (index_mail_init_stream(imail, NULL, NULL, &input) < 0)
i_stream_unref(&imail->data.stream);
}
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c Tue Oct 04 17:17:12 2011 +0300
+++ b/src/lib-storage/index/index-mail.c Tue Oct 04 17:22:55 2011 +0300
@@ -14,7 +14,7 @@
#include "mail-cache.h"
#include "mail-index-modseq.h"
#include "index-storage.h"
-#include "istream-mail-stats.h"
+#include "istream-mail.h"
#include "index-mail.h"
#include <fcntl.h>
@@ -837,8 +837,8 @@
if (!data->initialized_wrapper_stream &&
_mail->transaction->stats_track) {
- input = i_stream_create_mail_stats_counter(_mail->transaction,
- data->stream);
+ input = i_stream_create_mail(_mail, data->stream,
+ !data->stream_has_only_header);
i_stream_unref(&data->stream);
data->stream = input;
data->initialized_wrapper_stream = TRUE;
@@ -1616,6 +1616,12 @@
case 0:
field_name = "fields";
break;
+ case MAIL_FETCH_PHYSICAL_SIZE:
+ field_name = "physical size";
+ imail->data.physical_size = (uoff_t)-1;
+ imail->data.virtual_size = (uoff_t)-1;
+ imail->data.parts = NULL;
+ break;
case MAIL_FETCH_VIRTUAL_SIZE:
field_name = "virtual size";
imail->data.physical_size = (uoff_t)-1;
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/index-mail.h
--- a/src/lib-storage/index/index-mail.h Tue Oct 04 17:17:12 2011 +0300
+++ b/src/lib-storage/index/index-mail.h Tue Oct 04 17:22:55 2011 +0300
@@ -105,6 +105,7 @@
unsigned int save_bodystructure_header:1;
unsigned int save_bodystructure_body:1;
unsigned int save_message_parts:1;
+ unsigned int stream_has_only_header:1;
unsigned int parsed_bodystructure:1;
unsigned int hdr_size_set:1;
unsigned int body_size_set:1;
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail-stats.c
--- a/src/lib-storage/index/istream-mail-stats.c Tue Oct 04 17:17:12 2011 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "mail-storage-private.h"
-#include "istream-private.h"
-#include "istream-mail-stats.h"
-
-struct mail_stats_istream {
- struct istream_private istream;
-
- struct mailbox_transaction_context *trans;
- unsigned int files_read_increased:1;
-};
-
-static ssize_t
-i_stream_mail_stats_read_mail_stats(struct istream_private *stream)
-{
- struct mail_stats_istream *mstream =
- (struct mail_stats_istream *)stream;
- ssize_t ret;
-
- i_stream_seek(stream->parent, stream->parent_start_offset +
- stream->istream.v_offset);
-
- ret = i_stream_read_copy_from_parent(&stream->istream);
- if (ret > 0) {
- mstream->trans->stats.files_read_bytes += ret;
- if (!mstream->files_read_increased) {
- mstream->files_read_increased = TRUE;
- mstream->trans->stats.files_read_count++;
- }
- }
- return ret;
-}
-
-static void
-i_stream_mail_stats_seek(struct istream_private *stream,
- uoff_t v_offset, bool mark ATTR_UNUSED)
-{
- stream->istream.v_offset = v_offset;
- stream->skip = stream->pos = 0;
-}
-
-static const struct stat *
-i_stream_mail_stats_stat(struct istream_private *stream, bool exact)
-{
- return i_stream_stat(stream->parent, exact);
-}
-
-struct istream *
-i_stream_create_mail_stats_counter(struct mailbox_transaction_context *trans,
- struct istream *input)
-{
- struct mail_stats_istream *mstream;
-
- mstream = i_new(struct mail_stats_istream, 1);
- mstream->trans = trans;
- mstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
-
- mstream->istream.parent = input;
- mstream->istream.read = i_stream_mail_stats_read_mail_stats;
- mstream->istream.seek = i_stream_mail_stats_seek;
- mstream->istream.stat = i_stream_mail_stats_stat;
-
- mstream->istream.istream.blocking = input->blocking;
- mstream->istream.istream.seekable = input->seekable;
- return i_stream_create(&mstream->istream, input,
- i_stream_get_fd(input));
-}
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail-stats.h
--- a/src/lib-storage/index/istream-mail-stats.h Tue Oct 04 17:17:12 2011 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-#ifndef ISTREAM_MAIL_STATS_H
-#define ISTREAM_MAIL_STATS_H
-
-struct istream *
-i_stream_create_mail_stats_counter(struct mailbox_transaction_context *trans,
- struct istream *input);
-
-#endif
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/istream-mail.c Tue Oct 04 17:22:55 2011 +0300
@@ -0,0 +1,129 @@
+/* Copyright (c) 2009-2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "mail-storage-private.h"
+#include "istream-private.h"
+#include "index-mail.h"
+#include "istream-mail.h"
+
+struct mail_istream {
+ struct istream_private istream;
+
+ struct mail *mail;
+ uoff_t expected_size;
+ unsigned int files_read_increased:1;
+ unsigned int input_has_body:1;
+};
+
+static bool i_stream_mail_try_get_cached_size(struct mail_istream *mstream)
+{
+ struct mail *mail = mstream->mail;
+ enum mail_lookup_abort orig_lookup_abort;
+
+ if (mstream->expected_size != (uoff_t)-1)
+ return TRUE;
+
+ orig_lookup_abort = mail->lookup_abort;
+ mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE;
+ if (mail_get_physical_size(mail, &mstream->expected_size) < 0)
+ mstream->expected_size = (uoff_t)-1;
+ mail->lookup_abort = orig_lookup_abort;
+ return mstream->expected_size != (uoff_t)-1;
+}
+
+static void
+i_stream_mail_set_size_corrupted(struct mail_istream *mstream, size_t size)
+{
+ uoff_t cur_size = mstream->istream.istream.v_offset + size;
+ const char *str;
+ char chr;
+
+ if (mstream->expected_size < cur_size) {
+ str = "smaller";
+ chr = '<';
+ } else {
+ str = "larger";
+ chr = '>';
+ }
+
+ mail_storage_set_critical(mstream->mail->box->storage,
+ "Cached message size %s than expected "
+ "(%"PRIuUOFF_T" %c %"PRIuUOFF_T")", str,
+ mstream->expected_size, chr, cur_size);
+ index_mail_set_cache_corrupted(mstream->mail, MAIL_FETCH_PHYSICAL_SIZE);
+ mstream->istream.istream.stream_errno = EIO;
+}
+
+static ssize_t
+i_stream_mail_read(struct istream_private *stream)
+{
+ struct mail_istream *mstream = (struct mail_istream *)stream;
+ size_t size;
+ ssize_t ret;
+
+ i_stream_seek(stream->parent, stream->parent_start_offset +
+ stream->istream.v_offset);
+
+ ret = i_stream_read_copy_from_parent(&stream->istream);
+ (void)i_stream_get_data(&stream->istream, &size);
+ if (ret > 0) {
+ mstream->mail->transaction->stats.files_read_bytes += ret;
+ if (!mstream->files_read_increased) {
+ mstream->files_read_increased = TRUE;
+ mstream->mail->transaction->stats.files_read_count++;
+ }
+ if (mstream->expected_size < stream->istream.v_offset + size) {
+ i_stream_mail_set_size_corrupted(mstream, size);
+ return -1;
+ }
+ } else if (ret < 0 && stream->istream.eof) {
+ if (!mstream->input_has_body) {
+ /* trying to read past the header, but this stream
+ doesn't have the body */
+ return -1;
+ }
+ if (i_stream_mail_try_get_cached_size(mstream) &&
+ mstream->expected_size > stream->istream.v_offset + size) {
+ i_stream_mail_set_size_corrupted(mstream, size);
+ return -1;
+ }
+ }
+ return ret;
+}
+
+static void
+i_stream_mail_seek(struct istream_private *stream,
+ uoff_t v_offset, bool mark ATTR_UNUSED)
+{
+ stream->istream.v_offset = v_offset;
+ stream->skip = stream->pos = 0;
+}
+
+static const struct stat *
+i_stream_mail_stat(struct istream_private *stream, bool exact)
+{
+ return i_stream_stat(stream->parent, exact);
+}
+
+struct istream *i_stream_create_mail(struct mail *mail, struct istream *input,
+ bool input_has_body)
+{
+ struct mail_istream *mstream;
+
+ mstream = i_new(struct mail_istream, 1);
+ mstream->mail = mail;
+ mstream->input_has_body = input_has_body;
+ mstream->expected_size = (uoff_t)-1;
+ (void)i_stream_mail_try_get_cached_size(mstream);
+ mstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
+
+ mstream->istream.parent = input;
+ mstream->istream.read = i_stream_mail_read;
+ mstream->istream.seek = i_stream_mail_seek;
+ mstream->istream.stat = i_stream_mail_stat;
+
+ mstream->istream.istream.blocking = input->blocking;
+ mstream->istream.istream.seekable = input->seekable;
+ return i_stream_create(&mstream->istream, input,
+ i_stream_get_fd(input));
+}
diff -r 276a39ebda4d -r 75f044354386 src/lib-storage/index/istream-mail.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/istream-mail.h Tue Oct 04 17:22:55 2011 +0300
More information about the dovecot-cvs
mailing list