]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Fix detecting if index is undeleted
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 2 Nov 2020 16:55:16 +0000 (18:55 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 10 Nov 2020 15:24:01 +0000 (17:24 +0200)
It was possible that mail_index_is_deleted() kept returning that the index
was deleted, even if it was marked as undeleted. This happened when the
deletion was in dovecot.index.log.2, undeletion in dovecot.index.log and
dovecot.index pointed to the .log.2 file. This caused the .log file to be
read first, which sees the undeletion. Later on the .log.2 was parsed and
it marked the index back as deleted.

src/lib-index/mail-index-private.h
src/lib-index/mail-transaction-log-file.c

index d1be1a4d67fe69816aa87fcd0e715f0a4d4d28ac..ea1cf393db49690e8e2ce877182b2dca12404cd5 100644 (file)
@@ -187,6 +187,9 @@ struct mail_index {
        uint32_t last_read_log_file_seq;
        uint32_t last_read_log_file_tail_offset;
 
+       /* log file which last updated index_deleted */
+       uint32_t index_delete_changed_file_seq;
+
        /* transaction log head seq/offset when we last fscked */
        uint32_t fsck_log_head_file_seq;
        uoff_t fsck_log_head_file_offset;
index 34f55faf8345c1cea222bdef3143c9effed5cc57..9a18cb89f058be33570f76d04932a17f69cb87b2 100644 (file)
@@ -1397,17 +1397,21 @@ log_file_track_sync(struct mail_transaction_log_file *file,
                        return ret < 0 ? -1 : 1;
                break;
        case MAIL_TRANSACTION_INDEX_DELETED:
-               if (file->sync_offset < file->index_undeleted_offset)
+               if (file->sync_offset < file->index_undeleted_offset ||
+                   file->hdr.file_seq < file->log->index->index_delete_changed_file_seq)
                        break;
                file->log->index->index_deleted = TRUE;
                file->log->index->index_delete_requested = FALSE;
+               file->log->index->index_delete_changed_file_seq = file->hdr.file_seq;
                file->index_deleted_offset = file->sync_offset + trans_size;
                break;
        case MAIL_TRANSACTION_INDEX_UNDELETED:
-               if (file->sync_offset < file->index_deleted_offset)
+               if (file->sync_offset < file->index_deleted_offset ||
+                   file->hdr.file_seq < file->log->index->index_delete_changed_file_seq)
                        break;
                file->log->index->index_deleted = FALSE;
                file->log->index->index_delete_requested = FALSE;
+               file->log->index->index_delete_changed_file_seq = file->hdr.file_seq;
                file->index_undeleted_offset = file->sync_offset + trans_size;
                break;
        case MAIL_TRANSACTION_BOUNDARY: {