From: Timo Sirainen Date: Thu, 29 Apr 2004 00:08:00 +0000 (+0300) Subject: Don't modify index file when creating new transaction log. X-Git-Tag: 1.1.alpha1~4171 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40ef82c46f6652412b068ebcdac7c3e74840a284;p=thirdparty%2Fdovecot%2Fcore.git Don't modify index file when creating new transaction log. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-index-private.h b/src/lib-index/mail-index-private.h index 342ee7e5c6..c33275f916 100644 --- a/src/lib-index/mail-index-private.h +++ b/src/lib-index/mail-index-private.h @@ -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; diff --git a/src/lib-index/mail-index.c b/src/lib-index/mail-index.c index 71f74d375b..97b18a04d2 100644 --- a/src/lib-index/mail-index.c +++ b/src/lib-index/mail-index.c @@ -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); } diff --git a/src/lib-index/mail-transaction-log-view.c b/src/lib-index/mail-transaction-log-view.c index d443a2b146..56e9c9d275 100644 --- a/src/lib-index/mail-transaction-log-view.c +++ b/src/lib-index/mail-transaction-log-view.c @@ -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); diff --git a/src/lib-index/mail-transaction-log.c b/src/lib-index/mail-transaction-log.c index 65850512d4..ea3293a5dc 100644 --- a/src/lib-index/mail-transaction-log.c +++ b/src/lib-index/mail-transaction-log.c @@ -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()"); diff --git a/src/lib-index/mail-transaction-log.h b/src/lib-index/mail-transaction-log.h index 7d271e019d..bc70e600a5 100644 --- a/src/lib-index/mail-transaction-log.h +++ b/src/lib-index/mail-transaction-log.h @@ -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; };