]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Don't modify index file when creating new transaction log.
authorTimo Sirainen <tss@iki.fi>
Thu, 29 Apr 2004 00:08:00 +0000 (03:08 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 29 Apr 2004 00:08:00 +0000 (03:08 +0300)
--HG--
branch : HEAD

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

index 342ee7e5c6b2789b22b6aac4464e84af91f7f197..c33275f9161a268f68870264beea49b74838fc51 100644 (file)
@@ -70,7 +70,7 @@ struct mail_index {
        uint32_t indexid;
 
        int lock_type, shared_lock_count, excl_lock_count;
-       unsigned int lock_id, opening_lock_id;
+       unsigned int lock_id;
        char *copy_lock_path;
        struct dotlock dotlock;
 
index 71f74d375bcb3a049b4d8aa0f867c4c7c0eca42e..97b18a04d243d23d0a4aa2c0f8509b5a8f7b34ff 100644 (file)
@@ -538,10 +538,10 @@ static int
 mail_index_open2(struct mail_index *index, enum mail_index_open_flags flags)
 {
        struct mail_index_header hdr;
+       unsigned int lock_id = 0;
        int ret;
 
-       index->opening_lock_id = 0;
-       ret = mail_index_try_open(index, &index->opening_lock_id);
+       ret = mail_index_try_open(index, &lock_id);
        if (ret > 0)
                hdr = *index->hdr;
        else if (ret == 0) {
@@ -559,10 +559,8 @@ mail_index_open2(struct mail_index *index, enum mail_index_open_flags flags)
        if (index->log == NULL)
                return -1;
 
-       if (index->opening_lock_id != 0) {
-               mail_index_unlock(index, index->opening_lock_id);
-                index->opening_lock_id = 0;
-       }
+       if (lock_id != 0)
+               mail_index_unlock(index, lock_id);
        return index->fd != -1 ? 1 : mail_index_create(index, &hdr);
 }
 
index d443a2b146e6b777dc53c7c4959bae19e11a10f0..56e9c9d275868d1e883cea1b66b453e7454bb29c 100644 (file)
@@ -88,8 +88,33 @@ mail_transaction_log_view_set(struct mail_transaction_log_view *view,
         mail_transaction_log_view_close_files(view);
 
        ret = mail_transaction_log_file_find(view->log, min_file_seq, &file);
-       if (ret <= 0)
-               return -1;
+       if (ret <= 0) {
+               if (ret == 0 &&
+                   min_file_seq == view->log->tail->hdr.file_seq-1 &&
+                   min_file_offset == view->log->tail->hdr.prev_file_offset) {
+                       /* we can skip this */
+                       min_file_seq++;
+                       min_file_offset =
+                               sizeof(struct mail_transaction_log_header);
+                       ret = mail_transaction_log_file_find(view->log,
+                                                            min_file_seq,
+                                                            &file);
+               }
+
+               if (ret == 0) {
+                       mail_index_set_error(view->log->index,
+                               "Lost transaction log file %s seq %u",
+                               view->log->tail->filepath, min_file_seq);
+               }
+               if (ret <= 0)
+                       return -1;
+
+               if (min_file_seq > max_file_seq) {
+                       /* empty view */
+                       max_file_seq = min_file_seq;
+                       max_file_offset = min_file_offset;
+               }
+       }
        end_offset = min_file_seq == max_file_seq ?
                max_file_offset : (uoff_t)-1;
        ret = mail_transaction_log_file_map(file, min_file_offset, end_offset);
index 65850512d49a2d048564a4bb02ecff11734718b2..ea3293a5dc531f600e9ea3e5d45e5b425f7fa5d6 100644 (file)
@@ -61,6 +61,12 @@ mail_transaction_log_file_set_corrupted(struct mail_transaction_log_file *file,
        va_end(va);
 }
 
+#define INDEX_HAS_MISSING_LOGS(index, file) \
+       ((file)->hdr.file_seq != (index)->hdr->log_file_seq && \
+        ((file)->hdr.file_seq != (index)->hdr->log_file_seq+1 || \
+         (file)->hdr.prev_file_offset != (index)->hdr->log_file_offset))
+
+
 static int mail_transaction_log_check_file_seq(struct mail_transaction_log *log)
 {
        struct mail_index *index = log->index;
@@ -77,7 +83,7 @@ static int mail_transaction_log_check_file_seq(struct mail_transaction_log *log)
                ret = mail_index_map(index, FALSE);
                if (ret <= 0)
                        ret = -1;
-               else if (file->hdr.file_seq != index->hdr->log_file_seq) {
+               else if (INDEX_HAS_MISSING_LOGS(index, file)) {
                        /* broken - fix it by creating a new log file */
                        ret = mail_transaction_log_rotate(log);
                }
@@ -104,11 +110,10 @@ mail_transaction_log_open_or_create(struct mail_index *index)
        }
 
        if (index->fd != -1 &&
-           log->head->hdr.file_seq != index->hdr->log_file_seq) {
+           INDEX_HAS_MISSING_LOGS(index, log->head)) {
                /* head log file isn't same as head index file -
                   shouldn't happen except in race conditions. lock them and
-                  check again - FIXME: missing error handling.
-                  FIXME: index->hdr check crashes if we created the log */
+                  check again - FIXME: missing error handling. */
                (void)mail_transaction_log_check_file_seq(log);
        }
        return log;
@@ -280,14 +285,13 @@ mail_transaction_log_file_read_hdr(struct mail_transaction_log_file *file,
        return 1;
 }
 
-static int mail_transaction_log_file_create(struct mail_transaction_log *log,
-                                           const char *path,
-                                           dev_t dev, ino_t ino)
+static int
+mail_transaction_log_file_create(struct mail_transaction_log *log,
+                                const char *path, dev_t dev, ino_t ino)
 {
        struct mail_index *index = log->index;
        struct mail_transaction_log_header hdr;
        struct stat st;
-       unsigned int lock_id;
        int fd, fd2, ret;
 
        fd = file_dotlock_open(path, NULL, LOG_DOTLOCK_TIMEOUT,
@@ -326,37 +330,9 @@ static int mail_transaction_log_file_create(struct mail_transaction_log *log,
        hdr.indexid = index->indexid;
        hdr.used_size = sizeof(hdr);
 
-       if (index->fd != -1) {
-               index->log_locked = TRUE; /* kludging around assert.. */
-               if (mail_index_lock_exclusive(index, &lock_id) < 0) {
-                       (void)file_dotlock_delete(path, fd);
-                       index->log_locked = FALSE;
-                       return -1;
-               }
-
-               ret = mail_index_map(index, FALSE);
-               if (ret > 0) {
-                       /* update log_file_* fields in header */
-                       struct mail_index_header idx_hdr;
-
-                       idx_hdr = *index->hdr;
-                       idx_hdr.log_file_seq++;
-                       idx_hdr.log_file_offset = sizeof(hdr);
-                       if (mail_index_write_header(index, &idx_hdr) < 0)
-                               ret = -1;
-               }
-               hdr.file_seq = index->hdr->log_file_seq;
-               mail_index_unlock(index, lock_id);
-               index->log_locked = FALSE;
-
-               if (ret <= 0) {
-                       (void)file_dotlock_delete(path, fd);
-                       return -1;
-               }
-       } else {
-               /* creating new index file */
-               hdr.file_seq = index->hdr->log_file_seq+1;
-       }
+       if (index->fd != -1)
+               hdr.prev_file_offset = index->hdr->log_file_offset;
+       hdr.file_seq = index->hdr->log_file_seq+1;
 
        if (write_full(fd, &hdr, sizeof(hdr)) < 0) {
                mail_index_file_set_syscall_error(index, path, "write_full()");
index 7d271e019d3f50ceca524195e7665d84da34b203..bc70e600a566e1a477479451e999cc3885c2118a 100644 (file)
@@ -6,6 +6,7 @@
 struct mail_transaction_log_header {
        uint32_t indexid;
        uint32_t file_seq;
+       uint32_t prev_file_offset;
        uint32_t used_size;
 };