mail-transaction-log-view.c revision a4d209d480d453566d331e870b8d0c99af7716c8
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2003-2008 Dovecot authors, see the included COPYING file */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen /* a list of log files we've referenced. we have to keep this list
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen explicitly because more files may be added into the linked list
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen at any time. */
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen ARRAY_DEFINE(file_refs, struct mail_transaction_log_file *);
42dbeeb3462895b03e7633dbc59e8e191199734bTimo Sirainen struct mail_transaction_log_file *cur, *head, *tail;
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenmail_transaction_log_view_open(struct mail_transaction_log *log)
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen view = i_new(struct mail_transaction_log_view, 1);
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen array_append(&view->file_refs, &view->head, 1);
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenmail_transaction_log_view_unref_all(struct mail_transaction_log_view *view)
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen struct mail_transaction_log_file *const *files;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen unsigned int i, count;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen for (i = 0; i < count; i++)
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenvoid mail_transaction_log_view_close(struct mail_transaction_log_view **_view)
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen struct mail_transaction_log_view *view = *_view;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen for (p = &view->log->views; *p != NULL; p = &(*p)->next) {
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenvoid mail_transaction_log_views_close(struct mail_transaction_log *log)
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen for (view = log->views; view != NULL; view = view->next)
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainenint mail_transaction_log_view_set(struct mail_transaction_log_view *view,
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen uint32_t min_file_seq, uoff_t min_file_offset,
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen uint32_t max_file_seq, uoff_t max_file_offset,
d4fe93a9c242d745e0cf2e6cc58d5caf265de2a0Timo Sirainen struct mail_transaction_log_file *file, *const *files;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen unsigned int i;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* transaction log is closed already. this log view shouldn't
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen be used anymore. */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen /* index file doesn't exist yet. this transaction log should
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen start from the beginning */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen if (view->log->files->hdr.prev_file_seq != 0) {
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen /* but it doesn't */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen min_file_seq = view->log->files->hdr.file_seq;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen if (min_file_seq == view->log->files->hdr.prev_file_seq &&
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen min_file_offset == view->log->files->hdr.prev_file_offset) {
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen /* we can skip this */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen min_file_seq = view->log->files->hdr.file_seq;
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen /* empty view */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen if (min_file_seq == max_file_seq && min_file_offset > max_file_offset) {
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen /* log file offset is probably corrupted in the index file. */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen min_file_seq, min_file_offset, max_file_offset);
4d6c99647852146fec4f2663767b17593ef73a47Timo Sirainen if (min_file_offset > 0 && min_file_offset < view->tail->hdr.hdr_size) {
4d6c99647852146fec4f2663767b17593ef73a47Timo Sirainen /* log file offset is probably corrupted in the index file. */
4d6c99647852146fec4f2663767b17593ef73a47Timo Sirainen ") < hdr_size (%u)",
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen for (seq = min_file_seq; seq <= max_file_seq; seq++) {
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen if (file == NULL || file->hdr.file_seq != seq) {
5478609e31a7665ee108ded988a309673f221aa1Timo Sirainen /* see if we could find the missing file. if we know
553667c748977991590854426255e1c34a615f24Timo Sirainen the max. file sequence, make sure NFS attribute
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen cache gets flushed if necessary. */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen bool nfs_flush = max_file_seq != (uint32_t)-1;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen ret = mail_transaction_log_find_file(view->log, seq,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen /* not found / corrupted */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen if (file == NULL || file->hdr.file_seq != seq) {
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen if (file == NULL && max_file_seq == (uint32_t)-1 &&
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen /* we just wanted to sync everything */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen /* if any of the found files reset the index,
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen ignore any missing files up to it */
9511a40d933181045343110c8101b75887062aaeTimo Sirainen /* missing files in the middle */
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen /* we can ignore the missing file */
if (min_file_offset == 0) {
if (ret <= 0)
return ret;
&file) > 0) {
return TRUE;
return last;
const char *fmt, ...)
T_BEGIN {
} T_END;
const void *data)
return FALSE;
if (rec_size == 0) {
return FALSE;
switch (rec_type) {
case MAIL_TRANSACTION_APPEND:
case MAIL_TRANSACTION_EXPUNGE:
sizeof(struct mail_transaction_expunge));
sizeof(struct mail_transaction_flag_update));
case MAIL_TRANSACTION_KEYWORD_UPDATE: {
unsigned int seqset_offset;
sizeof(struct mail_transaction_keyword_reset));
count = 0;
} else if (count == 0) {
rec_type);
return ret;
const void **data_r)
const void *data;
int ret;
T_BEGIN {
} T_END;
if (ret > 0) {
return ret;
const void **data_r)
const void *data;
int ret = 0;
if (ret <= 0) {
if (ret < 0)
return ret;