]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mbox: Fixed getting header MD5 (GUID) if it wasn't already in index.
authorTimo Sirainen <tss@iki.fi>
Thu, 18 Feb 2010 05:06:42 +0000 (07:06 +0200)
committerTimo Sirainen <tss@iki.fi>
Thu, 18 Feb 2010 05:06:42 +0000 (07:06 +0200)
--HG--
branch : HEAD

src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/mbox/mbox-sync-private.h
src/lib-storage/index/mbox/mbox-sync.c

index cdb7cbbdfd52a3b47f95f5398c1c8bc3c5bdaf8a..e4cfdb2e06837a56f32d93b194c401f7ceee284e 100644 (file)
@@ -175,6 +175,7 @@ mbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
 {
        struct index_mail *mail = (struct index_mail *)_mail;
        struct mbox_mailbox *mbox = (struct mbox_mailbox *)_mail->box;
+       uoff_t offset;
 
        switch (field) {
        case MAIL_FETCH_FROM_ENVELOPE:
@@ -191,10 +192,16 @@ mbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
                /* i guess in theory the empty_md5 is valid and can happen,
                   but it's almost guaranteed that it means the MD5 sum is
                   missing. recalculate it. */
+               offset = istream_raw_mbox_get_start_offset(mbox->mbox_stream);
                mbox->mbox_save_md5 = TRUE;
-                mbox_prepare_resync(_mail);
-               if (mbox_sync(mbox, MBOX_SYNC_FORCE_SYNC) < 0)
+               if (mbox_sync(mbox, MBOX_SYNC_FORCE_SYNC |
+                             MBOX_SYNC_READONLY) < 0)
                        return -1;
+               if (istream_raw_mbox_seek(mbox->mbox_stream, offset) < 0) {
+                       i_error("mbox %s sync lost during MD5 syncing",
+                               _mail->box->name);
+                       return -1;
+               }
 
                if (!mbox_mail_get_md5_header(mail, value_r)) {
                        i_error("mbox %s resyncing didn't save header MD5 values",
index 2cc13bc45f5368c6967ecca83e5c4a393fd31a6d..936b16f5096fba6bd9572f11b4e08be0a1eb9bae 100644 (file)
@@ -11,7 +11,8 @@ enum mbox_sync_flags {
        MBOX_SYNC_LOCK_READING  = 0x04,
        MBOX_SYNC_UNDIRTY       = 0x08,
        MBOX_SYNC_REWRITE       = 0x10,
-       MBOX_SYNC_FORCE_SYNC    = 0x20
+       MBOX_SYNC_FORCE_SYNC    = 0x20,
+       MBOX_SYNC_READONLY      = 0x40
 };
 
 struct mbox_flag_type {
@@ -138,6 +139,7 @@ struct mbox_sync_context {
 
        /* global flags: */
        unsigned int keep_recent:1;
+       unsigned int readonly:1;
        unsigned int delay_writes:1;
        unsigned int renumber_uids:1;
        unsigned int moved_offsets:1;
index cf226acb559980d568d50fe38076a4a5af139487..04d05a833ee5637977e7b7695a8541fbb4e243bd 100644 (file)
@@ -181,7 +181,7 @@ static void mbox_sync_read_index_syncs(struct mbox_sync_context *sync_ctx,
 
        index_sync_changes_read(sync_ctx->sync_changes, uid, sync_expunge_r,
                                expunged_guid_128);
-       if (sync_ctx->mbox->box.backend_readonly) {
+       if (sync_ctx->readonly) {
                /* we can't expunge anything from read-only mboxes */
                *sync_expunge_r = FALSE;
        }
@@ -1590,7 +1590,6 @@ static int mbox_sync_do(struct mbox_sync_context *sync_ctx,
                   b) we ran out of UIDs
                   c) syncing had errors */
                if (sync_ctx->delay_writes &&
-                   !sync_ctx->mbox->box.backend_readonly &&
                    (sync_ctx->errors || sync_ctx->renumber_uids)) {
                        /* fixing a broken mbox state, be sure to write
                           the changes. */
@@ -1730,9 +1729,11 @@ static int mbox_sync_int(struct mbox_mailbox *mbox, enum mbox_sync_flags flags,
        struct mbox_sync_context sync_ctx;
        enum mail_index_sync_flags sync_flags;
        int ret, changed;
-       bool delay_writes;
+       bool delay_writes, readonly;
 
-       delay_writes = mbox->box.backend_readonly ||
+       readonly = mbox->box.backend_readonly ||
+               (flags & MBOX_SYNC_READONLY) != 0;
+       delay_writes = readonly ||
                ((flags & MBOX_SYNC_REWRITE) == 0 &&
                 mbox->storage->set->mbox_lazy_writes);
 
@@ -1779,7 +1780,7 @@ again:
                   lock it for writing immediately. the mbox must be locked
                   before index syncing is started to avoid deadlocks, so we
                   don't have much choice either (well, easy ones anyway). */
-               int lock_type = mbox->box.backend_readonly ? F_RDLCK : F_WRLCK;
+               int lock_type = readonly ? F_RDLCK : F_WRLCK;
 
                if ((ret = mbox_lock(mbox, lock_type, lock_id)) <= 0) {
                        if (ret == 0 || lock_type == F_RDLCK)
@@ -1788,7 +1789,7 @@ again:
                        /* try as read-only */
                        if (mbox_lock(mbox, F_RDLCK, lock_id) <= 0)
                                return -1;
-                       mbox->box.backend_readonly = TRUE;
+                       mbox->box.backend_readonly = readonly = TRUE;
                }
        }
 
@@ -1846,8 +1847,8 @@ again:
        i_array_init(&sync_ctx.mails, 64);
 
        sync_ctx.flags = flags;
-       sync_ctx.delay_writes = delay_writes ||
-               sync_ctx.mbox->box.backend_readonly;
+       sync_ctx.readonly = readonly;
+       sync_ctx.delay_writes = delay_writes;
 
        sync_ctx.sync_changes =
                index_sync_changes_init(index_sync_ctx, sync_view, trans,
@@ -1899,7 +1900,7 @@ again:
        sync_ctx.index_sync_ctx = NULL;
 
        if (ret == 0 && mbox->mbox_fd != -1 && sync_ctx.keep_recent &&
-           !sync_ctx.mbox->box.backend_readonly) {
+           !readonly) {
                /* try to set atime back to its original value */
                struct utimbuf buf;
                struct stat st;
@@ -1933,7 +1934,8 @@ int mbox_sync(struct mbox_mailbox *mbox, enum mbox_sync_flags flags)
        unsigned int lock_id = 0;
        int ret;
 
-       i_assert(mbox->mbox_lock_type != F_RDLCK);
+       i_assert(mbox->mbox_lock_type != F_RDLCK ||
+                (flags & MBOX_SYNC_READONLY) != 0);
 
        mbox->syncing = TRUE;
        ret = mbox_sync_int(mbox, flags, &lock_id);