dovecot-1.1: mbox: Don't cache mbox state after it has been unlo...
dovecot at dovecot.org
dovecot at dovecot.org
Sat Dec 13 11:23:26 EET 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/9b7af230f9f0
changeset: 8037:9b7af230f9f0
user: Timo Sirainen <tss at iki.fi>
date: Sat Dec 13 11:23:22 2008 +0200
description:
mbox: Don't cache mbox state after it has been unlocked.
diffstat:
5 files changed, 69 insertions(+), 20 deletions(-)
src/lib-storage/index/mbox/istream-raw-mbox.c | 42 +++++++++++++++++++++++--
src/lib-storage/index/mbox/istream-raw-mbox.h | 4 ++
src/lib-storage/index/mbox/mbox-file.c | 33 +++++++++----------
src/lib-storage/index/mbox/mbox-lock.c | 7 ++++
src/lib-storage/index/mbox/mbox-mail.c | 3 +
diffs (240 lines):
diff -r 539f8d983285 -r 9b7af230f9f0 src/lib-storage/index/mbox/istream-raw-mbox.c
--- a/src/lib-storage/index/mbox/istream-raw-mbox.c Sat Dec 13 10:36:13 2008 +0200
+++ b/src/lib-storage/index/mbox/istream-raw-mbox.c Sat Dec 13 11:23:22 2008 +0200
@@ -15,6 +15,8 @@ struct raw_mbox_istream {
uoff_t from_offset, hdr_offset, body_offset, mail_size;
uoff_t input_peak_offset;
+ unsigned int locked:1;
+ unsigned int seeked:1;
unsigned int crlf_ending:1;
unsigned int corrupted:1;
unsigned int eof:1;
@@ -143,6 +145,7 @@ static ssize_t i_stream_raw_mbox_read(st
int eoh_char;
bool crlf_ending = FALSE;
+ i_assert(rstream->seeked);
i_assert(stream->istream.v_offset >= rstream->from_offset);
if (stream->istream.eof)
@@ -449,6 +452,8 @@ uoff_t istream_raw_mbox_get_start_offset
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
return rstream->from_offset;
}
@@ -456,6 +461,8 @@ uoff_t istream_raw_mbox_get_header_offse
{
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+
+ i_assert(rstream->seeked);
if (rstream->hdr_offset == rstream->from_offset)
(void)i_stream_raw_mbox_read(&rstream->istream);
@@ -475,6 +482,8 @@ uoff_t istream_raw_mbox_get_body_offset(
(struct raw_mbox_istream *)stream->real_stream;
uoff_t offset;
size_t pos;
+
+ i_assert(rstream->seeked);
if (rstream->body_offset != (uoff_t)-1)
return rstream->body_offset;
@@ -509,6 +518,7 @@ uoff_t istream_raw_mbox_get_body_size(st
size_t size;
uoff_t old_offset, body_size, next_body_offset;
+ i_assert(rstream->seeked);
i_assert(rstream->hdr_offset != (uoff_t)-1);
i_assert(rstream->body_offset != (uoff_t)-1);
@@ -562,6 +572,8 @@ time_t istream_raw_mbox_get_received_tim
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
if (rstream->received_time == (time_t)-1)
(void)i_stream_raw_mbox_read(&rstream->istream);
return rstream->received_time;
@@ -572,6 +584,8 @@ const char *istream_raw_mbox_get_sender(
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+ i_assert(rstream->seeked);
+
if (rstream->sender == NULL)
(void)i_stream_raw_mbox_read(&rstream->istream);
return rstream->sender == NULL ? "" : rstream->sender;
@@ -581,6 +595,8 @@ bool istream_raw_mbox_has_crlf_ending(st
{
struct raw_mbox_istream *rstream =
(struct raw_mbox_istream *)stream->real_stream;
+
+ i_assert(rstream->seeked);
return rstream->crlf_ending;
}
@@ -620,17 +636,21 @@ int istream_raw_mbox_seek(struct istream
(struct raw_mbox_istream *)stream->real_stream;
bool check;
+ i_assert(rstream->locked);
+
rstream->corrupted = FALSE;
rstream->eof = FALSE;
rstream->istream.istream.eof = FALSE;
- if (rstream->mail_size != (uoff_t)-1 &&
+ /* if seeked is FALSE, we unlocked in the middle. don't try to use
+ any cached state then. */
+ if (rstream->mail_size != (uoff_t)-1 && rstream->seeked &&
rstream->hdr_offset + rstream->mail_size == offset) {
istream_raw_mbox_next(stream, (uoff_t)-1);
return 0;
}
- if (offset == rstream->from_offset) {
+ if (offset == rstream->from_offset && rstream->seeked) {
/* back to beginning of current message */
offset = rstream->hdr_offset;
check = offset == 0;
@@ -650,6 +670,7 @@ int istream_raw_mbox_seek(struct istream
rstream->hdr_offset = offset;
check = TRUE;
}
+ rstream->seeked = TRUE;
i_stream_seek_mark(stream, offset);
i_stream_seek_mark(rstream->istream.parent, offset);
@@ -684,3 +705,20 @@ bool istream_raw_mbox_is_corrupted(struc
return rstream->corrupted;
}
+
+void istream_raw_mbox_set_locked(struct istream *stream)
+{
+ struct raw_mbox_istream *rstream =
+ (struct raw_mbox_istream *)stream->real_stream;
+
+ rstream->locked = TRUE;
+}
+
+void istream_raw_mbox_set_unlocked(struct istream *stream)
+{
+ struct raw_mbox_istream *rstream =
+ (struct raw_mbox_istream *)stream->real_stream;
+
+ rstream->locked = FALSE;
+ rstream->seeked = FALSE;
+}
diff -r 539f8d983285 -r 9b7af230f9f0 src/lib-storage/index/mbox/istream-raw-mbox.h
--- a/src/lib-storage/index/mbox/istream-raw-mbox.h Sat Dec 13 10:36:13 2008 +0200
+++ b/src/lib-storage/index/mbox/istream-raw-mbox.h Sat Dec 13 11:23:22 2008 +0200
@@ -44,5 +44,9 @@ bool istream_raw_mbox_is_eof(struct istr
bool istream_raw_mbox_is_eof(struct istream *stream);
/* Returns TRUE if we've noticed corruption in used offsets/sizes. */
bool istream_raw_mbox_is_corrupted(struct istream *stream);
+/* Change stream's locking state. We'll assert-crash if stream is tried to be
+ read while it's unlocked. */
+void istream_raw_mbox_set_locked(struct istream *stream);
+void istream_raw_mbox_set_unlocked(struct istream *stream);
#endif
diff -r 539f8d983285 -r 9b7af230f9f0 src/lib-storage/index/mbox/mbox-file.c
--- a/src/lib-storage/index/mbox/mbox-file.c Sat Dec 13 10:36:13 2008 +0200
+++ b/src/lib-storage/index/mbox/mbox-file.c Sat Dec 13 11:23:22 2008 +0200
@@ -66,26 +66,25 @@ int mbox_file_open_stream(struct mbox_ma
if (mbox->mbox_file_stream != NULL) {
/* read-only mbox stream */
i_assert(mbox->mbox_fd == -1 && mbox->mbox_readonly);
-
- mbox->mbox_stream =
- i_stream_create_raw_mbox(mbox->mbox_file_stream);
- return 0;
- }
-
- if (mbox->mbox_fd == -1) {
- if (mbox_file_open(mbox) < 0)
- return -1;
- }
-
- if (mbox->mbox_writeonly)
- mbox->mbox_file_stream = i_stream_create_from_data(NULL, 0);
- else {
- mbox->mbox_file_stream =
- i_stream_create_fd(mbox->mbox_fd,
- MAIL_READ_BLOCK_SIZE, FALSE);
+ } else {
+ if (mbox->mbox_fd == -1) {
+ if (mbox_file_open(mbox) < 0)
+ return -1;
+ }
+
+ if (mbox->mbox_writeonly) {
+ mbox->mbox_file_stream =
+ i_stream_create_from_data(NULL, 0);
+ } else {
+ mbox->mbox_file_stream =
+ i_stream_create_fd(mbox->mbox_fd,
+ MAIL_READ_BLOCK_SIZE, FALSE);
+ }
}
mbox->mbox_stream = i_stream_create_raw_mbox(mbox->mbox_file_stream);
+ if (mbox->mbox_lock_type != F_UNLCK)
+ istream_raw_mbox_set_locked(mbox->mbox_stream);
return 0;
}
diff -r 539f8d983285 -r 9b7af230f9f0 src/lib-storage/index/mbox/mbox-lock.c
--- a/src/lib-storage/index/mbox/mbox-lock.c Sat Dec 13 10:36:13 2008 +0200
+++ b/src/lib-storage/index/mbox/mbox-lock.c Sat Dec 13 11:23:22 2008 +0200
@@ -5,6 +5,7 @@
#include "nfs-workarounds.h"
#include "mail-index-private.h"
#include "mbox-storage.h"
+#include "istream-raw-mbox.h"
#include "mbox-file.h"
#include "mbox-lock.h"
@@ -709,6 +710,8 @@ int mbox_lock(struct mbox_mailbox *mbox,
mbox->mbox_excl_locks++;
*lock_id_r = mbox->mbox_lock_id + 1;
}
+ if (mbox->mbox_stream != NULL)
+ istream_raw_mbox_set_locked(mbox->mbox_stream);
return 1;
}
@@ -754,6 +757,10 @@ int mbox_unlock(struct mbox_mailbox *mbo
}
/* all locks gone */
+ /* make sure we don't read the stream while unlocked */
+ if (mbox->mbox_stream != NULL)
+ istream_raw_mbox_set_unlocked(mbox->mbox_stream);
+
memset(&ctx, 0, sizeof(ctx));
ctx.mbox = mbox;
diff -r 539f8d983285 -r 9b7af230f9f0 src/lib-storage/index/mbox/mbox-mail.c
--- a/src/lib-storage/index/mbox/mbox-mail.c Sat Dec 13 10:36:13 2008 +0200
+++ b/src/lib-storage/index/mbox/mbox-mail.c Sat Dec 13 11:23:22 2008 +0200
@@ -194,9 +194,10 @@ mbox_mail_get_next_offset(struct index_m
}
/* We can't really trust trans_view. The next message may already be
- expunged from it. Also there hdr.messages_count may be incorrect.
+ expunged from it. Also hdr.messages_count may be incorrect there.
So refresh the index to get the latest changes and get the next
message's offset using a new view. */
+ i_assert(mbox->mbox_lock_type != F_UNLCK);
if (mbox_sync_header_refresh(mbox) < 0)
return -1;
More information about the dovecot-cvs
mailing list