From b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sat, 30 Aug 2008 14:56:41 +0300 Subject: [PATCH] mbox: If we detect corrupted cached offsets/sizes, make sure the mbox gets resynced. --HG-- branch : HEAD --- src/lib-storage/index/mbox/istream-raw-mbox.c | 8 ++++++++ src/lib-storage/index/mbox/istream-raw-mbox.h | 2 ++ src/lib-storage/index/mbox/mbox-mail.c | 8 +++++++- src/lib-storage/index/mbox/mbox-storage.c | 15 +++++++++++++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/lib-storage/index/mbox/istream-raw-mbox.c b/src/lib-storage/index/mbox/istream-raw-mbox.c index ebbf1ce249..91eb4b65a8 100644 --- a/src/lib-storage/index/mbox/istream-raw-mbox.c +++ b/src/lib-storage/index/mbox/istream-raw-mbox.c @@ -647,3 +647,11 @@ bool istream_raw_mbox_is_eof(struct istream *stream) return rstream->eof; } + +bool istream_raw_mbox_is_corrupted(struct istream *stream) +{ + struct raw_mbox_istream *rstream = + (struct raw_mbox_istream *)stream->real_stream; + + return rstream->corrupted; +} diff --git a/src/lib-storage/index/mbox/istream-raw-mbox.h b/src/lib-storage/index/mbox/istream-raw-mbox.h index d6319d0e04..f51134b5a0 100644 --- a/src/lib-storage/index/mbox/istream-raw-mbox.h +++ b/src/lib-storage/index/mbox/istream-raw-mbox.h @@ -42,5 +42,7 @@ void istream_raw_mbox_set_next_offset(struct istream *stream, uoff_t offset); /* Returns TRUE if we've read the whole mbox. */ 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); #endif diff --git a/src/lib-storage/index/mbox/mbox-mail.c b/src/lib-storage/index/mbox/mbox-mail.c index c78a0200a3..b8ca7fc1b4 100644 --- a/src/lib-storage/index/mbox/mbox-mail.c +++ b/src/lib-storage/index/mbox/mbox-mail.c @@ -42,6 +42,12 @@ static int mbox_mail_seek(struct index_mail *mail) if (mail->mail.mail.expunged || mbox->syncing) return -1; + if (mbox->mbox_stream != NULL && + istream_raw_mbox_is_corrupted(mbox->mbox_stream)) { + /* clear the corruption by forcing a full resync */ + sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC; + } + for (try = 0; try < 2; try++) { if (mbox->mbox_lock_type == F_UNLCK) { sync_flags |= MBOX_SYNC_LOCK_READING; @@ -60,6 +66,7 @@ static int mbox_mail_seek(struct index_mail *mail) } else if ((sync_flags & MBOX_SYNC_FORCE_SYNC) != 0) { /* dirty offsets are broken and mbox is write-locked. sync it to update offsets. */ + mbox_prepare_resync(mail); if (mbox_sync(mbox, sync_flags) < 0) return -1; } @@ -80,7 +87,6 @@ static int mbox_mail_seek(struct index_mail *mail) } /* we'll need to re-sync it completely */ - mbox_prepare_resync(mail); sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC; } if (ret == 0) { diff --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 35cf59d9a9..3a8a874f2c 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -12,6 +12,7 @@ #include "mbox-lock.h" #include "mbox-file.h" #include "mbox-sync-private.h" +#include "istream-raw-mbox.h" #include "mail-copy.h" #include "index-mail.h" @@ -762,18 +763,28 @@ static int mbox_storage_mailbox_close(struct mailbox *box) { struct mbox_mailbox *mbox = (struct mbox_mailbox *)box; const struct mail_index_header *hdr; + enum mbox_sync_flags sync_flags = 0; int ret = 0; + if (mbox->mbox_stream != NULL && + istream_raw_mbox_is_corrupted(mbox->mbox_stream)) { + /* clear the corruption by forcing a full resync */ + sync_flags |= MBOX_SYNC_UNDIRTY | MBOX_SYNC_FORCE_SYNC; + } + if (mbox->ibox.view != NULL) { hdr = mail_index_get_header(mbox->ibox.view); if ((hdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0 && !mbox->mbox_readonly) { /* we've done changes to mbox which haven't been written yet. do it now. */ - if (mbox_sync(mbox, MBOX_SYNC_REWRITE) < 0) - ret = -1; + sync_flags |= MBOX_SYNC_REWRITE; } } + if (sync_flags != 0) { + if (mbox_sync(mbox, sync_flags) < 0) + ret = -1; + } if (mbox->mbox_global_lock_id != 0) (void)mbox_unlock(mbox, mbox->mbox_global_lock_id); -- 2.47.3