]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mbox: If we detect corrupted cached offsets/sizes, make sure the mbox gets resynced.
authorTimo Sirainen <tss@iki.fi>
Sat, 30 Aug 2008 11:56:41 +0000 (14:56 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 30 Aug 2008 11:56:41 +0000 (14:56 +0300)
--HG--
branch : HEAD

src/lib-storage/index/mbox/istream-raw-mbox.c
src/lib-storage/index/mbox/istream-raw-mbox.h
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/mbox/mbox-storage.c

index ebbf1ce249f92292f69df0cd22e61de49b15e9a5..91eb4b65a8d39d1f02eae1b914bec3b344647add 100644 (file)
@@ -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;
+}
index d6319d0e0473d1e3511d4508c04e9e895413c079..f51134b5a029cdde9953c0750b43c79082dfab9b 100644 (file)
@@ -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
index c78a0200a3d512b88473878c82e076247cb89511..b8ca7fc1b4397e779da32be9ec2e24f5fd6762a3 100644 (file)
@@ -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) {
index 35cf59d9a9b0d6727ed06d668429a09bbface959..3a8a874f2cf9f5518bfd53db615551e1d6ec37f8 100644 (file)
@@ -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);