Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8529:e7b0a099c33d HEAD
mbox: Don't cache mbox state after it has been unlocked.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 13 Dec 2008 11:21:21 +0200 |
parents | 1a9e14718bd6 |
children | 60ea101c7534 |
files | src/lib-storage/index/mbox/istream-raw-mbox.c src/lib-storage/index/mbox/istream-raw-mbox.h src/lib-storage/index/mbox/mbox-file.c src/lib-storage/index/mbox/mbox-lock.c src/lib-storage/index/mbox/mbox-mail.c |
diffstat | 5 files changed, 73 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- 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:21:21 2008 +0200 @@ -15,8 +15,11 @@ 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 mail_size_forced:1; unsigned int eof:1; unsigned int header_missing_eoh:1; }; @@ -144,6 +147,7 @@ int eoh_char, tz; bool crlf_ending = FALSE; + i_assert(rstream->seeked); i_assert(stream->istream.v_offset >= rstream->from_offset); if (stream->istream.eof) @@ -315,8 +319,9 @@ /* istream_raw_mbox_set_next_offset() used invalid cached next_offset? */ i_error("Next message unexpectedly lost from mbox file " - "%s at %"PRIuUOFF_T, rstream->path, - rstream->hdr_offset + rstream->mail_size); + "%s at %"PRIuUOFF_T" (%s)", rstream->path, + rstream->hdr_offset + rstream->mail_size, + rstream->mail_size_forced ? "cached" : "noncached"); rstream->eof = TRUE; rstream->corrupted = TRUE; rstream->istream.istream.stream_errno = EINVAL; @@ -455,6 +460,8 @@ struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream->real_stream; + i_assert(rstream->seeked); + return rstream->from_offset; } @@ -463,6 +470,8 @@ 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); @@ -482,6 +491,8 @@ uoff_t offset; size_t pos; + i_assert(rstream->seeked); + if (rstream->body_offset != (uoff_t)-1) return rstream->body_offset; @@ -516,6 +527,7 @@ 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); @@ -569,6 +581,8 @@ 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; @@ -579,6 +593,8 @@ 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; @@ -589,6 +605,8 @@ struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream->real_stream; + i_assert(rstream->seeked); + return rstream->crlf_ending; } @@ -627,17 +645,21 @@ (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; @@ -657,6 +679,7 @@ rstream->hdr_offset = offset; check = TRUE; } + rstream->seeked = TRUE; i_stream_seek_mark(stream, offset); i_stream_seek_mark(rstream->istream.parent, offset); @@ -673,6 +696,7 @@ i_assert(rstream->hdr_offset != (uoff_t)-1); + rstream->mail_size_forced = TRUE; rstream->mail_size = offset - rstream->hdr_offset; } @@ -691,3 +715,20 @@ 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; +}
--- 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:21:21 2008 +0200 @@ -46,5 +46,9 @@ 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
--- 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:21:21 2008 +0200 @@ -66,28 +66,26 @@ 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, - mbox->path); - return 0; - } + } else { + if (mbox->mbox_fd == -1) { + if (mbox_file_open(mbox) < 0) + return -1; + } - 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); + 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, mbox->path); + if (mbox->mbox_lock_type != F_UNLCK) + istream_raw_mbox_set_locked(mbox->mbox_stream); return 0; }
--- 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:21:21 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" @@ -714,6 +715,8 @@ 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; } @@ -759,6 +762,10 @@ } /* 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;
--- 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:21:21 2008 +0200 @@ -194,9 +194,10 @@ } /* 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;